New Frontend in Vue with drf interface (#72)

* frontend rewrite with vie initial commit

* got ComicCard.vue working nice.

* got TheComicList.vue working.

* added router and basic config

* getting jwt stuff working.

* login with jwt now working.

* implemented browse api call

* implemented browse api recievers

* jwt token is now updating automatically.

* removed code for jwt testing.

* enabled browsing

* breadcrumbs working

* adding django webpack loader

* linking up navigation

* fixes for ComicCard.vue stying

* added thumbnail view

* added thumbnail generation and handling.

* detached breadcrumbs

* fix breadcrumbs

* added first stages of reader

* reader view is working.

* reader is now working with keyboard shortcuts

* implemented setting read page.

* implemented pagination on comic reader.

* hide elements that shouldn't be shown.

* fixed the ComicCard.vue to use as little space as possible.

* fix navbar browse link

* added RecentView.vue and added manual option for breadcrumbs

* updated rest api to handle recent comics.

* most functionality of recent comics done

* modified comicstatus relation to use uuid relation and implemented mark read and unread for batches.

* added functions to TheRecentTable.vue

* added feed link to TheRecentTable.vue

* fixes for comicstatus updates.

* added constraints to comicstatus

* update to python packages.

* some changes for django 4, also removed django-recaptcha2 as it doesnt support django 4.

* some fixes and updates to ComicCard.vue

* cleaned up generate_directory. fixed bug where pages not visible on first call.

* cleaned up generate_directory. fixed bug where pages not visible on first call.

* cleaned up generate_directory. fixed bug where pages not visible on first call.

* cleaned up generate_directory.

* added silk stubs

* fix for re-requesting thumbnail after getting it already.

* fix for removing stale comics.
adding leeway to access token.

* mark read and unread

* added filtering to comic list.

* stored filtering state.

* stored filtering state.

* added next functionality to login.

* cleanup LoginView.vue

* bump font-awesome.

* working on AccountView.vue

* fixed form submission on LoginView.vue

* account page should now be working.

* hide users option if not superuser.

* added pdf support

* make pdf resize.

* added touch controls to pdf reader

* added touch controls to comic reader

* beginnings of routing between issues.

* fixes for navigating pages.

* fixes for navigating pages.

* fixes for navigating pages.

* renamed HomeView.vue to BrowseView.vue

* stubs for users page added. api ready

* users page further functinality

* fix for notification

* fix for notification

* moved messages to parent.

* form to add users

* added error handling

* removed console logging

* classification in base directory should be lowest

* renamed usermisc to classification to be more consistent with what it does.

* renamed usermisc to classification to be more consistent with what it does.

* added functionality to change classification of directories.

* merged rss_id api into account api.

* merged breadcrumbs api into browse api.

* clears some warnings from console.

* fixed read/unread rendering.

* added build script and starting lint

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing lint errors

* fixing navigation bugs

* cleanup and fixes

* fixed generated tooltips over calling.

* fixed classifications.

* initial setup now working

* fix navbar branding

* fix favicon

* added beta build script.

* fixes to get ready for production

* optimisations for loading new comics.

* added loading indicators to TheComicList.vue

* lint fixes

* made two methods static. may use them elsewhere.

* fix for scanning files.

* version updates.

* fixes for production

* fixes for production

Co-authored-by: Peter Dwyer <peter.dwyer@clanwilliamhealth.com>
This commit is contained in:
2022-08-25 15:42:20 +01:00
committed by GitHub
parent 3be7d9cb5c
commit c5633bf54a
86 changed files with 25205 additions and 644 deletions

View File

@@ -0,0 +1,5 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

View File

@@ -0,0 +1,24 @@
<template>
<the-breadcrumbs :manual_crumbs="this.crumbs" />
<the-account-form />
</template>
<script>
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
import TheAccountForm from "@/components/TheAccountForm";
export default {
name: "AccountView",
components: {TheAccountForm, TheBreadcrumbs},
data () {
return {
crumbs: [
{id: 0, selector: '', name: 'Home'},
{id: 1, selector: '', name: 'Account'}
]
}},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,20 @@
<template>
<the-breadcrumbs :selector="selector"/>
<the-comic-list :selector="selector" :key="selector" />
</template>
<script>
import TheComicList from "@/components/TheComicList";
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
export default {
name: 'BrowseView',
components: {
TheBreadcrumbs,
TheComicList,
},
props: {
selector: String
}
}
</script>

View File

@@ -0,0 +1,68 @@
<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>
<initial-setup v-if="initialSetupRequired" />
</CRow>
</CContainer>
</template>
<script>
import InitialSetup from "@/components/InitialSetup";
import axios from "axios";
export default {
name: "LoginView",
components: {InitialSetup},
data() {
return {
username: '',
password: '',
password_alert: false,
initialSetupRequired: false
}
},
methods: {
login () {
this.$store.dispatch("obtainToken", {username: this.username, password: this.password})
}
},
mounted() {
axios.get('/api/initial_setup/required/').then(response => {
if (response.data.required){
this.initialSetupRequired = true
}
})
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,52 @@
<template>
<the-breadcrumbs :selector="selector" />
<the-comic-reader :selector="selector" v-if="comic_loaded" :key="selector" />
<the-pdf-reader :selector="selector" v-if="pdf_loaded" :key="selector" />
</template>
<script>
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
import TheComicReader from "@/components/TheComicReader";
import api from "@/api";
import ThePdfReader from "@/components/ThePdfReader";
export default {
name: "ReadView",
components: {ThePdfReader, TheComicReader, TheBreadcrumbs},
props: {
selector: String
},
data () {
return {
comic_data: {},
comic_loaded: false,
pdf_loaded: false
}
},
methods: {
updateType() {
let comic_data_url = '/api/read/' + this.selector + '/type/'
api.get(comic_data_url)
.then(response => {
if (response.data.type === 'pdf'){
this.pdf_loaded = true
this.comic_loaded = false
} else {
this.comic_loaded = true
this.pdf_loaded = false
}
})
.catch((error) => {console.log(error)})
}
},
mounted () {
this.updateType()
},
beforeUpdate() {
this.updateType()
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,24 @@
<template>
<the-breadcrumbs :manual_crumbs="this.crumbs" />
<the-recent-table />
</template>
<script>
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
import TheRecentTable from "@/components/TheRecentTable";
export default {
name: "RecentView",
components: {TheRecentTable, TheBreadcrumbs},
data () {
return {
crumbs: [
{id: 0, selector: '', name: 'Home'},
{id: 1, selector: '', name: 'Recent'}
]
}},
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,81 @@
<template>
<the-breadcrumbs :manual_crumbs="this.crumbs" />
<CContainer>
<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>
</template>
<script>
import TheBreadcrumbs from "@/components/TheBreadcrumbs";
import UserList from "@/components/UserList";
import api from "@/api";
import UserEdit from "@/components/UserEdit";
import alertMessages from "@/components/AlertMessages";
import AddUser from "@/components/AddUser";
import router from "@/router";
const default_crumbs = [
{id: 0, selector: '', name: 'Home'},
{id: 1, route: {'name': 'user'}, name: 'Users'}
]
export default {
name: "UserView",
components: {AddUser, alertMessages, UserEdit, UserList, TheBreadcrumbs},
props: {
userid: String
},
data () {
return {
crumbs: [...default_crumbs],
users: [],
viewUserList: true,
user_data: null,
messages: []
}},
methods: {
updateUsers() {
api.get('/api/users/').then(response => {
this.users = response.data
})
},
getUser() {
api.get('/api/users/' + this.userid + '/').then(response => {
this.user_data = response.data
this.crumbs.push({id: 1, selector: '', name: response.data.username})
}).catch(() => {
this.messages.push({
color: 'danger',
text: 'User with id "' + this.userid + '" does not exist.'
})
router.push({name: 'user'})
})
},
addMessage(message){
this.messages.push(message)
}
},
mounted() {
this.updateUsers()
if (this.userid){
this.getUser()
}
},
beforeUpdate() {
this.updateUsers()
this.crumbs = [...default_crumbs]
if (this.userid){
this.getUser()
} else {
this.user_data = null
this.crumbs = default_crumbs
}
}
}
</script>
<style scoped>
</style>