Serves as a starting point for all BADC projects
// to run locally (defaults to port 8080, can be adjusted by the `PORT` env var)
npm install
npm run serve
// to build
npm run build
// run all tests
npm run test
npm run watch
// run one test
npm run test SomeTest
npm run watch SomeTest
// run all unit tests
npm run test:unit
npm run watch:unit
// run all integration tests
npm run test:integration
npm run watch:integration
- add
.env.local
to base directory (this file will not be commited)
# setup
NODE_ENV=development
PORT=5000
# project
VUE_APP_PROJECT_TITLE=
VUE_APP_PROJECT_BASE_API=
# authentication
VUE_APP_OKTA_ISSUER=
VUE_APP_OKTA_CLIENT_ID=
VUE_APP_OKTA_REDIRECT_URI=
VUE_APP_OKTA_BASE_URL=
VUE_APP_OKTA_IDP_ID=
Role access is controlled by sections
. A section is a collection of roles that have access to similar features. Define sections
and roles
in src/roles.js
Specify access on each route by setting the section
or allowedRoles
meta properties. These can be used sperate, together, or not at all. Routes without either of these two properties will be accesable by all roles.
{
name: 'example',
meta: {
section: 'home', // section this route belongs to
allowedRoles: ['SOME_ROLE'], // which roles are allowed to access this route
}
Check section access with hasAccess
. If you'd like to check for a single role use hasRole
.
this.$h.hasAccess('some_section')
this.$h.hasRole('SOME_ROLE')
Data is requested through the Resource
system.
- Create a new resource in
src/data/resources
- Add your resource name to
index.js
- Add api calls to the resource (examples)
- Use your resource:
import { request, requestResource } from '@/services/RequestService'
// call with an axios config object
request({ endpoint: 'example' })
// call with a resource name
requestResource('resource-name')
// optionally, you can pass a formating function as well as a validation function
requestResource('resource-name', format, validate)
import RequestMixin from '@/mixins/RequestMixin'
// methods are same as above
this.$request({ endpoint: 'endpoint' })
this.$requestResource('resource-name')
// request is kept track of with
this.$state
/*
{
data: {},
loading: true,
error: undefined,
}
*/
<data-wrapper resource="resource-name" v-slot={ _state }>
<!-- loading slot -->
<div slot="loading">
{{_state.loading}}
</div>
<!-- error slot -->
<div slot="error">
{{_state.error}}
</div>
<!-- response slot -->
<div>
{{_state.data}}
</div>
</data-wrapper>
These are defined in src/data/resources
Returns a valid axios config from the query
function
example: {
query: () => ({
endpoint: 'example',
}),
},
Optionally, params are provided as an argument to the query
function
exampleWithParams: {
query: (params) => ({
endpoint: 'example',
params: {
...params
},
}),
},
You can provide formatter
which intercepts, transforms, and returns the modified response
exampleWithFormatter: {
query: () => ({
endpoint: 'example',
params: {},
}),
formatter: (response) => {
return response
},
},
Note: `formatter` can be async. Workers should be used if the response is large enough to prevent UI blocking
Provide a validator
which intercepts, validates, and passes the response on if no error is returned. Return the error as a string, or return undefined
if the response is valid
exampleWithValidator: {
query: () => ({
endpoint: 'example',
params: {},
}),
validation: (response) => {
if (!response.hasOwnProperty('key')) {
return 'Validation failed'
}
return
},
},
Disable authentication
exampleWithNoAuth: {
query: () => ({
endpoint: 'example',
headers: {
authentication: false,
},
}),
},