Remove coreui (#76)

* adding typing and flake8

* removing coreui. ComicCard.vue finished

* removing coreui. ConfirmButton.vue finished

* removing coreui. more pages finished.

* removing coreui. all pages finished

* removing coreui. all pages finished

* version bump and update python deps.

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/InitialSetup.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheAccountForm.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheAccountForm.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ConfirmButton.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/vue.config.js

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/ComicPaginate.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update frontend/src/components/TheNavbar.vue

Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>

* Update TheNavbar.vue

Co-authored-by: Peter Dwyer <peter.dwyer@clanwilliamhealth.com>
Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>
This commit is contained in:
2022-09-07 15:14:03 +01:00
committed by GitHub
parent 2af8e18f0a
commit 01e73cc9b3
27 changed files with 1574 additions and 1518 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -4,34 +4,26 @@
"private": true,
"scripts": {
"serve": "webpack-dev-server --config webpack.dev.js",
"build": "npx webpack --config webpack.prod.js",
"build": "webpack --config webpack.prod.js",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@coreui/coreui": "^4.2.0",
"@coreui/vue": "^4.3.0",
"@fortawesome/fontawesome-svg-core": "^6.1.2",
"@fortawesome/free-solid-svg-icons": "^6.1.2",
"@fortawesome/vue-fontawesome": "^3.0.1",
"axios": "^0.27.2",
"axios-jwt": "^1.8.0",
"bootstrap": "^4.6.2",
"core-js": "^3.8.3",
"bootstrap": "^5.2.0",
"hammerjs": "^2.0.8",
"jwt-decode": "^3.1.2",
"pdfvuer": "^2.0.1",
"reveal.js": "^4.3.1",
"reveal.js-menu": "^2.1.0",
"style-loader": "^3.3.1",
"timeago.js": "^4.0.2",
"vue": "^3.2.13",
"vue-loader": "^17.0.0",
"vue-router": "^4.0.3",
"vue-toast-notification": "3.0",
"vuejs-paginate-next": "^1.0.2",
"vuex": "^4.0.0",
"webpack": "^5.74.0",
"webpack-bundle-tracker": "^1.6.0"
"webpack": "^5.74.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@@ -45,7 +37,12 @@
"eslint-plugin-vue": "^8.0.3",
"jshint": "^2.13.5",
"mini-css-extract-plugin": "^2.6.1",
"webpack-cli": "^4.10.0"
"terser-webpack-plugin": "^5.3.6",
"webpack-bundle-analyzer": "^4.6.1",
"webpack-cli": "^4.10.0",
"webpack-bundle-tracker": "^1.6.0",
"style-loader": "^3.3.1",
"vue-loader": "^17.0.0"
},
"eslintConfig": {
"root": true,
@@ -62,9 +59,6 @@
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
"defaults"
]
}

View File

