feat: Add Authentication Support and Start of Frontend (#5)
* Setup Authentication On Resources * Go mod tidy * git ignore node modules * Frontend Template * Work on setting up vue frontend * Github Actions * More work on Auth and Frontend. * update dependabot * add Reviewers * Fix Up Labels * Update CodeQL Tests * Fix Format * Fix Formating * More Updates to github actions and bundled frontend files * Fix Formating * increase timeout * Password Checking/Setting Functions
18
.github/dependabot.yml
vendored
|
@ -10,4 +10,20 @@ updates:
|
|||
schedule:
|
||||
interval: "daily"
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- "dependencies"
|
||||
- "backend"
|
||||
reviewers:
|
||||
- "fishwaldo"
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/frontend/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "frontend"
|
||||
reviewers:
|
||||
- "fishwaldo"
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
|
|
18
.github/labeler.yml
vendored
|
@ -1,21 +1,21 @@
|
|||
version: v1
|
||||
|
||||
labels:
|
||||
- label: "type: feature"
|
||||
- label: "feature"
|
||||
sync: true
|
||||
matcher:
|
||||
title: "^feat: .*"
|
||||
commits: "^feat: .*"
|
||||
body: "(\\n|.)*- \\[x\\] feature(\\n|.)*"
|
||||
|
||||
- label: "type: fix"
|
||||
- label: "fix"
|
||||
sync: true
|
||||
matcher:
|
||||
title: "^fix: .*"
|
||||
commits: "^fix: .*"
|
||||
body: "(\\n|.)*- \\[x\\] (fix|bug)(\\n|.)*"
|
||||
|
||||
- label: "type: chore"
|
||||
- label: "chore"
|
||||
sync: true
|
||||
matcher:
|
||||
title: "^chore: .*"
|
||||
|
@ -23,7 +23,7 @@ labels:
|
|||
body: "(\\n|.)*- \\[x\\] chore(\\n|.)*"
|
||||
files: [ ".github/*" ]
|
||||
|
||||
- label: "type: documentation"
|
||||
- label: "documentation"
|
||||
sync: true
|
||||
matcher:
|
||||
title: "^docs: .*"
|
||||
|
@ -38,8 +38,8 @@ checks:
|
|||
failure: Missing semantic label for merge.
|
||||
labels:
|
||||
any:
|
||||
- 'type: feature'
|
||||
- 'type: fix'
|
||||
- 'type: chore'
|
||||
- 'type: documentation'
|
||||
- 'type: dependencies'
|
||||
- 'feature'
|
||||
- 'fix'
|
||||
- 'chore'
|
||||
- 'documentation'
|
||||
- 'dependencies'
|
||||
|
|
45
.github/workflows/build.yml
vendored
|
@ -16,8 +16,17 @@ jobs:
|
|||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Install NPM
|
||||
if: success()
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: install Node Dependancies
|
||||
run: cd frontend && npm install
|
||||
- name: Build Frontend
|
||||
run: cd frontend && npm run build
|
||||
- name: Build
|
||||
run: go build .
|
||||
- name: Run tests
|
||||
|
@ -34,6 +43,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Install NPM
|
||||
if: success()
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Build Frontend
|
||||
run: cd frontend && npm install && npm run build
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
|
@ -47,14 +63,21 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
needs: [ test ]
|
||||
steps:
|
||||
- name: Install Go
|
||||
if: success()
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: Run tests
|
||||
run: go mod tidy && go test -v -race -covermode=atomic -coverprofile=coverage.out ./...
|
||||
- name: CodeCov
|
||||
uses: codecov/codecov-action@v2
|
||||
- name: Install Go
|
||||
if: success()
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: Install NPM
|
||||
if: success()
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Build Frontend
|
||||
run: cd frontend && npm install && npm run build
|
||||
- name: Run tests
|
||||
run: go mod tidy && go test -v -race -covermode=atomic -coverprofile=coverage.out ./...
|
||||
- name: CodeCov
|
||||
uses: codecov/codecov-action@v2
|
||||
|
|
2
.github/workflows/golangci-lint.yml
vendored
|
@ -29,7 +29,7 @@ jobs:
|
|||
# working-directory: somedir
|
||||
|
||||
# Optional: golangci-lint command line arguments.
|
||||
args: --issues-exit-code=0
|
||||
args: --issues-exit-code=0 --timeout=5m
|
||||
|
||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||
only-new-issues: true
|
||||
|
|
41
.github/workflows/goreleaser.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
name: goreleaser
|
||||
|
||||
on:
|
||||
push:
|
||||
# run only against tags
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
# packages: write
|
||||
# issues: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Fetch all tags
|
||||
run: git fetch --force --tags
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18
|
||||
- name: Install NPM
|
||||
if: success()
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
6
.gitignore
vendored
|
@ -16,3 +16,9 @@
|
|||
config.yaml
|
||||
.gitignore
|
||||
.gitignore
|
||||
mouthpiece
|
||||
test.db
|
||||
frontend/node_modules/
|
||||
frontend/dist/
|
||||
dist/
|
||||
test.db-journal
|
||||
|
|
40
.goreleaser.yaml
Normal file
|
@ -0,0 +1,40 @@
|
|||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
before:
|
||||
hooks:
|
||||
# You may remove this if you don't use go modules.
|
||||
- go mod tidy
|
||||
# Build html frontend
|
||||
- go generate ./...
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- -s -w -X github.com/Fishwaldo/mouthpiece/internal.gitVersion={{.Version}} -X github.com/Fishwaldo/mouthpiece/internal.gitCommit={{.ShortCommit}} -X github.com/Fishwaldo/mouthpiece/internal.buildDate={{.Date}}
|
||||
asmflags:
|
||||
#- all=-trimpath
|
||||
gcflags:
|
||||
#- all=-trimpath
|
||||
archives:
|
||||
- replacements:
|
||||
darwin: Darwin
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
386: i386
|
||||
amd64: x86_64
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-next"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
16
config/auth_model.conf
Normal file
|
@ -0,0 +1,16 @@
|
|||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
[role_definition]
|
||||
g = _, _
|
||||
g2 = _, _
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = g(r.sub, p.sub) && g2(r.obj, p.obj) && r.act == p.act
|
||||
|
3
frontend/.browserslistrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
14
frontend/.editorconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
3
frontend/.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules/*
|
||||
/dist/**
|
||||
.eslintrc.js
|
43
frontend/.eslintrc.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
|
||||
extends: [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
},
|
||||
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'prettier/prettier': 'off',
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'**/__tests__/*.{j,t}s?(x)',
|
||||
'**/tests/unit/**/*.spec.{j,t}s?(x)',
|
||||
],
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'@vue/typescript'
|
||||
]
|
||||
}
|
7
frontend/.prettierrc.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
// jsxBracketSameLine: true,
|
||||
semi: false,
|
||||
trailingComma: "all",
|
||||
singleQuote: true,
|
||||
tabWidth: 2
|
||||
};
|
195
frontend/README.md
Normal file
|
@ -0,0 +1,195 @@
|
|||
[](https://github.com/coreui/coreui)
|
||||
[![npm package][npm-coreui-badge]][npm-coreui]
|
||||
[![NPM downloads][npm-coreui-download]][npm-coreui]
|
||||
[](https://github.com/coreui/vue)
|
||||
[![npm package][npm-coreui-vue-badge]][npm-coreui-vue]
|
||||
[![NPM downloads][npm-coreui-vue-download]][npm-coreui-vue]
|
||||
[![npm next][npm-next]][npm]
|
||||
|
||||
[npm-coreui]: https://www.npmjs.com/package/@coreui/coreui
|
||||
[npm-coreui-badge]: https://img.shields.io/npm/v/@coreui/coreui.png?style=flat-square
|
||||
[npm-coreui-download]: https://img.shields.io/npm/dm/@coreui/coreui.svg?style=flat-square
|
||||
[npm-coreui-vue]: https://www.npmjs.com/package/@coreui/vue
|
||||
[npm-coreui-vue-badge]: https://img.shields.io/npm/v/@coreui/vue.png?style=flat-square
|
||||
[npm-coreui-vue-download]: https://img.shields.io/npm/dm/@coreui/vue.svg?style=flat-square
|
||||
[npm-next]: https://img.shields.io/npm/v/@coreui/vue/next.png?style=flat-square
|
||||
[npm]: https://www.npmjs.com/package/@coreui/vue
|
||||
|
||||
# CoreUI Free Vue Admin Template v4
|
||||
|
||||
CoreUI is meant to be the UX game changer. Pure & transparent code is devoid of redundant components, so the app is light enough to offer ultimate user experience. This means mobile devices also, where the navigation is just as easy and intuitive as on a desktop or laptop. The CoreUI Layout API lets you customize your project for almost any device – be it Mobile, Web or WebApp – CoreUI covers them all!
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Versions](#versions)
|
||||
* [CoreUI Pro](#coreui-pro)
|
||||
* [Quick Start](#quick-start)
|
||||
* [Installation](#installation)
|
||||
* [Basic usage](#basic-usage)
|
||||
* [What's included](#whats-included)
|
||||
* [Documentation](#documentation)
|
||||
* [Versioning](#versioning)
|
||||
* [Creators](#creators)
|
||||
* [Community](#community)
|
||||
* [Copyright and License](#copyright-and-license)
|
||||
|
||||
## Versions
|
||||
|
||||
* [CoreUI Free Bootstrap Admin Template](https://github.com/coreui/coreui-free-bootstrap-admin-template)
|
||||
* [CoreUI Free Angular Admin Template](https://github.com/coreui/coreui-free-angular-admin-template)
|
||||
* [CoreUI Free React.js Admin Template](https://github.com/coreui/coreui-free-react-admin-template)
|
||||
* [CoreUI Free Vue.js Admin Template](https://github.com/coreui/coreui-free-vue-admin-template)
|
||||
|
||||
## CoreUI Pro
|
||||
|
||||
* 💪 [CoreUI Pro Angular Admin Template](https://coreui.io/product/angular-dashboard-template/)
|
||||
* 💪 [CoreUI Pro Bootstrap Admin Template](https://coreui.io/product/bootstrap-dashboard-template/)
|
||||
* 💪 [CoreUI Pro React Admin Template](https://coreui.io/product/react-dashboard-template/)
|
||||
* 💪 [CoreUI Pro Vue Admin Template](https://coreui.io/product/vue-dashboard-template/)
|
||||
|
||||
## Quick Start
|
||||
|
||||
- [Download the latest release](https://github.com/coreui/coreui-free-vue-admin-template/archive/refs/heads/main.zip)
|
||||
- Clone the repo: `git clone https://github.com/coreui/coreui-free-vue-admin-template.git`
|
||||
|
||||
### Instalation
|
||||
|
||||
``` bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
``` bash
|
||||
$ yarn install
|
||||
```
|
||||
|
||||
### Basic usage
|
||||
|
||||
``` bash
|
||||
# dev server with hot reload at http://localhost:3000
|
||||
$ npm run serve
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
``` bash
|
||||
# dev server with hot reload at http://localhost:3000
|
||||
$ yarn serve
|
||||
```
|
||||
|
||||
Navigate to [http://localhost:3000](http://localhost:3000). The app will automatically reload if you change any of the source files.
|
||||
|
||||
#### Build
|
||||
|
||||
Run `build` to build the project. The build artifacts will be stored in the `build/` directory.
|
||||
|
||||
```bash
|
||||
# build for production with minification
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
# build for production with minification
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
## What's included
|
||||
|
||||
Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:
|
||||
|
||||
```
|
||||
coreui-free-vue-admin-template
|
||||
├── public/ # static files
|
||||
│ └── index.html # html template
|
||||
│
|
||||
├── src/ # project root
|
||||
│ ├── assets/ # images, icons, etc.
|
||||
│ ├── components/ # common components - header, footer, sidebar, etc.
|
||||
│ ├── layouts/ # layout containers
|
||||
│ ├── scss/ # scss styles
|
||||
│ ├── router # routes config
|
||||
│ └── store # template state example
|
||||
│ ├── views/ # application views
|
||||
│ ├── _nav.js # sidebar navigation config
|
||||
│ ├── App.vue
|
||||
│ ├── ...
|
||||
│ └── main.js
|
||||
│
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation for the CoreUI Admin Template is hosted at our website [CoreUI for Vue](https://coreui.io/vue/)
|
||||
|
||||
## Versioning
|
||||
|
||||
For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI Free Admin Template is maintained under [the Semantic Versioning guidelines](http://semver.org/).
|
||||
|
||||
See [the Releases section of our project](https://github.com/coreui/coreui-free-vue-admin-template/releases) for changelogs for each release version.
|
||||
|
||||
## Creators
|
||||
|
||||
**Łukasz Holeczek**
|
||||
* <https://twitter.com/lukaszholeczek>
|
||||
* <https://github.com/mrholek>
|
||||
* <https://github.com/coreui>
|
||||
|
||||
**CoreUI team**
|
||||
* https://github.com/orgs/coreui/people
|
||||
|
||||
## Community
|
||||
|
||||
Get updates on CoreUI's development and chat with the project maintainers and community members.
|
||||
|
||||
- Follow [@core_ui on Twitter](https://twitter.com/core_ui).
|
||||
- Read and subscribe to [CoreUI Blog](https://coreui.io/blog/).
|
||||
|
||||
## Support CoreUI Development
|
||||
|
||||
CoreUI is an MIT-licensed open source project and is completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying the [CoreUI PRO](https://coreui.io/pricing/) or by becoming a sponsor via [Open Collective](https://opencollective.com/coreui/).
|
||||
|
||||
<!--- StartOpenCollectiveBackers -->
|
||||
|
||||
### Platinum Sponsors
|
||||
|
||||
Support this project by [becoming a Platinum Sponsor](https://opencollective.com/coreui/contribute/platinum-sponsor-40959/). A large company logo will be added here with a link to your website.
|
||||
|
||||
<a href="https://opencollective.com/coreui/contribute/platinum-sponsor-40959/checkout"><img src="https://opencollective.com/coreui/tiers/platinum-sponsor/0/avatar.svg?avatarHeight=100"></a>
|
||||
|
||||
### Gold Sponsors
|
||||
|
||||
Support this project by [becoming a Gold Sponsor](https://opencollective.com/coreui/contribute/gold-sponsor-40960/). A big company logo will be added here with a link to your website.
|
||||
|
||||
<a href="https://opencollective.com/coreui/contribute/gold-sponsor-40960/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a>
|
||||
|
||||
### Silver Sponsors
|
||||
|
||||
Support this project by [becoming a Silver Sponsor](https://opencollective.com/coreui/contribute/silver-sponsor-40967/). A medium company logo will be added here with a link to your website.
|
||||
|
||||
<a href="https://opencollective.com/coreui/contribute/silver-sponsor-40967/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a>
|
||||
|
||||
### Bronze Sponsors
|
||||
|
||||
Support this project by [becoming a Bronze Sponsor](https://opencollective.com/coreui/contribute/bronze-sponsor-40966/). The company avatar will show up here with a link to your OpenCollective Profile.
|
||||
|
||||
<a href="https://opencollective.com/coreui/contribute/bronze-sponsor-40966/checkout"><img src="https://opencollective.com/coreui/tiers/bronze-sponsor/0/avatar.svg?avatarHeight=100"></a>
|
||||
|
||||
### Backers
|
||||
|
||||
Thanks to all the backers and sponsors! Support this project by [becoming a backer](https://opencollective.com/coreui/contribute/backer-40965/).
|
||||
|
||||
<a href="https://opencollective.com/coreui/contribute/backer-40965/checkout" target="_blank" rel="noopener"><img src="https://opencollective.com/coreui/backers.svg?width=890"></a>
|
||||
|
||||
<!--- EndOpenCollectiveBackers -->
|
||||
|
||||
## Copyright and License
|
||||
|
||||
copyright 2022 creativeLabs Łukasz Holeczek.
|
||||
|
||||
|
||||
Code released under [the MIT license](https://github.com/coreui/coreui-free-react-admin-template/blob/master/LICENSE).
|
||||
There is only one limitation you can't can’t re-distribute the CoreUI as stock. You can’t do this if you modify the CoreUI. In past we faced some problems with persons who tried to sell CoreUI based templates.
|
3
frontend/babel.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset'],
|
||||
}
|
3
frontend/cypress.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"pluginsFile": "tests/e2e/plugins/index.js"
|
||||
}
|
10
frontend/frontend.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package frontend
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:generate npm run build
|
||||
|
||||
//go:embed dist
|
||||
var FrontEndFiles embed.FS
|
3
frontend/jest.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
|
||||
}
|
19
frontend/jsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
7
frontend/openapitools.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
|
||||
"spaces": 2,
|
||||
"generator-cli": {
|
||||
"version": "6.0.1"
|
||||
}
|
||||
}
|
27585
frontend/package-lock.json
generated
Normal file
75
frontend/package.json
Normal file
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"name": "@coreui/coreui-free-vue-admin-template",
|
||||
"version": "4.1.0",
|
||||
"description": "CoreUI Free Vue Admin Template",
|
||||
"author": "The CoreUI Team (https://github.com/orgs/coreui/people)",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"test:e2e": "vue-cli-service test:e2e",
|
||||
"lint": "vue-cli-service lint",
|
||||
"generate": "openapi --input http://localhost:8888/openapi.json --output ./src/generated --client axios --useOptions --exportSchemas true"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coreui/chartjs": "^3.0.0",
|
||||
"@coreui/coreui": "^4.1.0",
|
||||
"@coreui/icons": "^2.1.0",
|
||||
"@coreui/icons-vue": "2.0.0",
|
||||
"@coreui/utils": "^1.3.1",
|
||||
"@coreui/vue": "^4.1.0",
|
||||
"@coreui/vue-chartjs": "2.0.0",
|
||||
"@vuelidate/core": "^2.0.0-alpha.44",
|
||||
"@vuelidate/validators": "^2.0.0-alpha.31",
|
||||
"axios": "^0.27.2",
|
||||
"core-js": "^3.19.0",
|
||||
"vue": "^3.2.37",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-router": "^4.0.12",
|
||||
"vuex": "^4.0.2",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.0-rc.1",
|
||||
"@vue/cli-plugin-e2e-cypress": "~5.0.0-rc.1",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0-rc.1",
|
||||
"@vue/cli-plugin-router": "~5.0.0-rc.1",
|
||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||
"@vue/cli-plugin-unit-jest": "~5.0.0-rc.1",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0-rc.1",
|
||||
"@vue/cli-service": "~5.0.0-rc.1",
|
||||
"@vue/eslint-config-typescript": "^9.1.0",
|
||||
"@vue/test-utils": "^2.0.0-0",
|
||||
"@vue/vue3-jest": "^27.0.0-alpha.1",
|
||||
"babel-jest": "^27.0.6",
|
||||
"cypress": "^8.7.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"form-data": "^4.0.0",
|
||||
"jest": "^27.0.5",
|
||||
"openapi-typescript-codegen": "^0.23.0",
|
||||
"prettier": "^2.4.1",
|
||||
"sass": "^1.32.7",
|
||||
"sass-loader": "^12.0.0",
|
||||
"ts-jest": "^27.0.4",
|
||||
"typescript": "~4.5.5"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/coreui/coreui-free-vue-admin-template/issues"
|
||||
},
|
||||
"config": {
|
||||
"coreui_library_short_version": "4.1"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:coreui/coreui-free-vue-admin-template.git"
|
||||
}
|
||||
}
|
BIN
frontend/public/android-icon-144x144.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/public/android-icon-192x192.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
frontend/public/android-icon-36x36.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
frontend/public/android-icon-48x48.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
frontend/public/android-icon-72x72.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
frontend/public/android-icon-96x96.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
frontend/public/apple-icon-114x114.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
frontend/public/apple-icon-120x120.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
frontend/public/apple-icon-144x144.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/public/apple-icon-152x152.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
frontend/public/apple-icon-180x180.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
frontend/public/apple-icon-57x57.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
frontend/public/apple-icon-60x60.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
frontend/public/apple-icon-72x72.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
frontend/public/apple-icon-76x76.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
frontend/public/apple-icon-precomposed.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
frontend/public/apple-icon.png
Normal file
After Width: | Height: | Size: 18 KiB |
2
frontend/public/browserconfig.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
BIN
frontend/public/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
frontend/public/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
frontend/public/favicon-96x96.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
frontend/public/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
43
frontend/public/index.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
* MouthPiece Messaging Server
|
||||
* @version v1.0
|
||||
* @link https://coreui.io/vue/
|
||||
* Copyright (c) 2021 creativeLabs Łukasz Holeczek
|
||||
* License (https://coreui.io/pro/license)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,shrink-to-fit=no">
|
||||
<meta name="description" content="MouthPiece Messaging Server">
|
||||
<meta name="author" content="creativeLabs Łukasz Holeczek">
|
||||
<title>MouthPiece Messaging Server</title>
|
||||
<!-- favicons for all devices -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="<%= BASE_URL %>apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<%= BASE_URL %>apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%= BASE_URL %>apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="<%= BASE_URL %>apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="<%= BASE_URL %>apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="<%= BASE_URL %>apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<%= BASE_URL %>apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="<%= BASE_URL %>apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="<%= BASE_URL %>apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="<%= BASE_URL %>android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%= BASE_URL %>favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%= BASE_URL %>favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%= BASE_URL %>favicon-16x16.png">
|
||||
<link rel="manifest" href="<%= BASE_URL %>manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
|
@ -71,9 +71,9 @@ function login(prov) {
|
|||
});
|
||||
}
|
||||
|
||||
function loginAnonymously(username) {
|
||||
return fetch(
|
||||
`/auth/anonymous/login?id=auth-example&user=${encodeURIComponent(username)}`
|
||||
function loginAnonymously(username, password) {
|
||||
return req(
|
||||
`/auth/direct/login?id=auth-example&user=${encodeURIComponent(username)}&passwd=${encodeURIComponent(password)}`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ function loginViaEmailToken(token) {
|
|||
return req(`/auth/email/login?token=${token}`);
|
||||
}
|
||||
|
||||
const validUsernameRegex = /^[a-zA-Z][\w ]+$/;
|
||||
const validUsernameRegex = /[^@]+@[^\.]+\..+/;
|
||||
|
||||
function getUsernameInvalidReason(username) {
|
||||
if (username.length < 3) return "Username must be at least 3 characters long";
|
||||
|
@ -120,6 +120,11 @@ function getAnonymousLoginForm(onSubmit) {
|
|||
input.placeholder = "Username";
|
||||
input.className = "anon-form__input";
|
||||
|
||||
const pass = document.createElement("input");
|
||||
pass.type = "text";
|
||||
pass.placeholder = "Password";
|
||||
pass.className = "anon-form__input";
|
||||
|
||||
const submit = document.createElement("input");
|
||||
submit.type = "submit";
|
||||
submit.value = "Log in";
|
||||
|
@ -143,11 +148,12 @@ function getAnonymousLoginForm(onSubmit) {
|
|||
});
|
||||
|
||||
form.appendChild(input);
|
||||
form.appendChild(pass);
|
||||
form.appendChild(submit);
|
||||
|
||||
form.addEventListener("submit", e => {
|
||||
e.preventDefault();
|
||||
onSubmit(input.value);
|
||||
onSubmit(input.value, pass.value);
|
||||
});
|
||||
|
||||
return form;
|
||||
|
@ -330,7 +336,7 @@ function getLoginLinks() {
|
|||
return getProviders().then(providers =>
|
||||
providers.map(prov => {
|
||||
let a;
|
||||
if (prov === "anonymous") {
|
||||
if (prov === "direct") {
|
||||
a = document.createElement("span");
|
||||
a.dataset.provider = prov;
|
||||
a.className = "login__prov";
|
||||
|
@ -355,8 +361,8 @@ function getLoginLinks() {
|
|||
}
|
||||
});
|
||||
|
||||
const form = getAnonymousLoginForm(username => {
|
||||
loginAnonymously(username)
|
||||
const form = getAnonymousLoginForm((username, password) => {
|
||||
loginAnonymously(username, password)
|
||||
.then(() => {
|
||||
window.location.replace(window.location.href);
|
||||
})
|
41
frontend/public/manifest.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "CoreUI Free Vue Admin Template",
|
||||
"icons": [
|
||||
{
|
||||
"src": "\/android-icon-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "\/android-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
BIN
frontend/public/ms-icon-144x144.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/public/ms-icon-150x150.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
frontend/public/ms-icon-310x310.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
frontend/public/ms-icon-70x70.png
Normal file
After Width: | Height: | Size: 5 KiB |
8
frontend/src/App.vue
Normal file
|
@ -0,0 +1,8 @@
|
|||
<template>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
// Import Main styles for this application
|
||||
@import 'styles/style';
|
||||
</style>
|
58
frontend/src/_nav.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
export default [
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Dashboard',
|
||||
to: '/dashboard',
|
||||
icon: 'cil-speedometer',
|
||||
},
|
||||
{
|
||||
component: 'CNavTitle',
|
||||
name: 'Apps',
|
||||
},
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Applications',
|
||||
to: '/apps',
|
||||
icon: 'cil-puzzle',
|
||||
},
|
||||
{
|
||||
component: 'CNavTitle',
|
||||
name: 'Users',
|
||||
},
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Users',
|
||||
to: '/users',
|
||||
icon: 'cil-puzzle',
|
||||
},
|
||||
{
|
||||
component: 'CNavTitle',
|
||||
name: 'Transports',
|
||||
},
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Transports',
|
||||
to: '/transports',
|
||||
icon: 'cil-cursor',
|
||||
},
|
||||
{
|
||||
component: 'CNavTitle',
|
||||
name: 'Notifications',
|
||||
},
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Notifications',
|
||||
to: '/notifications',
|
||||
icon: 'cil-bell',
|
||||
},
|
||||
{
|
||||
component: 'CNavTitle',
|
||||
name: 'Settings',
|
||||
},
|
||||
{
|
||||
component: 'CNavItem',
|
||||
name: 'Settings',
|
||||
to: '/settings',
|
||||
icon: 'cil-star',
|
||||
},
|
||||
]
|
31
frontend/src/assets/brand/logo-negative.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
export const logoNegative = [
|
||||
'556 134',
|
||||
`
|
||||
<title>coreui vue logo</title>
|
||||
<g>
|
||||
<g style="fill:#1bbd93">
|
||||
<path class="cls-1" d="M347.9818,90.0869l-11.84-43.52-.0644-.1924q0-.5112.6406-.5117h1.2793a.66.66,0,0,1,.7051.5762l10.623,39.68c.042.0859.0859.1279.1289.1279.041,0,.084-.042.127-.1279l10.625-39.68a.657.657,0,0,1,.7031-.5762h1.2168a.54.54,0,0,1,.5762.7041l-11.9043,43.52a.6584.6584,0,0,1-.7041.5761h-1.4082A.6577.6577,0,0,1,347.9818,90.0869Z"/>
|
||||
<path class="cls-1" d="M382.2786,89.5751a10.9023,10.9023,0,0,1-4.3515-4.5439,14.4586,14.4586,0,0,1-1.5362-6.7842V46.5029a.5656.5656,0,0,1,.64-.64h1.2168a.5659.5659,0,0,1,.64.64v32a10.5488,10.5488,0,0,0,2.72,7.5527,10.36,10.36,0,0,0,14.3359,0,10.5493,10.5493,0,0,0,2.7207-7.5527v-32a.5655.5655,0,0,1,.64-.64h1.2159a.5666.5666,0,0,1,.6406.64V78.247a13.01,13.01,0,0,1-3.3926,9.376,11.8974,11.8974,0,0,1-9.0234,3.5527A12.8481,12.8481,0,0,1,382.2786,89.5751Z"/>
|
||||
<path class="cls-1" d="M439.5843,48.1035H419.5521a.2263.2263,0,0,0-.2559.2558V66.8554a.2259.2259,0,0,0,.2559.2559h13.8242a.5665.5665,0,0,1,.6406.64v.96a.5665.5665,0,0,1-.6406.6406H419.5521a.2263.2263,0,0,0-.2559.2559v18.56a.2259.2259,0,0,0,.2559.2559h20.0322a.5665.5665,0,0,1,.64.6406v.96a.5655.5655,0,0,1-.64.64H417.4407a.5654.5654,0,0,1-.6406-.64v-43.52a.5658.5658,0,0,1,.6406-.64h22.1436a.5659.5659,0,0,1,.64.64v.96A.5658.5658,0,0,1,439.5843,48.1035Z"/>
|
||||
<path class="cls-1" d="M454.5921,89.5117a2.8385,2.8385,0,0,1-.8-2.0489,2.9193,2.9193,0,0,1,.8-2.1113,2.7518,2.7518,0,0,1,2.0791-.832,2.8465,2.8465,0,0,1,2.9443,2.9433,2.7561,2.7561,0,0,1-.832,2.08,2.9208,2.9208,0,0,1-2.1123.8008A2.7521,2.7521,0,0,1,454.5921,89.5117Z"/>
|
||||
<path class="cls-1" d="M474.931,88.0078a11.3087,11.3087,0,0,1-3.2-8.4161v-5.44a.5655.5655,0,0,1,.64-.64h1.2158a.5662.5662,0,0,1,.6407.64v5.5039a9.1421,9.1421,0,0,0,2.5283,6.72,8.9734,8.9734,0,0,0,6.6875,2.5606,8.7916,8.7916,0,0,0,9.28-9.28V46.5029a.5655.5655,0,0,1,.64-.64h1.2158a.5656.5656,0,0,1,.64.64V79.5917a11.2541,11.2541,0,0,1-3.2315,8.4161,13.0621,13.0621,0,0,1-17.0556,0Z"/>
|
||||
<path class="cls-1" d="M512.8753,88.1035a10.4847,10.4847,0,0,1-3.36-8.128v-1.792a.5665.5665,0,0,1,.6406-.6406h1.0879a.5666.5666,0,0,1,.64.6406v1.6a8.5461,8.5461,0,0,0,2.752,6.6563,10.5361,10.5361,0,0,0,7.36,2.4961,9.8741,9.8741,0,0,0,6.9766-2.3682,8.2188,8.2188,0,0,0,2.56-6.3359,8.3952,8.3952,0,0,0-1.12-4.416,11.3752,11.3752,0,0,0-3.3281-3.3926,71.6866,71.6866,0,0,0-6.1758-3.7119,71.0151,71.0151,0,0,1-6.24-3.84,12.1824,12.1824,0,0,1-3.4238-3.68,10.2659,10.2659,0,0,1-1.28-5.3437,9.86,9.86,0,0,1,3.0723-7.7441,12.0126,12.0126,0,0,1,8.3193-2.752q5.6969,0,8.9609,3.1035a10.8247,10.8247,0,0,1,3.2637,8.2246v1.6a.5658.5658,0,0,1-.6406.64h-1.1514a.5651.5651,0,0,1-.64-.64V56.8076a8.8643,8.8643,0,0,0-2.6241-6.6885,9.9936,9.9936,0,0,0-7.2324-2.5274,9.37,9.37,0,0,0-6.5283,2.1436,7.8253,7.8253,0,0,0-2.3672,6.1123,7.8088,7.8088,0,0,0,1.0235,4.16,10.3978,10.3978,0,0,0,3.0078,3.039,63.0249,63.0249,0,0,0,5.9521,3.4883,70.7955,70.7955,0,0,1,6.72,4.2559,13.4613,13.4613,0,0,1,3.6485,3.9365,10.044,10.044,0,0,1,1.28,5.1836,10.7185,10.7185,0,0,1-3.2647,8.1924q-3.2637,3.0717-8.832,3.0722Q516.2342,91.1757,512.8753,88.1035Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g style="fill: currentColor">
|
||||
<g>
|
||||
<path d="M99.835,36.0577l-39-22.5167a12,12,0,0,0-12,0l-39,22.5166a12.0339,12.0339,0,0,0-6,10.3924V91.4833a12.0333,12.0333,0,0,0,6,10.3923l39,22.5167a12,12,0,0,0,12,0l39-22.5167a12.0331,12.0331,0,0,0,6-10.3923V46.45A12.0334,12.0334,0,0,0,99.835,36.0577Zm-2,55.4256a4,4,0,0,1-2,3.4641l-39,22.5167a4.0006,4.0006,0,0,1-4,0l-39-22.5167a4,4,0,0,1-2-3.4641V46.45a4,4,0,0,1,2-3.4642l39-22.5166a4,4,0,0,1,4,0l39,22.5166a4,4,0,0,1,2,3.4642Z"/>
|
||||
<path d="M77.8567,82.0046h-2.866a4,4,0,0,0-1.9247.4934L55.7852,91.9833,35.835,80.4648V57.4872l19.95-11.5185,17.2893,9.4549a3.9993,3.9993,0,0,0,1.9192.4906h2.8632a2,2,0,0,0,2-2V51.2024a2,2,0,0,0-1.04-1.7547L59.628,38.9521a8.0391,8.0391,0,0,0-7.8428.09L31.8346,50.56a8.0246,8.0246,0,0,0-4,6.9287v22.976a8,8,0,0,0,4,6.9283l19.95,11.5186a8.0429,8.0429,0,0,0,7.8433.0879l19.19-10.5312a2,2,0,0,0,1.0378-1.7533v-2.71A2,2,0,0,0,77.8567,82.0046Z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M172.58,45.3618a15.0166,15.0166,0,0,0-15,14.9995V77.6387a15,15,0,0,0,30,0V60.3613A15.0166,15.0166,0,0,0,172.58,45.3618Zm7,32.2769a7,7,0,0,1-14,0V60.3613a7,7,0,0,1,14,0Z"/>
|
||||
<path d="M135.9138,53.4211a7.01,7.01,0,0,1,7.8681,6.0752.9894.9894,0,0,0,.9843.865h6.03a1.0108,1.0108,0,0,0,.9987-1.0971,15.0182,15.0182,0,0,0-15.7162-13.8837,15.2881,15.2881,0,0,0-14.2441,15.4163V77.2037A15.288,15.288,0,0,0,136.0792,92.62a15.0183,15.0183,0,0,0,15.7162-13.8842,1.0107,1.0107,0,0,0-.9987-1.0971h-6.03a.9894.9894,0,0,0-.9843.865,7.01,7.01,0,0,1-7.8679,6.0757,7.1642,7.1642,0,0,1-6.0789-7.1849V60.6057A7.1638,7.1638,0,0,1,135.9138,53.4211Z"/>
|
||||
<path d="M218.7572,72.9277a12.1585,12.1585,0,0,0,7.1843-11.0771V58.1494A12.1494,12.1494,0,0,0,213.7921,46H196.835a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V74h6.6216l7.9154,17.4138a1,1,0,0,0,.91.5862h6.5911a1,1,0,0,0,.91-1.4138Zm-.8157-11.0771A4.1538,4.1538,0,0,1,213.7926,66h-9.8511V54h9.8511a4.1538,4.1538,0,0,1,4.1489,4.1494Z"/>
|
||||
<path d="M260.835,46h-26a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h26a1,1,0,0,0,1-1V85a1,1,0,0,0-1-1h-19V72h13a1,1,0,0,0,1-1V65a1,1,0,0,0-1-1h-13V54h19a1,1,0,0,0,1-1V47A1,1,0,0,0,260.835,46Z"/>
|
||||
<path d="M298.835,46h-6a1,1,0,0,0-1,1V69.6475a7.0066,7.0066,0,1,1-14,0V47a1,1,0,0,0-1-1h-6a1,1,0,0,0-1,1V69.6475a15.0031,15.0031,0,1,0,30,0V47A1,1,0,0,0,298.835,46Z"/>
|
||||
<rect x="307.835" y="46" width="8" height="38" rx="1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
`,
|
||||
]
|
30
frontend/src/assets/brand/logo.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
export const logo = [
|
||||
'556 134',
|
||||
`
|
||||
<title>coreui vue</title>
|
||||
<g>
|
||||
<g style="fill:#1bbd93">
|
||||
<path class="cls-1" d="M347.9818,90.0869l-11.84-43.52-.0644-.1924q0-.5112.6406-.5117h1.2793a.66.66,0,0,1,.7051.5762l10.623,39.68c.042.0859.0859.1279.1289.1279.041,0,.084-.042.127-.1279l10.625-39.68a.657.657,0,0,1,.7031-.5762h1.2168a.54.54,0,0,1,.5762.7041l-11.9043,43.52a.6584.6584,0,0,1-.7041.5761h-1.4082A.6577.6577,0,0,1,347.9818,90.0869Z"/>
|
||||
<path class="cls-1" d="M382.2786,89.5751a10.9023,10.9023,0,0,1-4.3515-4.5439,14.4586,14.4586,0,0,1-1.5362-6.7842V46.5029a.5656.5656,0,0,1,.64-.64h1.2168a.5659.5659,0,0,1,.64.64v32a10.5488,10.5488,0,0,0,2.72,7.5527,10.36,10.36,0,0,0,14.3359,0,10.5493,10.5493,0,0,0,2.7207-7.5527v-32a.5655.5655,0,0,1,.64-.64h1.2159a.5666.5666,0,0,1,.6406.64V78.247a13.01,13.01,0,0,1-3.3926,9.376,11.8974,11.8974,0,0,1-9.0234,3.5527A12.8481,12.8481,0,0,1,382.2786,89.5751Z"/>
|
||||
<path class="cls-1" d="M439.5843,48.1035H419.5521a.2263.2263,0,0,0-.2559.2558V66.8554a.2259.2259,0,0,0,.2559.2559h13.8242a.5665.5665,0,0,1,.6406.64v.96a.5665.5665,0,0,1-.6406.6406H419.5521a.2263.2263,0,0,0-.2559.2559v18.56a.2259.2259,0,0,0,.2559.2559h20.0322a.5665.5665,0,0,1,.64.6406v.96a.5655.5655,0,0,1-.64.64H417.4407a.5654.5654,0,0,1-.6406-.64v-43.52a.5658.5658,0,0,1,.6406-.64h22.1436a.5659.5659,0,0,1,.64.64v.96A.5658.5658,0,0,1,439.5843,48.1035Z"/>
|
||||
<path class="cls-1" d="M454.5921,89.5117a2.8385,2.8385,0,0,1-.8-2.0489,2.9193,2.9193,0,0,1,.8-2.1113,2.7518,2.7518,0,0,1,2.0791-.832,2.8465,2.8465,0,0,1,2.9443,2.9433,2.7561,2.7561,0,0,1-.832,2.08,2.9208,2.9208,0,0,1-2.1123.8008A2.7521,2.7521,0,0,1,454.5921,89.5117Z"/>
|
||||
<path class="cls-1" d="M474.931,88.0078a11.3087,11.3087,0,0,1-3.2-8.4161v-5.44a.5655.5655,0,0,1,.64-.64h1.2158a.5662.5662,0,0,1,.6407.64v5.5039a9.1421,9.1421,0,0,0,2.5283,6.72,8.9734,8.9734,0,0,0,6.6875,2.5606,8.7916,8.7916,0,0,0,9.28-9.28V46.5029a.5655.5655,0,0,1,.64-.64h1.2158a.5656.5656,0,0,1,.64.64V79.5917a11.2541,11.2541,0,0,1-3.2315,8.4161,13.0621,13.0621,0,0,1-17.0556,0Z"/>
|
||||
<path class="cls-1" d="M512.8753,88.1035a10.4847,10.4847,0,0,1-3.36-8.128v-1.792a.5665.5665,0,0,1,.6406-.6406h1.0879a.5666.5666,0,0,1,.64.6406v1.6a8.5461,8.5461,0,0,0,2.752,6.6563,10.5361,10.5361,0,0,0,7.36,2.4961,9.8741,9.8741,0,0,0,6.9766-2.3682,8.2188,8.2188,0,0,0,2.56-6.3359,8.3952,8.3952,0,0,0-1.12-4.416,11.3752,11.3752,0,0,0-3.3281-3.3926,71.6866,71.6866,0,0,0-6.1758-3.7119,71.0151,71.0151,0,0,1-6.24-3.84,12.1824,12.1824,0,0,1-3.4238-3.68,10.2659,10.2659,0,0,1-1.28-5.3437,9.86,9.86,0,0,1,3.0723-7.7441,12.0126,12.0126,0,0,1,8.3193-2.752q5.6969,0,8.9609,3.1035a10.8247,10.8247,0,0,1,3.2637,8.2246v1.6a.5658.5658,0,0,1-.6406.64h-1.1514a.5651.5651,0,0,1-.64-.64V56.8076a8.8643,8.8643,0,0,0-2.6241-6.6885,9.9936,9.9936,0,0,0-7.2324-2.5274,9.37,9.37,0,0,0-6.5283,2.1436,7.8253,7.8253,0,0,0-2.3672,6.1123,7.8088,7.8088,0,0,0,1.0235,4.16,10.3978,10.3978,0,0,0,3.0078,3.039,63.0249,63.0249,0,0,0,5.9521,3.4883,70.7955,70.7955,0,0,1,6.72,4.2559,13.4613,13.4613,0,0,1,3.6485,3.9365,10.044,10.044,0,0,1,1.28,5.1836,10.7185,10.7185,0,0,1-3.2647,8.1924q-3.2637,3.0717-8.832,3.0722Q516.2342,91.1757,512.8753,88.1035Z"/>
|
||||
</g>
|
||||
<g style="fill:#3c4b64">
|
||||
<g>
|
||||
<path d="M99.835,36.0577l-39-22.5167a12,12,0,0,0-12,0l-39,22.5166a12.0339,12.0339,0,0,0-6,10.3924V91.4833a12.0333,12.0333,0,0,0,6,10.3923l39,22.5167a12,12,0,0,0,12,0l39-22.5167a12.0331,12.0331,0,0,0,6-10.3923V46.45A12.0334,12.0334,0,0,0,99.835,36.0577Zm-2,55.4256a4,4,0,0,1-2,3.4641l-39,22.5167a4.0006,4.0006,0,0,1-4,0l-39-22.5167a4,4,0,0,1-2-3.4641V46.45a4,4,0,0,1,2-3.4642l39-22.5166a4,4,0,0,1,4,0l39,22.5166a4,4,0,0,1,2,3.4642Z"/>
|
||||
<path d="M77.8567,82.0046h-2.866a4,4,0,0,0-1.9247.4934L55.7852,91.9833,35.835,80.4648V57.4872l19.95-11.5185,17.2893,9.4549a3.9993,3.9993,0,0,0,1.9192.4906h2.8632a2,2,0,0,0,2-2V51.2024a2,2,0,0,0-1.04-1.7547L59.628,38.9521a8.0391,8.0391,0,0,0-7.8428.09L31.8346,50.56a8.0246,8.0246,0,0,0-4,6.9287v22.976a8,8,0,0,0,4,6.9283l19.95,11.5186a8.0429,8.0429,0,0,0,7.8433.0879l19.19-10.5312a2,2,0,0,0,1.0378-1.7533v-2.71A2,2,0,0,0,77.8567,82.0046Z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M172.58,45.3618a15.0166,15.0166,0,0,0-15,14.9995V77.6387a15,15,0,0,0,30,0V60.3613A15.0166,15.0166,0,0,0,172.58,45.3618Zm7,32.2769a7,7,0,0,1-14,0V60.3613a7,7,0,0,1,14,0Z"/>
|
||||
<path d="M135.9138,53.4211a7.01,7.01,0,0,1,7.8681,6.0752.9894.9894,0,0,0,.9843.865h6.03a1.0108,1.0108,0,0,0,.9987-1.0971,15.0182,15.0182,0,0,0-15.7162-13.8837,15.2881,15.2881,0,0,0-14.2441,15.4163V77.2037A15.288,15.288,0,0,0,136.0792,92.62a15.0183,15.0183,0,0,0,15.7162-13.8842,1.0107,1.0107,0,0,0-.9987-1.0971h-6.03a.9894.9894,0,0,0-.9843.865,7.01,7.01,0,0,1-7.8679,6.0757,7.1642,7.1642,0,0,1-6.0789-7.1849V60.6057A7.1638,7.1638,0,0,1,135.9138,53.4211Z"/>
|
||||
<path d="M218.7572,72.9277a12.1585,12.1585,0,0,0,7.1843-11.0771V58.1494A12.1494,12.1494,0,0,0,213.7921,46H196.835a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V74h6.6216l7.9154,17.4138a1,1,0,0,0,.91.5862h6.5911a1,1,0,0,0,.91-1.4138Zm-.8157-11.0771A4.1538,4.1538,0,0,1,213.7926,66h-9.8511V54h9.8511a4.1538,4.1538,0,0,1,4.1489,4.1494Z"/>
|
||||
<path d="M260.835,46h-26a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h26a1,1,0,0,0,1-1V85a1,1,0,0,0-1-1h-19V72h13a1,1,0,0,0,1-1V65a1,1,0,0,0-1-1h-13V54h19a1,1,0,0,0,1-1V47A1,1,0,0,0,260.835,46Z"/>
|
||||
<path d="M298.835,46h-6a1,1,0,0,0-1,1V69.6475a7.0066,7.0066,0,1,1-14,0V47a1,1,0,0,0-1-1h-6a1,1,0,0,0-1,1V69.6475a15.0031,15.0031,0,1,0,30,0V47A1,1,0,0,0,298.835,46Z"/>
|
||||
<rect x="307.835" y="46" width="8" height="38" rx="1"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
`,
|
||||
]
|
12
frontend/src/assets/brand/sygnet.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
export const sygnet = [
|
||||
'160 160',
|
||||
`
|
||||
<title>coreui logo</title>
|
||||
<g>
|
||||
<g style="fill:#fff;">
|
||||
<path d="M125,47.091,86,24.5743a12,12,0,0,0-12,0L35,47.091a12.0336,12.0336,0,0,0-6,10.3923v45.0334a12.0335,12.0335,0,0,0,6,10.3923l39,22.5166a11.9993,11.9993,0,0,0,12,0l39-22.5166a12.0335,12.0335,0,0,0,6-10.3923V57.4833A12.0336,12.0336,0,0,0,125,47.091Zm-2,55.4257a4,4,0,0,1-2,3.464L82,128.4974a4,4,0,0,1-4,0L39,105.9807a4,4,0,0,1-2-3.464V57.4833a4,4,0,0,1,2-3.4641L78,31.5025a4,4,0,0,1,4,0l39,22.5167a4,4,0,0,1,2,3.4641Z"/>
|
||||
<path d="M103.0216,93.0379h-2.866a4,4,0,0,0-1.9246.4935L80.95,103.0167,61,91.4981V68.5206L80.95,57.002l17.2894,9.455a4,4,0,0,0,1.9192.4905h2.8632a2,2,0,0,0,2-2V62.2357a2,2,0,0,0-1.04-1.7547L84.793,49.9854a8.0391,8.0391,0,0,0-7.8428.09L57,61.5929A8.0243,8.0243,0,0,0,53,68.5216v22.976a8,8,0,0,0,4,6.9283l19.95,11.5185a8.0422,8.0422,0,0,0,7.8433.0879l19.19-10.5311a2,2,0,0,0,1.0378-1.7534v-2.71A2,2,0,0,0,103.0216,93.0379Z"/>
|
||||
</g>
|
||||
</g>
|
||||
`,
|
||||
]
|
171
frontend/src/assets/icons/index.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
import {
|
||||
cibFacebook,
|
||||
cibTwitter,
|
||||
cibLinkedin,
|
||||
cibFlickr,
|
||||
cibTumblr,
|
||||
cibXing,
|
||||
cibGithub,
|
||||
cibGoogle,
|
||||
cibStackoverflow,
|
||||
cibYoutube,
|
||||
cibDribbble,
|
||||
cibInstagram,
|
||||
cibPinterest,
|
||||
cibVk,
|
||||
cibYahoo,
|
||||
cibBehance,
|
||||
cibReddit,
|
||||
cibVimeo,
|
||||
cibCcMastercard,
|
||||
cibCcVisa,
|
||||
cibCcStripe,
|
||||
cibCcPaypal,
|
||||
cibCcApplePay,
|
||||
cibCcAmex,
|
||||
} from '@coreui/icons'
|
||||
import { cifUs, cifBr, cifIn, cifFr, cifEs, cifPl } from '@coreui/icons'
|
||||
import {
|
||||
cilArrowBottom,
|
||||
cilArrowRight,
|
||||
cilArrowTop,
|
||||
cilBan,
|
||||
cilBasket,
|
||||
cilBell,
|
||||
cilCalculator,
|
||||
cilCalendar,
|
||||
cilCloudDownload,
|
||||
cilChartPie,
|
||||
cilCheck,
|
||||
cilChevronBottom,
|
||||
cilChevronTop,
|
||||
cilCheckCircle,
|
||||
cilCode,
|
||||
cilCommentSquare,
|
||||
cilCursor,
|
||||
cilDrop,
|
||||
cilDollar,
|
||||
cilEnvelopeClosed,
|
||||
cilEnvelopeOpen,
|
||||
cilEuro,
|
||||
cilGlobeAlt,
|
||||
cilGrid,
|
||||
cilFile,
|
||||
cilJustifyCenter,
|
||||
cilLaptop,
|
||||
cilLayers,
|
||||
cilLightbulb,
|
||||
cilList,
|
||||
cilLocationPin,
|
||||
cilLockLocked,
|
||||
cilMagnifyingGlass,
|
||||
cilMediaPlay,
|
||||
cilMenu,
|
||||
cilMoon,
|
||||
cilNotes,
|
||||
cilOptions,
|
||||
cilPencil,
|
||||
cilPeople,
|
||||
cilPuzzle,
|
||||
cilSettings,
|
||||
cilShieldAlt,
|
||||
cilSpeech,
|
||||
cilSpeedometer,
|
||||
cilStar,
|
||||
cilTask,
|
||||
cilUser,
|
||||
cilUserFemale,
|
||||
cilUserFollow,
|
||||
cilXCircle,
|
||||
} from '@coreui/icons'
|
||||
|
||||
export const iconsSet = Object.assign(
|
||||
{},
|
||||
{
|
||||
cilArrowBottom,
|
||||
cilArrowRight,
|
||||
cilArrowTop,
|
||||
cilBan,
|
||||
cilBasket,
|
||||
cilBell,
|
||||
cilCalculator,
|
||||
cilCalendar,
|
||||
cilCloudDownload,
|
||||
cilChartPie,
|
||||
cilCheck,
|
||||
cilChevronBottom,
|
||||
cilChevronTop,
|
||||
cilCheckCircle,
|
||||
cilCode,
|
||||
cilCommentSquare,
|
||||
cilCursor,
|
||||
cilDrop,
|
||||
cilDollar,
|
||||
cilEnvelopeClosed,
|
||||
cilEnvelopeOpen,
|
||||
cilEuro,
|
||||
cilGlobeAlt,
|
||||
cilGrid,
|
||||
cilFile,
|
||||
cilJustifyCenter,
|
||||
cilLaptop,
|
||||
cilLayers,
|
||||
cilLightbulb,
|
||||
cilList,
|
||||
cilLocationPin,
|
||||
cilLockLocked,
|
||||
cilMagnifyingGlass,
|
||||
cilMediaPlay,
|
||||
cilMenu,
|
||||
cilMoon,
|
||||
cilNotes,
|
||||
cilOptions,
|
||||
cilPencil,
|
||||
cilPeople,
|
||||
cilPuzzle,
|
||||
cilSettings,
|
||||
cilShieldAlt,
|
||||
cilSpeech,
|
||||
cilSpeedometer,
|
||||
cilStar,
|
||||
cilTask,
|
||||
cilUser,
|
||||
cilUserFemale,
|
||||
cilUserFollow,
|
||||
cilXCircle,
|
||||
},
|
||||
{
|
||||
cifUs,
|
||||
cifBr,
|
||||
cifIn,
|
||||
cifFr,
|
||||
cifEs,
|
||||
cifPl,
|
||||
},
|
||||
{
|
||||
cibFacebook,
|
||||
cibTwitter,
|
||||
cibLinkedin,
|
||||
cibFlickr,
|
||||
cibTumblr,
|
||||
cibXing,
|
||||
cibGithub,
|
||||
cibGoogle,
|
||||
cibStackoverflow,
|
||||
cibYoutube,
|
||||
cibDribbble,
|
||||
cibInstagram,
|
||||
cibPinterest,
|
||||
cibVk,
|
||||
cibYahoo,
|
||||
cibBehance,
|
||||
cibReddit,
|
||||
cibVimeo,
|
||||
cibCcMastercard,
|
||||
cibCcVisa,
|
||||
cibCcStripe,
|
||||
cibCcPaypal,
|
||||
cibCcApplePay,
|
||||
cibCcAmex,
|
||||
},
|
||||
)
|
BIN
frontend/src/assets/images/angular.jpg
Executable file
After Width: | Height: | Size: 165 KiB |
BIN
frontend/src/assets/images/avatars/1.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
frontend/src/assets/images/avatars/2.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/src/assets/images/avatars/3.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/src/assets/images/avatars/4.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
frontend/src/assets/images/avatars/5.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
frontend/src/assets/images/avatars/6.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
frontend/src/assets/images/avatars/7.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
frontend/src/assets/images/avatars/8.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
frontend/src/assets/images/avatars/9.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
frontend/src/assets/images/react.jpg
Executable file
After Width: | Height: | Size: 195 KiB |
BIN
frontend/src/assets/images/vue.jpg
Executable file
After Width: | Height: | Size: 167 KiB |
BIN
frontend/src/assets/images/vue400.jpg
Normal file
After Width: | Height: | Size: 5.4 KiB |
46
frontend/src/components/AppBreadcrumb.vue
Normal file
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<CBreadcrumb class="d-md-down-none me-auto mb-0">
|
||||
<CBreadcrumbItem
|
||||
v-for="item in breadcrumbs"
|
||||
:key="item"
|
||||
:href="item.active ? '' : item.path"
|
||||
:active="item.active"
|
||||
>
|
||||
{{ item.name }}
|
||||
</CBreadcrumbItem>
|
||||
</CBreadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import router from '@/router'
|
||||
|
||||
export default {
|
||||
name: 'AppBreadcrumb',
|
||||
setup() {
|
||||
const breadcrumbs = ref()
|
||||
|
||||
const getBreadcrumbs = () => {
|
||||
return router.currentRoute.value.matched.map((route) => {
|
||||
return {
|
||||
active: route.path === router.currentRoute.value.fullPath,
|
||||
name: route.name,
|
||||
path: `${router.options.history.base}${route.path}`,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
router.afterEach(() => {
|
||||
breadcrumbs.value = getBreadcrumbs()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
breadcrumbs.value = getBreadcrumbs()
|
||||
})
|
||||
|
||||
return {
|
||||
breadcrumbs,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
20
frontend/src/components/AppFooter.vue
Normal file
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<CFooter>
|
||||
<div>
|
||||
<a href="https://github.com/Fishwaldo/mouthpiece" target="_blank">MouthPiece</a>
|
||||
<span class="ms-1"
|
||||
>© {{ new Date().getFullYear() }} Justin Hammond.</span
|
||||
>
|
||||
</div>
|
||||
<div class="ms-auto">
|
||||
<span class="me-1" target="_blank">Powered by</span>
|
||||
<a href="https://coreui.io/vue">CoreUI for Vue</a>
|
||||
</div>
|
||||
</CFooter>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppFooter',
|
||||
}
|
||||
</script>
|
63
frontend/src/components/AppHeader.vue
Normal file
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<CHeader position="sticky" class="mb-4">
|
||||
<CContainer fluid>
|
||||
<CHeaderToggler class="ps-1" @click="$store.commit('toggleSidebar')">
|
||||
<CIcon icon="cil-menu" size="lg" />
|
||||
</CHeaderToggler>
|
||||
<CHeaderBrand class="mx-auto d-lg-none" to="/">
|
||||
<CIcon :icon="logo" height="48" alt="Logo" />
|
||||
</CHeaderBrand>
|
||||
<CHeaderNav class="d-none d-md-flex me-auto">
|
||||
<CNavItem>
|
||||
<CNavLink href="/dashboard"> Dashboard </CNavLink>
|
||||
</CNavItem>
|
||||
<CNavItem>
|
||||
<CNavLink href="#">Users</CNavLink>
|
||||
</CNavItem>
|
||||
<CNavItem>
|
||||
<CNavLink href="#">Settings</CNavLink>
|
||||
</CNavItem>
|
||||
</CHeaderNav>
|
||||
<CHeaderNav>
|
||||
<CNavItem>
|
||||
<CNavLink href="#">
|
||||
<CIcon class="mx-2" icon="cil-bell" size="lg" />
|
||||
</CNavLink>
|
||||
</CNavItem>
|
||||
<CNavItem>
|
||||
<CNavLink href="#">
|
||||
<CIcon class="mx-2" icon="cil-list" size="lg" />
|
||||
</CNavLink>
|
||||
</CNavItem>
|
||||
<CNavItem>
|
||||
<CNavLink href="#">
|
||||
<CIcon class="mx-2" icon="cil-envelope-open" size="lg" />
|
||||
</CNavLink>
|
||||
</CNavItem>
|
||||
<AppHeaderDropdownAccnt />
|
||||
</CHeaderNav>
|
||||
</CContainer>
|
||||
<CHeaderDivider />
|
||||
<CContainer fluid>
|
||||
<AppBreadcrumb />
|
||||
</CContainer>
|
||||
</CHeader>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppBreadcrumb from './AppBreadcrumb'
|
||||
import AppHeaderDropdownAccnt from './AppHeaderDropdownAccnt'
|
||||
import { logo } from '@/assets/brand/logo'
|
||||
export default {
|
||||
name: 'AppHeader',
|
||||
components: {
|
||||
AppBreadcrumb,
|
||||
AppHeaderDropdownAccnt,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
logo,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
64
frontend/src/components/AppHeaderDropdownAccnt.vue
Normal file
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<CDropdown variant="nav-item">
|
||||
<CDropdownToggle placement="bottom-end" class="py-0" :caret="false">
|
||||
<CAvatar :src="avatar" size="md" />
|
||||
</CDropdownToggle>
|
||||
<CDropdownMenu class="pt-0">
|
||||
<CDropdownHeader component="h6" class="bg-light fw-semibold py-2">
|
||||
Account
|
||||
</CDropdownHeader>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-bell" /> Updates
|
||||
<CBadge color="info" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-envelope-open" /> Messages
|
||||
<CBadge color="success" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-task" /> Tasks
|
||||
<CBadge color="danger" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-comment-square" /> Comments
|
||||
<CBadge color="warning" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownHeader component="h6" class="bg-light fw-semibold py-2">
|
||||
Settings
|
||||
</CDropdownHeader>
|
||||
<CDropdownItem> <CIcon icon="cil-user" /> Profile </CDropdownItem>
|
||||
<CDropdownItem> <CIcon icon="cil-settings" /> Settings </CDropdownItem>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-dollar" /> Payments
|
||||
<CBadge color="secondary" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-file" /> Projects
|
||||
<CBadge color="primary" class="ms-auto">{{ itemsCount }}</CBadge>
|
||||
</CDropdownItem>
|
||||
<CDropdownDivider />
|
||||
<CDropdownItem>
|
||||
<CIcon icon="cil-shield-alt" /> Lock Account
|
||||
</CDropdownItem>
|
||||
<CDropdownItem @click="logout"> <CIcon icon="cil-lock-locked" /> Logout </CDropdownItem>
|
||||
</CDropdownMenu>
|
||||
</CDropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import avatar from '@/assets/images/avatars/8.jpg'
|
||||
export default {
|
||||
name: 'AppHeaderDropdownAccnt',
|
||||
setup() {
|
||||
return {
|
||||
avatar: avatar,
|
||||
itemsCount: 42,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
this.$store.dispatch('auth/logout')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
55
frontend/src/components/AppSidebar.vue
Normal file
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<CSidebar
|
||||
position="fixed"
|
||||
:unfoldable="sidebarUnfoldable"
|
||||
:visible="sidebarVisible"
|
||||
@visible-change="
|
||||
(event) =>
|
||||
$store.commit({
|
||||
type: 'updateSidebarVisible',
|
||||
value: event,
|
||||
})
|
||||
"
|
||||
>
|
||||
<CSidebarBrand>
|
||||
<CIcon
|
||||
custom-class-name="sidebar-brand-full"
|
||||
:icon="logoNegative"
|
||||
:height="35"
|
||||
/>
|
||||
<CIcon
|
||||
custom-class-name="sidebar-brand-narrow"
|
||||
:icon="sygnet"
|
||||
:height="35"
|
||||
/>
|
||||
</CSidebarBrand>
|
||||
<AppSidebarNav />
|
||||
<CSidebarToggler
|
||||
class="d-none d-lg-flex"
|
||||
@click="$store.commit('toggleUnfoldable')"
|
||||
/>
|
||||
</CSidebar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { AppSidebarNav } from './AppSidebarNav'
|
||||
import { logoNegative } from '@/assets/brand/logo-negative'
|
||||
import { sygnet } from '@/assets/brand/sygnet'
|
||||
export default {
|
||||
name: 'AppSidebar',
|
||||
components: {
|
||||
AppSidebarNav,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore()
|
||||
return {
|
||||
logoNegative,
|
||||
sygnet,
|
||||
sidebarUnfoldable: computed(() => store.state.sidebarUnfoldable),
|
||||
sidebarVisible: computed(() => store.state.sidebarVisible),
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
141
frontend/src/components/AppSidebarNav.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
import { defineComponent, h, onMounted, ref, resolveComponent } from 'vue'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
|
||||
import {
|
||||
CBadge,
|
||||
CSidebarNav,
|
||||
CNavItem,
|
||||
CNavGroup,
|
||||
CNavTitle,
|
||||
} from '@coreui/vue'
|
||||
import nav from '@/_nav.js'
|
||||
|
||||
const normalizePath = (path) =>
|
||||
decodeURI(path)
|
||||
.replace(/#.*$/, '')
|
||||
.replace(/(index)?\.(html)$/, '')
|
||||
|
||||
const isActiveLink = (route, link) => {
|
||||
if (link === undefined) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (route.hash === link) {
|
||||
return true
|
||||
}
|
||||
|
||||
const currentPath = normalizePath(route.path)
|
||||
const targetPath = normalizePath(link)
|
||||
|
||||
return currentPath === targetPath
|
||||
}
|
||||
|
||||
const isActiveItem = (route, item) => {
|
||||
if (isActiveLink(route, item.to)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (item.items) {
|
||||
return item.items.some((child) => isActiveItem(route, child))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const AppSidebarNav = defineComponent({
|
||||
name: 'AppSidebarNav',
|
||||
components: {
|
||||
CNavItem,
|
||||
CNavGroup,
|
||||
CNavTitle,
|
||||
},
|
||||
setup() {
|
||||
const route = useRoute()
|
||||
const firstRender = ref(true)
|
||||
|
||||
onMounted(() => {
|
||||
firstRender.value = false
|
||||
})
|
||||
|
||||
const renderItem = (item) => {
|
||||
if (item.items) {
|
||||
return h(
|
||||
CNavGroup,
|
||||
{
|
||||
...(firstRender.value && {
|
||||
visible: item.items.some((child) => isActiveItem(route, child)),
|
||||
}),
|
||||
},
|
||||
{
|
||||
togglerContent: () => [
|
||||
h(resolveComponent('CIcon'), {
|
||||
customClassName: 'nav-icon',
|
||||
name: item.icon,
|
||||
}),
|
||||
item.name,
|
||||
],
|
||||
default: () => item.items.map((child) => renderItem(child)),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return item.to
|
||||
? h(
|
||||
RouterLink,
|
||||
{
|
||||
to: item.to,
|
||||
custom: true,
|
||||
},
|
||||
{
|
||||
default: (props) =>
|
||||
h(
|
||||
resolveComponent(item.component),
|
||||
{
|
||||
active: props.isActive,
|
||||
href: props.href,
|
||||
onClick: () => props.navigate(),
|
||||
},
|
||||
{
|
||||
default: () => [
|
||||
item.icon &&
|
||||
h(resolveComponent('CIcon'), {
|
||||
customClassName: 'nav-icon',
|
||||
name: item.icon,
|
||||
}),
|
||||
item.name,
|
||||
item.badge &&
|
||||
h(
|
||||
CBadge,
|
||||
{
|
||||
class: 'ms-auto',
|
||||
color: item.badge.color,
|
||||
},
|
||||
{
|
||||
default: () => item.badge.text,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
},
|
||||
)
|
||||
: h(
|
||||
resolveComponent(item.component),
|
||||
{},
|
||||
{
|
||||
default: () => item.name,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return () =>
|
||||
h(
|
||||
CSidebarNav,
|
||||
{},
|
||||
{
|
||||
default: () => nav.map((item) => renderItem(item)),
|
||||
},
|
||||
)
|
||||
},
|
||||
})
|
||||
export { AppSidebarNav }
|
24
frontend/src/generated/core/ApiError.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
|
||||
export class ApiError extends Error {
|
||||
public readonly url: string;
|
||||
public readonly status: number;
|
||||
public readonly statusText: string;
|
||||
public readonly body: any;
|
||||
public readonly request: ApiRequestOptions;
|
||||
|
||||
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||
super(message);
|
||||
|
||||
this.name = 'ApiError';
|
||||
this.url = response.url;
|
||||
this.status = response.status;
|
||||
this.statusText = response.statusText;
|
||||
this.body = response.body;
|
||||
this.request = request;
|
||||
}
|
||||
}
|
16
frontend/src/generated/core/ApiRequestOptions.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiRequestOptions = {
|
||||
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
|
||||
readonly url: string;
|
||||
readonly path?: Record<string, any>;
|
||||
readonly cookies?: Record<string, any>;
|
||||
readonly headers?: Record<string, any>;
|
||||
readonly query?: Record<string, any>;
|
||||
readonly formData?: Record<string, any>;
|
||||
readonly body?: any;
|
||||
readonly mediaType?: string;
|
||||
readonly responseHeader?: string;
|
||||
readonly errors?: Record<number, string>;
|
||||
};
|
10
frontend/src/generated/core/ApiResult.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type ApiResult = {
|
||||
readonly url: string;
|
||||
readonly ok: boolean;
|
||||
readonly status: number;
|
||||
readonly statusText: string;
|
||||
readonly body: any;
|
||||
};
|
128
frontend/src/generated/core/CancelablePromise.ts
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export class CancelError extends Error {
|
||||
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'CancelError';
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export interface OnCancel {
|
||||
readonly isResolved: boolean;
|
||||
readonly isRejected: boolean;
|
||||
readonly isCancelled: boolean;
|
||||
|
||||
(cancelHandler: () => void): void;
|
||||
}
|
||||
|
||||
export class CancelablePromise<T> implements Promise<T> {
|
||||
readonly [Symbol.toStringTag]!: string;
|
||||
|
||||
private _isResolved: boolean;
|
||||
private _isRejected: boolean;
|
||||
private _isCancelled: boolean;
|
||||
private readonly _cancelHandlers: (() => void)[];
|
||||
private readonly _promise: Promise<T>;
|
||||
private _resolve?: (value: T | PromiseLike<T>) => void;
|
||||
private _reject?: (reason?: any) => void;
|
||||
|
||||
constructor(
|
||||
executor: (
|
||||
resolve: (value: T | PromiseLike<T>) => void,
|
||||
reject: (reason?: any) => void,
|
||||
onCancel: OnCancel
|
||||
) => void
|
||||
) {
|
||||
this._isResolved = false;
|
||||
this._isRejected = false;
|
||||
this._isCancelled = false;
|
||||
this._cancelHandlers = [];
|
||||
this._promise = new Promise<T>((resolve, reject) => {
|
||||
this._resolve = resolve;
|
||||
this._reject = reject;
|
||||
|
||||
const onResolve = (value: T | PromiseLike<T>): void => {
|
||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||
return;
|
||||
}
|
||||
this._isResolved = true;
|
||||
this._resolve?.(value);
|
||||
};
|
||||
|
||||
const onReject = (reason?: any): void => {
|
||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||
return;
|
||||
}
|
||||
this._isRejected = true;
|
||||
this._reject?.(reason);
|
||||
};
|
||||
|
||||
const onCancel = (cancelHandler: () => void): void => {
|
||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||
return;
|
||||
}
|
||||
this._cancelHandlers.push(cancelHandler);
|
||||
};
|
||||
|
||||
Object.defineProperty(onCancel, 'isResolved', {
|
||||
get: (): boolean => this._isResolved,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isRejected', {
|
||||
get: (): boolean => this._isRejected,
|
||||
});
|
||||
|
||||
Object.defineProperty(onCancel, 'isCancelled', {
|
||||
get: (): boolean => this._isCancelled,
|
||||
});
|
||||
|
||||
return executor(onResolve, onReject, onCancel as OnCancel);
|
||||
});
|
||||
}
|
||||
|
||||
public then<TResult1 = T, TResult2 = never>(
|
||||
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
||||
): Promise<TResult1 | TResult2> {
|
||||
return this._promise.then(onFulfilled, onRejected);
|
||||
}
|
||||
|
||||
public catch<TResult = never>(
|
||||
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
|
||||
): Promise<T | TResult> {
|
||||
return this._promise.catch(onRejected);
|
||||
}
|
||||
|
||||
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||
return this._promise.finally(onFinally);
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||
return;
|
||||
}
|
||||
this._isCancelled = true;
|
||||
if (this._cancelHandlers.length) {
|
||||
try {
|
||||
for (const cancelHandler of this._cancelHandlers) {
|
||||
cancelHandler();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Cancellation threw an error', error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._cancelHandlers.length = 0;
|
||||
this._reject?.(new CancelError('Request aborted'));
|
||||
}
|
||||
|
||||
public get isCancelled(): boolean {
|
||||
return this._isCancelled;
|
||||
}
|
||||
}
|
31
frontend/src/generated/core/OpenAPI.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
type Headers = Record<string, string>;
|
||||
|
||||
export type OpenAPIConfig = {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||
TOKEN?: string | Resolver<string>;
|
||||
USERNAME?: string | Resolver<string>;
|
||||
PASSWORD?: string | Resolver<string>;
|
||||
HEADERS?: Headers | Resolver<Headers>;
|
||||
ENCODE_PATH?: (path: string) => string;
|
||||
};
|
||||
|
||||
export const OpenAPI: OpenAPIConfig = {
|
||||
BASE: '',
|
||||
VERSION: '0.0.1',
|
||||
WITH_CREDENTIALS: false,
|
||||
CREDENTIALS: 'include',
|
||||
TOKEN: undefined,
|
||||
USERNAME: undefined,
|
||||
PASSWORD: undefined,
|
||||
HEADERS: undefined,
|
||||
ENCODE_PATH: undefined,
|
||||
};
|
304
frontend/src/generated/core/request.ts
Normal file
|
@ -0,0 +1,304 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import axios from 'axios';
|
||||
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { ApiError } from './ApiError';
|
||||
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||
import type { ApiResult } from './ApiResult';
|
||||
import { CancelablePromise } from './CancelablePromise';
|
||||
import type { OnCancel } from './CancelablePromise';
|
||||
import type { OpenAPIConfig } from './OpenAPI';
|
||||
|
||||
const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
|
||||
return value !== undefined && value !== null;
|
||||
};
|
||||
|
||||
const isString = (value: any): value is string => {
|
||||
return typeof value === 'string';
|
||||
};
|
||||
|
||||
const isStringWithValue = (value: any): value is string => {
|
||||
return isString(value) && value !== '';
|
||||
};
|
||||
|
||||
const isBlob = (value: any): value is Blob => {
|
||||
return (
|
||||
typeof value === 'object' &&
|
||||
typeof value.type === 'string' &&
|
||||
typeof value.stream === 'function' &&
|
||||
typeof value.arrayBuffer === 'function' &&
|
||||
typeof value.constructor === 'function' &&
|
||||
typeof value.constructor.name === 'string' &&
|
||||
/^(Blob|File)$/.test(value.constructor.name) &&
|
||||
/^(Blob|File)$/.test(value[Symbol.toStringTag])
|
||||
);
|
||||
};
|
||||
|
||||
const isFormData = (value: any): value is FormData => {
|
||||
return value instanceof FormData;
|
||||
};
|
||||
|
||||
const isSuccess = (status: number): boolean => {
|
||||
return status >= 200 && status < 300;
|
||||
};
|
||||
|
||||
const base64 = (str: string): string => {
|
||||
try {
|
||||
return btoa(str);
|
||||
} catch (err) {
|
||||
// @ts-ignore
|
||||
return Buffer.from(str).toString('base64');
|
||||
}
|
||||
};
|
||||
|
||||
const getQueryString = (params: Record<string, any>): string => {
|
||||
const qs: string[] = [];
|
||||
|
||||
const append = (key: string, value: any) => {
|
||||
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||
};
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isDefined(value)) {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => {
|
||||
process(key, v);
|
||||
});
|
||||
} else if (typeof value === 'object') {
|
||||
Object.entries(value).forEach(([k, v]) => {
|
||||
process(`${key}[${k}]`, v);
|
||||
});
|
||||
} else {
|
||||
append(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
process(key, value);
|
||||
});
|
||||
|
||||
if (qs.length > 0) {
|
||||
return `?${qs.join('&')}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||
const encoder = config.ENCODE_PATH || encodeURI;
|
||||
|
||||
const path = options.url
|
||||
.replace('{api-version}', config.VERSION)
|
||||
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||
if (options.path?.hasOwnProperty(group)) {
|
||||
return encoder(String(options.path[group]));
|
||||
}
|
||||
return substring;
|
||||
});
|
||||
|
||||
const url = `${config.BASE}${path}`;
|
||||
if (options.query) {
|
||||
return `${url}${getQueryString(options.query)}`;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
|
||||
const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||
if (options.formData) {
|
||||
const formData = new FormData();
|
||||
|
||||
const process = (key: string, value: any) => {
|
||||
if (isString(value) || isBlob(value)) {
|
||||
formData.append(key, value);
|
||||
} else {
|
||||
formData.append(key, JSON.stringify(value));
|
||||
}
|
||||
};
|
||||
|
||||
Object.entries(options.formData)
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(v => process(key, v));
|
||||
} else {
|
||||
process(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
return formData;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||
|
||||
const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||
if (typeof resolver === 'function') {
|
||||
return (resolver as Resolver<T>)(options);
|
||||
}
|
||||
return resolver;
|
||||
};
|
||||
|
||||
const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
|
||||
const token = await resolve(options, config.TOKEN);
|
||||
const username = await resolve(options, config.USERNAME);
|
||||
const password = await resolve(options, config.PASSWORD);
|
||||
const additionalHeaders = await resolve(options, config.HEADERS);
|
||||
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
|
||||
|
||||
const headers = Object.entries({
|
||||
Accept: 'application/json',
|
||||
...additionalHeaders,
|
||||
...options.headers,
|
||||
...formHeaders,
|
||||
})
|
||||
.filter(([_, value]) => isDefined(value))
|
||||
.reduce((headers, [key, value]) => ({
|
||||
...headers,
|
||||
[key]: String(value),
|
||||
}), {} as Record<string, string>);
|
||||
|
||||
if (isStringWithValue(token)) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||
const credentials = base64(`${username}:${password}`);
|
||||
headers['Authorization'] = `Basic ${credentials}`;
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
if (options.mediaType) {
|
||||
headers['Content-Type'] = options.mediaType;
|
||||
} else if (isBlob(options.body)) {
|
||||
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||
} else if (isString(options.body)) {
|
||||
headers['Content-Type'] = 'text/plain';
|
||||
} else if (!isFormData(options.body)) {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
const getRequestBody = (options: ApiRequestOptions): any => {
|
||||
if (options.body) {
|
||||
return options.body;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const sendRequest = async <T>(
|
||||
config: OpenAPIConfig,
|
||||
options: ApiRequestOptions,
|
||||
url: string,
|
||||
body: any,
|
||||
formData: FormData | undefined,
|
||||
headers: Record<string, string>,
|
||||
onCancel: OnCancel
|
||||
): Promise<AxiosResponse<T>> => {
|
||||
const source = axios.CancelToken.source();
|
||||
|
||||
const requestConfig: AxiosRequestConfig = {
|
||||
url,
|
||||
headers,
|
||||
data: body ?? formData,
|
||||
method: options.method,
|
||||
withCredentials: config.WITH_CREDENTIALS,
|
||||
cancelToken: source.token,
|
||||
};
|
||||
|
||||
onCancel(() => source.cancel('The user aborted a request.'));
|
||||
|
||||
try {
|
||||
return await axios.request(requestConfig);
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError<T>;
|
||||
if (axiosError.response) {
|
||||
return axiosError.response;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
|
||||
if (responseHeader) {
|
||||
const content = response.headers[responseHeader];
|
||||
if (isString(content)) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const getResponseBody = (response: AxiosResponse<any>): any => {
|
||||
if (response.status !== 204) {
|
||||
return response.data;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||
const errors: Record<number, string> = {
|
||||
400: 'Bad Request',
|
||||
401: 'Unauthorized',
|
||||
403: 'Forbidden',
|
||||
404: 'Not Found',
|
||||
500: 'Internal Server Error',
|
||||
502: 'Bad Gateway',
|
||||
503: 'Service Unavailable',
|
||||
...options.errors,
|
||||
}
|
||||
|
||||
const error = errors[result.status];
|
||||
if (error) {
|
||||
throw new ApiError(options, result, error);
|
||||
}
|
||||
|
||||
if (!result.ok) {
|
||||
throw new ApiError(options, result, 'Generic Error');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request method
|
||||
* @param config The OpenAPI configuration object
|
||||
* @param options The request options from the service
|
||||
* @returns CancelablePromise<T>
|
||||
* @throws ApiError
|
||||
*/
|
||||
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise<T> => {
|
||||
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
||||
try {
|
||||
const url = getUrl(config, options);
|
||||
const formData = getFormData(options);
|
||||
const body = getRequestBody(options);
|
||||
const headers = await getHeaders(config, options, formData);
|
||||
|
||||
if (!onCancel.isCancelled) {
|
||||
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel);
|
||||
const responseBody = getResponseBody(response);
|
||||
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||
|
||||
const result: ApiResult = {
|
||||
url,
|
||||
ok: isSuccess(response.status),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
body: responseHeader ?? responseBody,
|
||||
};
|
||||
|
||||
catchErrorCodes(options, result);
|
||||
|
||||
resolve(result.body);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
37
frontend/src/generated/index.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export { ApiError } from './core/ApiError';
|
||||
export { CancelablePromise, CancelError } from './core/CancelablePromise';
|
||||
export { OpenAPI } from './core/OpenAPI';
|
||||
export type { OpenAPIConfig } from './core/OpenAPI';
|
||||
|
||||
export { App } from './models/App';
|
||||
export { App2 } from './models/App2';
|
||||
export { AppDetails } from './models/AppDetails';
|
||||
export type { AppList } from './models/AppList';
|
||||
export type { CheckerResult } from './models/CheckerResult';
|
||||
export type { ErrorModel } from './models/ErrorModel';
|
||||
export type { FEConfig } from './models/FEConfig';
|
||||
export type { MessageResult } from './models/MessageResult';
|
||||
export type { post_message_request } from './models/post_message_request';
|
||||
export type { stringList } from './models/stringList';
|
||||
export type { TransportConfig } from './models/TransportConfig';
|
||||
export type { User } from './models/User';
|
||||
export type { UserList } from './models/UserList';
|
||||
|
||||
export { $App } from './schemas/$App';
|
||||
export { $App2 } from './schemas/$App2';
|
||||
export { $AppDetails } from './schemas/$AppDetails';
|
||||
export { $AppList } from './schemas/$AppList';
|
||||
export { $CheckerResult } from './schemas/$CheckerResult';
|
||||
export { $ErrorModel } from './schemas/$ErrorModel';
|
||||
export { $FEConfig } from './schemas/$FEConfig';
|
||||
export { $MessageResult } from './schemas/$MessageResult';
|
||||
export { $post_message_request } from './schemas/$post_message_request';
|
||||
export { $stringList } from './schemas/$stringList';
|
||||
export { $TransportConfig } from './schemas/$TransportConfig';
|
||||
export { $User } from './schemas/$User';
|
||||
export { $UserList } from './schemas/$UserList';
|
||||
|
||||
export { DefaultService } from './services/DefaultService';
|
80
frontend/src/generated/models/App.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type App = {
|
||||
/**
|
||||
* Application Name
|
||||
*/
|
||||
appname: string;
|
||||
associatedusers: Array<{
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
email: string;
|
||||
firstname: string;
|
||||
id: number;
|
||||
lastname: string;
|
||||
transports?: Array<{
|
||||
config: string;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
transport: string;
|
||||
updatedat: string;
|
||||
}>;
|
||||
updatedat: string;
|
||||
}>;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
/**
|
||||
* Description of Application
|
||||
*/
|
||||
description: string;
|
||||
filters: Array<{
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
name: string;
|
||||
updatedat: string;
|
||||
}>;
|
||||
/**
|
||||
* Icon of Application
|
||||
*/
|
||||
icon: string;
|
||||
id: number;
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
status: App.status;
|
||||
updatedat: string;
|
||||
/**
|
||||
* URL of Application
|
||||
*/
|
||||
url: string;
|
||||
};
|
||||
|
||||
export namespace App {
|
||||
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
export enum status {
|
||||
ENABLED = 'Enabled',
|
||||
DISABLED = 'Disabled',
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
84
frontend/src/generated/models/App2.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type App2 = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* Application Name
|
||||
*/
|
||||
appname: string;
|
||||
associatedusers: Array<{
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
email: string;
|
||||
firstname: string;
|
||||
id: number;
|
||||
lastname: string;
|
||||
transports?: Array<{
|
||||
config: string;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
transport: string;
|
||||
updatedat: string;
|
||||
}>;
|
||||
updatedat: string;
|
||||
}>;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
/**
|
||||
* Description of Application
|
||||
*/
|
||||
description: string;
|
||||
filters: Array<{
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
name: string;
|
||||
updatedat: string;
|
||||
}>;
|
||||
/**
|
||||
* Icon of Application
|
||||
*/
|
||||
icon: string;
|
||||
id: number;
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
status: App2.status;
|
||||
updatedat: string;
|
||||
/**
|
||||
* URL of Application
|
||||
*/
|
||||
url: string;
|
||||
};
|
||||
|
||||
export namespace App2 {
|
||||
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
export enum status {
|
||||
ENABLED = 'Enabled',
|
||||
DISABLED = 'Disabled',
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
44
frontend/src/generated/models/AppDetails.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type AppDetails = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* Application Name
|
||||
*/
|
||||
appname: string;
|
||||
/**
|
||||
* Description of Application
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Icon of Application
|
||||
*/
|
||||
icon: string;
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
status: AppDetails.status;
|
||||
/**
|
||||
* URL of Application
|
||||
*/
|
||||
url: string;
|
||||
};
|
||||
|
||||
export namespace AppDetails {
|
||||
|
||||
/**
|
||||
* Status of Application
|
||||
*/
|
||||
export enum status {
|
||||
ENABLED = 'Enabled',
|
||||
DISABLED = 'Disabled',
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
7
frontend/src/generated/models/AppList.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { App } from './App';
|
||||
|
||||
export type AppList = Array<App>;
|
17
frontend/src/generated/models/CheckerResult.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type CheckerResult = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
details?: Record<string, {
|
||||
error?: string;
|
||||
status: string;
|
||||
timestamp?: string;
|
||||
}>;
|
||||
status: string;
|
||||
};
|
||||
|
48
frontend/src/generated/models/ErrorModel.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type ErrorModel = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* A human-readable explanation specific to this occurrence of the problem.
|
||||
*/
|
||||
detail?: string;
|
||||
/**
|
||||
* Optional list of individual error details
|
||||
*/
|
||||
errors?: Array<{
|
||||
/**
|
||||
* Where the error occured, e.g. 'body.items[3].tags' or 'path.thing-id'
|
||||
*/
|
||||
location?: string;
|
||||
/**
|
||||
* Error message text
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* The value at the given location
|
||||
*/
|
||||
value?: any;
|
||||
}>;
|
||||
/**
|
||||
* A URI reference that identifies the specific occurence of the problem.
|
||||
*/
|
||||
instance?: string;
|
||||
/**
|
||||
* HTTP status code
|
||||
*/
|
||||
status?: number;
|
||||
/**
|
||||
* A short, human-readable summary of the problem type. This value should not change between occurances of the error.
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* A URI reference to human-readable documentation for the error.
|
||||
*/
|
||||
type?: string;
|
||||
};
|
||||
|
20
frontend/src/generated/models/FEConfig.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type FEConfig = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* Provider OAuth Config for Frontend
|
||||
*/
|
||||
oauthproviders: Record<string, {
|
||||
/**
|
||||
* OAuth Client ID
|
||||
*/
|
||||
clientid: string;
|
||||
}>;
|
||||
};
|
||||
|
19
frontend/src/generated/models/MessageResult.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type MessageResult = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* Message ID
|
||||
*/
|
||||
message_id: number;
|
||||
/**
|
||||
* Status of Message
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
20
frontend/src/generated/models/TransportConfig.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type TransportConfig = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
config: string;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
transport: string;
|
||||
updatedat: string;
|
||||
};
|
||||
|
28
frontend/src/generated/models/User.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type User = {
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
email: string;
|
||||
firstname: string;
|
||||
id: number;
|
||||
lastname: string;
|
||||
transports?: Array<{
|
||||
config: string;
|
||||
createdat: string;
|
||||
deletedat: {
|
||||
time: string;
|
||||
valid: boolean;
|
||||
};
|
||||
id: number;
|
||||
transport: string;
|
||||
updatedat: string;
|
||||
}>;
|
||||
updatedat: string;
|
||||
};
|
||||
|
7
frontend/src/generated/models/UserList.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { User } from './User';
|
||||
|
||||
export type UserList = Array<User>;
|
35
frontend/src/generated/models/post_message_request.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type post_message_request = {
|
||||
/**
|
||||
* An optional URL to a JSON Schema document describing this resource
|
||||
*/
|
||||
$schema?: string;
|
||||
/**
|
||||
* Additional Fields
|
||||
*/
|
||||
fields?: Record<string, any>;
|
||||
/**
|
||||
* Message to be Sent
|
||||
*/
|
||||
message: string;
|
||||
/**
|
||||
* Severity of Message
|
||||
*/
|
||||
severity?: string;
|
||||
/**
|
||||
* Short Message to be Sent
|
||||
*/
|
||||
shortmessage?: string;
|
||||
/**
|
||||
* Timestamp of Message
|
||||
*/
|
||||
timestamp?: string;
|
||||
/**
|
||||
* Topic of Message
|
||||
*/
|
||||
topic?: string;
|
||||
};
|
||||
|
6
frontend/src/generated/models/stringList.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
|
||||
export type stringList = Array<string>;
|
195
frontend/src/generated/schemas/$App.ts
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const $App = {
|
||||
properties: {
|
||||
appname: {
|
||||
type: 'string',
|
||||
description: `Application Name`,
|
||||
isRequired: true,
|
||||
pattern: '^[a-z0-9]+$',
|
||||
},
|
||||
associatedusers: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
firstname: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
lastname: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
transports: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
config: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
transport: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: `Description of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
filters: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
description: `Icon of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
status: {
|
||||
type: 'Enum',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: `URL of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
} as const;
|
200
frontend/src/generated/schemas/$App2.ts
Normal file
|
@ -0,0 +1,200 @@
|
|||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const $App2 = {
|
||||
properties: {
|
||||
$schema: {
|
||||
type: 'string',
|
||||
description: `An optional URL to a JSON Schema document describing this resource`,
|
||||
format: 'uri',
|
||||
},
|
||||
appname: {
|
||||
type: 'string',
|
||||
description: `Application Name`,
|
||||
isRequired: true,
|
||||
pattern: '^[a-z0-9]+$',
|
||||
},
|
||||
associatedusers: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
firstname: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
lastname: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
transports: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
config: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
transport: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: `Description of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
filters: {
|
||||
type: 'array',
|
||||
contains: {
|
||||
properties: {
|
||||
createdat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
deletedat: {
|
||||
properties: {
|
||||
time: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
valid: {
|
||||
type: 'boolean',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
},
|
||||
},
|
||||
isRequired: true,
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
description: `Icon of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
id: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
format: 'int32',
|
||||
},
|
||||
status: {
|
||||
type: 'Enum',
|
||||
isRequired: true,
|
||||
},
|
||||
updatedat: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
format: 'date-time',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
description: `URL of Application`,
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
} as const;
|