@@ -1,41 +1,43 @@
<template>
<CButton color="secondary" @click="visible = true">Add User</CButton>
<CModal :visible="visible" @close="visible = false">
<CModalHeader>
<CModalTitle>Add user</CModalTitle>
</CModalHeader>
<CForm @submit="addUser">
<CModalBody>
<CFormInput
type="text"
label="Username"
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
</CModalBody>
<CModalFooter>
<CButton color="secondary" @click="visible = false">
Close
</CButton>
<CButton color="primary" type="submit">Submit</CButton>
</CModalFooter>
</CForm>
</CModal>
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#addUserModal">Add User</button>
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add user</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form @submit="addUser">
<div class="modal-body">
<div class="mb-3">
<label for="usernameInput" class="form-label">Username</label>
<input type="text" class="form-control" id="usernameInput" aria-describedby="usernameHelp" v-model="username">
<div id="usernameHelp" class="form-text">Please enter a unique username</div>
</div>
<div class="mb-3">
<label for="emailInput" class="form-label">Email address</label>
<input type="email" class="form-control" id="emailInput" aria-describedby="emailHelp" v-model="email">
<div id="emailHelp" class="form-text">Must be 8-20 characters long.</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import api from "@/api";
import 'bootstrap/js/dist/modal'
export default {
name: "AddUser",
data() {
return {
visible: false,
username: '',
email: ''
}
@@ -58,7 +60,6 @@ export default {
color: 'success',
text: 'New user "' + response.data.username + '" created with password "' + response2.data.password + '".'
})
this.visible=false
this.$emit('user-added')
})
}).catch(err => {
@@ -66,7 +67,6 @@ export default {
color: 'danger',
text: 'Cannot create user "' + this.username + '" with error "' + (err.response.data.username? err.response.data.username: err.response.data.email) + '".'
})
this.visible = false
})
}
},
@@ -76,4 +76,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,7 +1,8 @@
<template>
<CAlert :color="message.color" dismissible v-for="message in messages" :key="message.text">
<div class="alert alert-dismissible fade show" :class="'alert-'+message.color" role="alert" v-for="message in messages" :key="message.text">
{{message.text}}
</CAlert>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</template>
<script>
@@ -20,4 +21,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,66 +1,77 @@
<template>
<CCol>
<CCard class="">
<CCardImage orientation="top" :src="thumbnail"/>
<CCardBody class="pb-0 pt-0 pl-1 pr-1 card-img-overlay d-flex" @click="$router.push((data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }}))">
<div class="col">
<div class="card">
<div class="card card-body p-0" @click="$router.push((data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }}))">
<img :src="thumbnail" class="card-img-top" :alt="data.title">
<span class="badge rounded-pill bg-primary unread-badge" v-if="this.unread > 0 && data.type === 'Directory'">{{ this.unread }}</span>
<span class="badge rounded-pill bg-warning classification-badge" v-if="card_type === 'Directory'" >{{ this.$store.state.classifications.find(i => i.value === classification).label }}</span>
<CCardTitle class="align-self-end text-break" style="">
<h5 class="card-title text-break mb-0">
<router-link :to="(data.type === 'Directory' ? {'name': 'browse', params: { selector: data.selector }} : {'name': 'read', params: { selector: data.selector }})">{{ data.title }}</router-link>
</CCardTitle>
</CCardBody>
<CCardFooter class="pl-0 pr-0 pt-0">
<CProgress class="mb-1 position-relative" >
<CProgressBar :value="progressPercentCalc" />
</h5>
</div>
<div class="card-footer px-0 pb-0">
<div class="progress position-relative">
<div class="progress-bar" role="progressbar" aria-label="Basic example" :style="'width: '+ progressPercentCalc +'%;'" :aria-valuenow="progressPercentCalc" aria-valuemin="0" aria-valuemax="100"></div>
<small class="justify-content-center d-flex position-absolute w-100 h-100" style="line-height: normal">{{ progressCalc }} / {{data.total}}</small>
</CProgress>
<CButtonGroup class="w-100">
<CButton color="primary" @click="updateComic('mark_unread')" ><font-awesome-icon icon='book' /></CButton>
<CButton color="primary" @click="updateComic('mark_read')" ><font-awesome-icon icon='book-open' /></CButton>
<CDropdown variant="btn-group">
<CDropdownToggle color="primary"><font-awesome-icon icon='edit' /></CDropdownToggle>
<CDropdownMenu>
<CDropdownItem @click="updateComic('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</CDropdownItem>
<CDropdownItem @click="updateComic('mark_read')"><font-awesome-icon icon='book-open' />Mark read</CDropdownItem>
<CDropdownItem v-if="data.type === 'ComicBook'" @click="$emit('markPreviousRead', data.selector)"><font-awesome-icon icon='book' /><font-awesome-icon icon='turn-up' />Mark previous comics read</CDropdownItem>
<CDropdownItem v-if="data.type === 'Directory'" @click="editDirectoryVisible = true"><font-awesome-icon icon='edit' />Edit comic</CDropdownItem>
</CDropdownMenu>
</CDropdown>
</CButtonGroup>
</CCardFooter>
</CCard>
<CModal :visible="editDirectoryVisible" @close="editDirectoryVisible = false">
<CModalHeader>
<CModalTitle>{{ data.title }}</CModalTitle>
</CModalHeader>
<CForm @submit="updateDirectory">
<CModalBody>
<CFormSelect
label="Classification"
aria-label="Set Classification"
v-model="new_classification"
:options="[...this.$store.state.classifications]">
</CFormSelect>
<CFormCheck
label="Recursive"
class="mt-2"
v-model="recursive"
/>
</CModalBody>
<CModalFooter>
<CButton color="secondary" @click="editDirectoryVisible = false ">
Close
</CButton>
<CButton color="primary" type="submit">Save changes</CButton>
</CModalFooter>
</CForm>
</CModal>
</CCol>
</div>
<div class="btn-group w-100 pt-1" role="group" aria-label="Basic example">
<button type="button" class="btn btn-primary" @click="updateComic('mark_unread')"><font-awesome-icon icon='book' /></button>
<button type="button" class="btn btn-primary" @click="updateComic('mark_read')" ><font-awesome-icon icon='book-open' /></button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<font-awesome-icon icon='edit' />
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" @click="updateComic('mark_unread')"><font-awesome-icon icon='book' /> Mark Un-read</a></li>
<li><a class="dropdown-item" @click="updateComic('mark_read')"><font-awesome-icon icon='book-open' /> Mark read</a></li>
<li><a class="dropdown-item" v-if="data.type === 'ComicBook'" @click="$emit('markPreviousRead', data.selector)"><font-awesome-icon icon='book' /><font-awesome-icon icon='turn-up' />Mark previous comics read</a></li>
<li><a class="dropdown-item" v-if="data.type === 'Directory'" data-bs-toggle="modal" :data-bs-target="'#'+data.selector"><font-awesome-icon icon='edit' />Edit comic</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" :id="data.selector" tabindex="-1" :aria-labelledby="data.selector+'-label'" aria-hidden="true" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" :id="data.selector+'-label'">{{ data.title }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form @submit="updateDirectory">
<div class="modal-body">
<div class="mb-3">
<label class="form-check-label mb-1" :for="data.selector+'-classification'" >
Classification
</label>
<select class="form-select" :id="data.selector+'-classification'" v-model="new_classification">
<option v-for="class_options in [...this.$store.state.classifications]" :key="class_options.value" :value="class_options.value">{{class_options.label}}</option>
</select>
</div>
<div class="mb-3">
<input class="form-check-input" type="checkbox" value="" :id="data.selector+'-recursive'" v-model="recursive">
<label class="form-check-label px-1" :for="data.selector+'-recursive'" >
Recursive
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import {useToast} from "vue-toast-notification";
import api from "@/api";
import 'bootstrap/js/dist/modal'
export default {
name: "ComicCard",
@@ -160,15 +171,12 @@ export default {
.card-title a {
color: white;
text-shadow: .2rem .2rem .3rem black ;
}
h5.card-title {
margin-bottom: 75px;
position: absolute;
bottom: 0;
left: 0;
text-decoration: none;
background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent);
}
h5.card-title::before {
filter: blur(12px);
width: 100%;
}
.card .unread-badge {
@@ -188,4 +196,4 @@ h5.card-title::before {
padding:5px;
color:black;
}
</style>
</style>

View File

@@ -0,0 +1,73 @@
<template>
<ul class="list-group list-group-horizontal">
<li class="list-group-item" @click="this.$emit('prevComic')">Prev&nbsp;Comic</li>
<li class="list-group-item" @click="prevPage">Prev</li>
<template v-for="ind in visible_pages" :key="ind">
<li class="list-group-item" :class="(ind===modelValue ? 'list-group-item-primary': '')" @click="setPage(ind)">{{ ind }}</li>
</template>
<li class="list-group-item" @click="nextPage">Next</li>
<li class="list-group-item" @click="this.$emit('nextComic')">Next&nbsp;Comic</li>
</ul>
</template>
<script>
export default {
name: "ComicPaginate",
props: {
page_count: Number,
modelValue: Number,
},
emits: ['update:modelValue', 'setPage', 'prevComic', 'nextComic'],
methods: {
setPage(evt) {
if (evt !== '...'){
this.$emit("setPage", evt)
}
},
nextPage(){
if (this.modelValue === this.page_count){
this.$emit('nextComic')
} else {
this.setPage(this.modelValue + 1)
}
},
prevPage(){
if (this.modelValue === 1) {
this.$emit('prevComic')
} else {
this.setPage(this.modelValue - 1)
}
}
},
computed: {
visible_pages(){
let out = []
if (this.page_count <= 5) {
for (let i = 1; i <= this.page_count; i++){
out.push(i)
}
return out
}
let min = Math.max(1, this.modelValue - 2)
let max = Math.min(this.page_count, this.modelValue + 2)
for (let i = min; i <= max; i++){
out.push(i)
}
if (out[0] !== 1) {
out.splice(0, 1, ...[1, "..."])
}
if (out[out.length - 1] !==this.page_count){
out.splice(out.length - 1, 1, ...["...", this.page_count])
}
return out
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,16 +1,13 @@
<template>
<CButtonGroup>
<CButton :color="color" v-if="!confirm" @click="confirm = !confirm">{{ label }}</CButton>
<CButton color="success" class="text-nowrap" v-if="confirm" variant="outline" @click="performAction">
<font-awesome-icon icon='check' class=""/>
Yes
</CButton>
<CButton color="danger" class="text-nowrap" v-if="confirm" variant="outline"
@click="confirm = !confirm">
<font-awesome-icon icon='times' class=""/>
No
</CButton>
</CButtonGroup>
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn" :class="'btn-'+color" v-if="!confirm" @click="confirm = !confirm">{{ label }}</button>
<button type="button" class="btn btn-outline-success text-nowrap" v-if="confirm" @click="performAction">
<font-awesome-icon icon="check" class="" />Yes
</button>
<button type="button" class="btn btn-outline-danger text-nowrap" v-if="confirm" @click="confirm = !confirm">
<font-awesome-icon icon='times' class=""/>No
</button>
</div>
</template>
<script>
export default {

View File

@@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@@ -1,30 +1,20 @@
<template>
<h1>Create your admin account.</h1>
<CForm @submit="saveForm">
<CFormInput
type="text"
label="Username"
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
<CFormInput
type="password"
label="Password"
v-model="password"
/>
<CFormInput
type="password"
label="Confirm Password"
v-model="confirm_password"
/>
<CButton color="primary" type="submit" class="mr-5 mt-2">Save</CButton>
</CForm>
<form @submit="saveForm">
<label class="form-label">Username</label>
<input class="form-control" type="text" v-model="username" />
<label class="form-label">Email address</label>
<input class="form-control" type="email" v-model="email">
<label class="form-label">Password</label>
<input class="form-control" type="password" v-model="password">
<label class="form-label">Confirm Password</label>
<input class="form-control" type="password" v-model="confirm_password">
<button class="btn btn-primary mr-5 mt-2" type="submit">Save</button>
</form>
</template>
<script>
@@ -60,4 +50,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,66 +1,35 @@
<template>
<CContainer>
<CForm @submit="updateAccount">
<CFormInput
type="text"
label="Username"
readonly
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
:placeholder="email"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
:valid="validateEmail(email)"
/>
<CFormInput
type="password"
label="Current Password"
placeholder="Enter Current Password"
text="Must enter current password to change settings."
v-model="current_password"
feedback-invalid="Wrong Password."
:valid="current_password.length > 0"
/>
<CFormInput
type="password"
label="New Password"
placeholder="Enter New Password"
text="Must be at least 9 characters long."
v-model="new_password"
feedback-invalid="Password is not complex enough."
:valid="checkNewPassword(new_password)"
/>
<CFormInput
type="password"
label="New Password Confirm"
placeholder="Enter New Password"
text="Must be at least 9 characters long."
v-model="new_password_confirm"
feedback-invalid="New passwords should match."
:valid="new_password === new_password_confirm && new_password.length > 8"
/>
<CButton color="primary" type="submit">Save</CButton>
</CForm>
</CContainer>
<div class="container">
<form @submit="updateAccount">
<label class="form-label">Username</label>
<input class="form-control" readonly type="text" v-model="username" />
<label class="form-label">Email address</label>
<input placeholder="" class="form-control" type="email" v-model="email" />
<label class="form-label">Current Password</label>
<input placeholder="Enter Current Password" class="form-control" type="password" v-model="current_password"/>
<div class="form-text">Must enter current password to change settings.</div>
<label class="form-label">New Password</label><input placeholder="Enter New Password" class="form-control" type="password" v-model="new_password"/>
<div class="form-text">Must be at least 9 characters long.</div>
<label class="form-label">New Password Confirm</label><input placeholder="Enter New Password" class="form-control" type="password" v-model="new_password_confirm"/>
<div class="form-text">Must be at least 9 characters long.</div>
<button class="btn btn-primary" type="submit">Save</button>
</form>
</div>
</template>
<script>
import {CForm, CFormInput, CContainer, CButton} from "@coreui/vue";
import api from "@/api";
import {useToast} from "vue-toast-notification";
const toast = useToast();
export default {
name: "TheAccountForm",
components: {
CForm,
CFormInput,
CContainer,
CButton
},
components: {},
data () {
return {
username: '',
@@ -87,7 +56,10 @@ export default {
updateAccount () {
if (!this.current_password) {
toast.error('Please enter your current password.', {position:'top'});
} else if (this.email === this.$store.state.user.email && this.new_password.length === 0){
toast.error('No changes detected', {position:'top'});
} else {
console.log(this.email === this.$store.state.user.email)
if (this.email !== this.$store.state.user.email) {
let payload = {
username: this.username,
@@ -101,7 +73,7 @@ export default {
toast.error(error.response.data.errors)
})
}
if (this.new_password === this.new_password_confirm) {
if (this.new_password === this.new_password_confirm && this.new_password.length > 0) {
let payload = {
username: this.username,
old_password: this.current_password,
@@ -119,16 +91,10 @@ export default {
}
},
validateEmail(mail){
return (/\S+@\S+\.\S+/.test(mail))
},
checkNewPassword(pass){
return (pass.length >= 9)
}
}
}
</script>
<style scoped>
</style>
</style>

View File

@@ -1,32 +1,30 @@
<template>
<CBreadcrumb>
<nav aria-label="breadcrumb" class="px-5">
<ol class="breadcrumb " >
<template v-for="(item, index) in crumbs" :key="item.id">
<template v-if="index !== crumbs.length - 1">
<CBreadcrumbItem v-if="item.selector">
<li class="breadcrumb-item" v-if="item.selector">
<router-link :to="{'name': 'browse', params: { selector: item.selector }}">{{ item.name }}</router-link>
</CBreadcrumbItem>
<CBreadcrumbItem v-else-if="item.route">
</li>
<li class="breadcrumb-item" v-else-if="item.route">
<router-link :to="item.route">{{ item.name }}</router-link>
</CBreadcrumbItem>
<CBreadcrumbItem v-else>
</li>
<li class="breadcrumb-item" v-else>
<router-link :to="{'name': 'browse'}">{{ item.name }}</router-link>
</CBreadcrumbItem>
</li>
</template>
<CBreadcrumbItem v-else active>{{ item.name }}</CBreadcrumbItem>
<li class="breadcrumb-item active" aria-current="page" v-else>{{ item.name }}</li>
</template>
</CBreadcrumb>
</ol>
</nav>
</template>
<script>
import { CBreadcrumbItem, CBreadcrumb } from '@coreui/vue'
import api from "@/api";
export default {
name: "TheBreadcrumbs",
components: {
CBreadcrumb,
CBreadcrumbItem,
},
components: { },
data () {
return {
crumbs: []
@@ -68,5 +66,10 @@ export default {
</script>
<style scoped>
</style>
.breadcrumb-item a {
text-decoration: none;
}
nav {
background: lightgrey;
}
</style>

View File

@@ -1,26 +1,24 @@
<template>
<CContainer fluid>
<CRow>
<CInputGroup>
<CFormInput placeholder="Search" aria-label="Filter comics by name" v-model="this.filters.search_string"/>
<CButton type="button" :color="(!filters.filter_read && !filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=false; filters.filter_unread=false">All</CButton>
<CButton type="button" :color="(filters.filter_read && !filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=true; filters.filter_unread=false">Read</CButton>
<CButton type="button" :color="(!filters.filter_read && filters.filter_unread? 'primary' : 'secondary')" variant="outline" @click="filters.filter_read=false; filters.filter_unread=true">Un-read</CButton>
<CDropdown variant="input-group">
<CDropdownToggle color="secondary" variant="outline">Action</CDropdownToggle>
<CDropdownMenu>
<CDropdownItem @click="markAll('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</CDropdownItem>
<CDropdownItem @click="markAll('mark_read')"><font-awesome-icon icon='book-open' />Mark read</CDropdownItem>
</CDropdownMenu>
</CDropdown>
</CInputGroup>
</CRow>
<div class="container-fluid">
<div class="row">
<div class="input-group">
<input class="form-control" aria-label="Filter comics by name" placeholder="Search" v-model="this.filters.search_string">
<button type="button" class="btn" :class="(!filters.filter_read && !filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=false; filters.filter_unread=false">All</button>
<button type="button" class="btn" :class="(filters.filter_read && !filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=true; filters.filter_unread=false">Read</button>
<button type="button" class="btn" :class="(!filters.filter_read && filters.filter_unread? 'btn-outline-primary' : 'btn-outline-secondary')" @click="filters.filter_read=false; filters.filter_unread=true">Un-read</button>
<button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Action</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" @click="markAll('mark_unread')"><font-awesome-icon icon='book' />Mark Un-read</a></li>
<li><a class="dropdown-item" @click="markAll('mark_read')"><font-awesome-icon icon='book-open' />Mark read</a></li>
</ul>
</div>
</div>
<div class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-6 row-cols-xl-auto mt-1" >
<template v-if="loading">
<div class="col-12 col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12">
<CProgress class="mt-3" >
<CProgressBar color="success" variant="striped" animated :value="100"/>
</CProgress>
<div class="progress mt-3">
<div class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" aria-label="Loading data" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
</div>
</template>
<template v-else>
@@ -29,7 +27,7 @@
</template>
</template>
</div>
</CContainer>
</div>
</template>
<script>
@@ -145,4 +143,4 @@ export default {
.dropdown-item {
cursor: pointer;
}
</style>
</style>

View File

@@ -6,34 +6,27 @@
</section>
</div>
</div>
<CRow class="navButtons pb-2">
<CListGroup :layout="'horizontal'">
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="prevComic">Prev&nbsp;Comic</CListGroupItem>
<paginate
v-model="paginate_page"
:page-count="pages.length"
:click-handler="this.setPage"
:prev-text="'Prev'"
:next-text="'Next'"
:container-class="'pagination'"
>
</paginate>
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="nextComic">Next&nbsp;Comic</CListGroupItem>
</CListGroup>
</CRow>
<div class="row navButtons pb-2">
<comic-paginate
v-model="paginate_page"
:page_count="pages.length"
@setPage="this.setPage"
@prevComic="prevComic"
@nextComic="nextComic"
/>
</div>
</template>
<script>
import Reveal from "reveal.js";
import api from "@/api";
import 'reveal.js-menu/menu.css'
import Paginate from "vuejs-paginate-next";
import * as Hammer from 'hammerjs'
import ComicPaginate from "@/components/ComicPaginate";
export default {
name: "TheComicReader",
components: {Paginate},
components: {ComicPaginate},
data () {
return {
current_page: 0,
@@ -185,7 +178,4 @@ export default {
section {
padding-bottom: 60px;
}
.list-group-item {
/*padding: 0;*/
}
</style>
</style>

View File

@@ -1,46 +1,39 @@
<template>
<CNavbar expand="lg" color-scheme="light" class="bg-light">
<CContainer fluid>
<CNavbarBrand href="#"><img src="/static/img/logo.svg" width="35" class="d-inline-block align-top" alt="CB"> Web Reader</CNavbarBrand>
<CNavbarToggler @click="visible = !visible"/>
<CCollapse class="navbar-collapse" :visible="visible">
<CNavbarNav>
<CNavItem>
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img src="/static/img/logo.svg" width="35" class="d-inline-block align-top" alt="CB"> Web Reader</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<router-link :to="{name: 'browse'}" class="nav-link" >Browse</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'recent'}" class="nav-link" >Recent</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'account'}" class="nav-link" >Account</router-link>
</CNavItem>
<CNavItem>
</li>
<li class="nav-item">
<router-link :to="{name: 'user'}" class="nav-link" v-if="this.$store.getters.is_superuser">Users</router-link>
</CNavItem>
<CNavItem>
<CNavLink @click="logout">Log Out</CNavLink>
</CNavItem>
</CNavbarNav>
</CCollapse>
</CContainer>
</CNavbar>
</li>
<li class="nav-item">
<a class="nav-link" @click="logout">Log Out</a>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script>
import { CNavbar, CNavbarNav, CContainer, CNavbarBrand, CNavbarToggler, CCollapse, CNavItem, CNavLink } from '@coreui/vue'
import store from "@/store";
import router from "@/router";
import 'bootstrap/js/dist/collapse'
export default {
name: "TheNavbar",
components: {
CNavbar,
CNavbarNav,
CContainer,
CNavbarBrand,
CNavbarToggler,
CCollapse,
CNavItem,
CNavLink
},
components: { },
data() {
return {
visible: false
@@ -59,4 +52,4 @@ export default {
.nav-link {
cursor: pointer;
}
</style>
</style>

View File

@@ -1,41 +1,35 @@
<template>
<CContainer ref="pdfContainer">
<CRow class="w-100 pb-5 mb-5" v-if="loaded" >
<pdf :src="pdfdata" :page="page" ref="pdfWindow" :resize="true">
<template v-slot:loading>
loading content here...
</template>
</pdf>
</CRow>
</CContainer>
<CRow class="navButtons pb-2">
<CListGroup :layout="'horizontal'">
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="prevComic">Prev&nbsp;Comic</CListGroupItem>
<paginate
v-model="page"
:page-count="numPages"
:click-handler="this.setPage"
:prev-text="'Prev'"
:next-text="'Next'"
:container-class="'pagination'"
>
</paginate>
<CListGroupItem class="p-1 pt-2 page-link pl-2 pr-2" @click="nextComic">Next&nbsp;Comic</CListGroupItem>
</CListGroup>
</CRow>
<div class="container" ref="pdfContainer">
<div class="row w-100 pb-5 mb-5" v-if="loaded">
<pdf :src="pdfdata" :page="page" ref="pdfWindow" :resize="true">
<template v-slot:loading>
loading content here...
</template>
</pdf>
</div>
</div>
<div class="row navButtons pb-2">
<comic-paginate
v-model="page"
:page_count="numPages"
@setPage="setPage"
@prevComic="prevComic"
@nextComic="nextComic"
/>
</div>
</template>
<script>
import pdfvuer from 'pdfvuer'
import api from "@/api";
import Paginate from "vuejs-paginate-next";
import * as Hammer from 'hammerjs'
import ComicPaginate from "@/components/ComicPaginate";
export default {
name: "ThePdfReader",
components: {
pdf: pdfvuer, Paginate
ComicPaginate,
pdf: pdfvuer
},
data () {
return {
@@ -83,7 +77,7 @@ export default {
this.setReadPage(this.page)
this.next_comic = response.data.next_comic
this.prev_comic = response.data.prev_comic
this.hammertime = new Hammer(this.$refs.pdfContainer.$el, {})
this.hammertime = new Hammer(this.$refs.pdfContainer, {})
this.hammertime.on('swipeleft', (_e, self=this) => {
self.nextPage()
})
@@ -130,7 +124,7 @@ export default {
this.setReadPage(this.page)
},
setReadPage(num){
this.$refs.pdfContainer.$el.scrollIntoView()
this.$refs.pdfContainer.scrollIntoView()
let payload = {
page: num-1
}
@@ -173,4 +167,4 @@ export default {
width: auto;
cursor: pointer;
}
</style>
</style>

View File

@@ -1,65 +1,68 @@
<template>
<CContainer>
<CRow>
<CCol>
<div class="container">
<div class="row">
<div class="col d-flex align-items-center">
<form class="form-inline ">
<label class="my-1 mr-2" for="selectChoices">Show</label>
<label class="my-1 px-1" for="selectChoices">Show</label>
<select class="custom-select my-1 mr-sm-2 " id="selectChoices" v-model="this.page_size" @change="this.setPage(this.page)">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<label class="my-1 mr-2" for="selectChoices">entries</label>
<label class="my-1 px-1" for="selectChoices">entries</label>
</form>
</CCol>
<CCol class="d-flex justify-content-end">
</div>
<div class="col d-flex justify-content-end">
<form class="form-inline">
<label for="searchText" class="my-1 mr-2">Search</label>
<input type="text" id="searchText" class="form-control my-1 mr-sm-2" v-model="search_text" @keyup="this.debounceInput()">
<div class="form-floating">
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" v-model="search_text" @keyup="this.debounceInput()">
<label for="floatingInput">Search</label>
</div>
</form>
</CCol>
</CRow>
<CRow>
</div>
</div>
<div class="row">
<caption>
<h2>Recent Comics - <a :href="'/feed/' + this.feed_id + '/'">Feed</a></h2>
Mark selected issues as:
<select name="func" id="func_selector" @change="this.performFunction()" v-model="func_selected">
<select class="form-select-sm" name="func" id="func_selector" @change="this.performFunction()" v-model="func_selected">
<option value="choose">Choose...</option>
<option value="mark_read">Read</option>
<option value="mark_unread">Un-Read</option>
</select>
</caption>
</CRow>
<CRow>
<CTable striped bordered>
<CTableHead>
<CTableRow>
<CTableHeaderCell scope="col"><input class="form-check-input m-0 position-relative mt-1" type="checkbox" value="" ref="select-all"></CTableHeaderCell>
<CTableHeaderCell scope="col"></CTableHeaderCell>
<CTableHeaderCell scope="col">Comic</CTableHeaderCell>
<CTableHeaderCell scope="col">Date Added</CTableHeaderCell>
<CTableHeaderCell scope="col">status</CTableHeaderCell>
</CTableRow>
</CTableHead>
<CTableBody>
</div>
<div class="row">
<table class="table table-striped table-bordered">
<caption>Recent Comics</caption>
<thead>
<tr>
<th scope="col"><input class="form-check-input m-0 position-relative mt-1" type="checkbox" value="" ref="select-all"></th>
<th scope="col"></th>
<th scope="col">Comic</th>
<th scope="col">Date Added</th>
<th scope="col">status</th>
</tr>
</thead>
<tbody>
<template v-for="item in comics" :key="item.id">
<CTableRow>
<CTableHeaderCell scope="row"><input ref="comic_selector" class="form-check-input m-0 position-relative mt-1" type="checkbox" :value="item.selector"></CTableHeaderCell>
<CTableDataCell class=""><font-awesome-icon icon='book' class="" /></CTableDataCell>
<CTableDataCell><router-link :to="{name: 'read', params: { selector: item.selector }}" class="" >{{ item.file_name }}</router-link></CTableDataCell>
<CTableDataCell>{{ timeago(item.date_added) }}</CTableDataCell>
<CTableDataCell>{{ get_status(item) }}</CTableDataCell>
</CTableRow>
<tr>
<th scope="row"><input ref="comic_selector" class="form-check-input m-0 position-relative mt-1" type="checkbox" :value="item.selector"></th>
<td class=""><font-awesome-icon icon='book' class="" /></td>
<td><router-link :to="{name: 'read', params: { selector: item.selector }}" class="" >{{ item.file_name }}</router-link></td>
<td>{{ timeago(item.date_added) }}</td>
<td>{{ get_status(item) }}</td>
</tr>
</template>
</CTableBody>
</CTable>
</CRow>
<CRow>
<CCol>
</tbody>
</table>
</div>
<div class="row">
<div class="col">
Showing page {{ this.page }} of {{ this.page_count }} pages.
</CCol>
<CCol class="d-flex justify-content-end">
</div>
<div class="col d-flex justify-content-end">
<paginate
v-model="this.page"
:page-count="this.page_count"
@@ -69,9 +72,9 @@
:container-class="'pagination '"
>
</paginate>
</CCol>
</CRow>
</CContainer>
</div>
</div>
</div>
</template>
<script>
@@ -181,4 +184,4 @@ export default {
.pagination {
cursor: pointer;
}
</style>
</style>

View File

@@ -1,35 +1,26 @@
<template>
<CContainer>
<CForm @submit="saveForm">
<CFormInput
type="text"
label="Username"
readonly
v-model="username"
/>
<CFormInput
type="email"
label="Email address"
:placeholder="user.email"
text="Must be 8-20 characters long."
v-model="email"
feedback-invalid="Email address invalid."
/>
<CFormSelect
aria-label="Default select example"
v-model="classification"
:options="[...this.$store.state.classifications]">
</CFormSelect>
<CRow class="mt-2">
<CCol>
<CButton color="primary" type="submit" class="mr-5">Save</CButton>
<confirm-button class="mr-5" label="Reset Password" :action="resetPassword" />
<confirm-button label="Delete User" :action="deleteUser" />
</CCol>
</CRow>
<div class="container">
<form @submit="saveForm">
<label class="form-label">Username</label>
<input class="form-control" readonly="" type="text" v-model="username" />
</CForm>
</CContainer>
<label class="form-label">Email address</label>
<input placeholder="" class="form-control" type="email" v-model="email"/>
<label class="form-label">Classification</label>
<select aria-label="Default select example" class="form-select" v-model="classification">
<option v-for="class_opt in [...this.$store.state.classifications]" :key="class_opt.value" :value="class_opt.value">{{class_opt.label}}</option>
</select>
<div class="row mt-2">
<div class="col">
<button type="submit" class="btn btn-primary me-5">Save</button>
<confirm-button class="me-5" label="Reset Password" :action="resetPassword" />
<confirm-button label="Delete User" :action="deleteUser" />
</div>
</div>
</form>
</div>
</template>
<script>
@@ -111,4 +102,3 @@ export default {
}
}
</script>

View File

@@ -1,28 +1,29 @@
<template>
<CTable striped bordered>
<CTableHead>
<CTableRow>
<CTableHeaderCell scope="col">#</CTableHeaderCell>
<CTableHeaderCell scope="col">Username</CTableHeaderCell>
<CTableHeaderCell scope="col">Email</CTableHeaderCell>
<CTableHeaderCell scope="col">Superuser</CTableHeaderCell>
<CTableHeaderCell scope="col">Classification</CTableHeaderCell>
</CTableRow>
</CTableHead>
<CTableBody>
<table class="table table-striped table-bordered">
<caption>User list</caption>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Username</th>
<th scope="col">Email</th>
<th scope="col">Superuser</th>
<th scope="col">Classification</th>
</tr>
</thead>
<tbody>
<template v-for="item in users" :key="item.id">
<CTableRow>
<CTableHeaderCell scope="row">{{ item.id }}</CTableHeaderCell>
<CTableDataCell class="">
<tr>
<th scope="row">{{ item.id }}</th>
<td class="">
<router-link :to="{'name': 'user', params: { userid: item.id }}">{{ item.username }}</router-link>
</CTableDataCell>
<CTableDataCell>{{ item.email }}</CTableDataCell>
<CTableDataCell>{{ item.is_superuser }}</CTableDataCell>
<CTableDataCell>{{ this.$store.state.classifications.find(i => i.value === item.classification.toString()).label }}</CTableDataCell>
</CTableRow>
</td>
<td>{{ item.email }}</td>
<td>{{ item.is_superuser }}</td>
<td>{{ this.$store.state.classifications.find(i => i.value === item.classification.toString()).label }}</td>
</tr>
</template>
</CTableBody>
</CTable>
</tbody>
</table>
</template>
<script>
@@ -36,4 +37,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,12 +1,13 @@
import * as Vue from 'vue'
import App from './App.vue'
import ToastPlugin from 'vue-toast-notification';
import CoreuiVue from '@coreui/vue';
import '@coreui/coreui/dist/css/coreui.min.css'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'vue-toast-notification/dist/theme-default.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/js/dist/dropdown'
/* import the fontawesome core */
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -14,14 +15,13 @@ import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
/* import specific icons */
import {faBook, faBookOpen, faEdit, faTurnUp} from '@fortawesome/free-solid-svg-icons'
library.add(faBook, faBookOpen, faEdit, faTurnUp)
import {faBook, faBookOpen, faEdit, faTurnUp, faTimes, faCheck} from '@fortawesome/free-solid-svg-icons'
library.add(faBook, faBookOpen, faEdit, faTurnUp, faTimes, faCheck)
import router from './router'
import store from './store'
Vue.createApp(App)
.use(CoreuiVue)
.use(ToastPlugin)
.use(store)
.use(router)

View File

@@ -1,36 +1,25 @@
<template>
<CContainer>
<CRow v-if="!initialSetupRequired">
<CCol lg="4"/>
<CCol lg="4" id="login-col">
<CForm @submit="login">
<CFormInput
type="username"
id="username"
label="Username"
placeholder="username"
text="Please enter your username"
aria-describedby="loginFormControlInputHelpInline"
v-model="username"
/>
<CFormInput
type="password"
id="password"
label="password"
placeholder="password"
text="Please enter your password"
aria-describedby="loginFormControlInputHelpInline"
v-model="password"
@keyup.enter="login"
/>
<CButton color="primary" class="mb-3">Login</CButton>
</CForm>
</CCol>
</CRow>
<CRow>
<div class="container">
<div class="row" v-if="!initialSetupRequired">
<div class="col col-lg-4" />
<div class="col col-lg-4" id="login-col">
<form @submit="login">
<label class="form-label" for="username">Username</label>
<input id="username" placeholder="username" aria-describedby="loginFormControlInputHelpInline" class="form-control" type="text" v-model="username" />
<div class="form-text" id="loginFormControlInputHelpInline">Please enter your username</div>
<label class="form-label" for="password">password</label>
<input id="password" placeholder="password" aria-describedby="loginFormControlInputHelpInline" class="form-control" type="password" v-model="password"/>
<div class="form-text" id="loginFormControlInputHelpInline">Please enter your password</div>
<button class="btn btn-primary mb-3" type="submit">Login</button>
</form>
</div>
</div>
<div class="row">
<initial-setup v-if="initialSetupRequired" />
</CRow>
</CContainer>
</div>
</div>
</template>
<script>
@@ -65,4 +54,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,11 +1,11 @@
<template>
<the-breadcrumbs :manual_crumbs="this.crumbs" />
<CContainer>
<div class="container">
<alert-messages :messages="messages" />
<user-list :users="users" v-if="!userid"/>
<user-edit v-if="user_data" :user="user_data" @add-message="addMessage"/>
<add-user v-if="!userid" @user-added="updateUsers" @add-message="addMessage"/>
</CContainer>
</div>
</template>
<script>
@@ -78,4 +78,4 @@ export default {
<style scoped>
</style>
</style>

View File

@@ -1,4 +1,10 @@
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
module.exports = defineConfig({
transpileDependencies: true
transpileDependencies: true,
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
},
})

View File

@@ -2,7 +2,7 @@ const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const BundleTracker = require('webpack-bundle-tracker');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const webpack = require('webpack')
@@ -12,7 +12,7 @@ module.exports = (env = {}) => {
return {
mode: 'production',
devtool: false,
devtool: 'hidden-source-map',
entry: path.resolve(__dirname, './src/main.js'),
output: {
path: path.resolve(__dirname, './dist/bundles/'),
@@ -56,6 +56,8 @@ module.exports = (env = {}) => {
}),
new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }),
new MiniCssExtractPlugin(),
// new BundleAnalyzerPlugin(),
],
optimization: {
splitChunks: {
@@ -63,4 +65,4 @@ module.exports = (env = {}) => {
},
},
};
}
}