Added counts to each category
Counts update on certain events and show or hide various elements Fixed various little ui element issues fixes #6
This commit is contained in:
parent
c903bcbcd1
commit
771b739c37
@ -13,6 +13,7 @@
|
||||
<script>
|
||||
|
||||
// import io from 'socket.io-client'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -50,7 +51,6 @@ export default {
|
||||
|
||||
},
|
||||
mounted: function(){
|
||||
|
||||
},
|
||||
computed: {
|
||||
loggedIn () {
|
||||
|
@ -28,7 +28,7 @@
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
/*scrollbar-width: none;*/
|
||||
}
|
||||
|
||||
div.ui.basic.segment.no-fluf-segment {
|
||||
|
@ -192,6 +192,7 @@
|
||||
this.unfolded = false
|
||||
setTimeout( () => {
|
||||
this.visible = false
|
||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
|
@ -68,6 +68,7 @@
|
||||
const imageCode = `<img alt="image" src="/api/static/thumb_${location}">`
|
||||
|
||||
this.$bus.$emit('new_file_upload', {noteId: this.noteId, imageCode})
|
||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||
}
|
||||
})
|
||||
.catch(results => {
|
||||
|
@ -154,6 +154,7 @@
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<router-link exact-active-class="active" class="menu-item menu-button" to="/notes" v-on:click.native="emitReloadEvent()">
|
||||
<i class="file outline icon"></i>Notes
|
||||
<!-- <span v-if="$store.getters.totals">{{ $store.getters.totals['totalNotes'] }}</span> -->
|
||||
</router-link>
|
||||
<div>
|
||||
<!-- <div class="menu-item sub">Show Only <i class="caret down icon"></i></div> -->
|
||||
@ -163,21 +164,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<div v-on:click="updateFastFilters(3)" class="menu-item menu-button">
|
||||
<i class="mail outline icon"></i>Inbox
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<div v-on:click="updateFastFilters(2)" class="menu-item menu-button">
|
||||
<i class="hdd outline icon"></i>Archived
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-section" v-if="loggedIn">
|
||||
<div class="menu-section" v-if="loggedIn && $store.getters.totals && $store.getters.totals['totalFiles']">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/attachments">
|
||||
<i class="folder open outline icon"></i>Files
|
||||
<!-- <span>{{ $store.getters.totals['totalFiles'] }}</span> -->
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
@ -242,6 +232,8 @@
|
||||
this.mobile = this.$store.getters.getIsUserOnMobile
|
||||
this.collapsed = this.$store.getters.getIsUserOnMobile
|
||||
|
||||
// {{ totals['totalNotes'] }}
|
||||
|
||||
if(this.mobile){
|
||||
this.menuOpen = false
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
axios.post('/api/note/delete', {'noteId':this.noteId}).then(response => {
|
||||
if(response.data == true){
|
||||
this.$bus.$emit('note_deleted', this.noteId)
|
||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -202,6 +202,7 @@
|
||||
loading: true,
|
||||
loadingMessage: 'Loading Note',
|
||||
currentNoteId: 0,
|
||||
modified: false,
|
||||
noteText: '',
|
||||
rawTextId: 0,
|
||||
shareUsername: null,
|
||||
@ -873,21 +874,16 @@
|
||||
'archived':this.archived,
|
||||
}
|
||||
|
||||
let vm = this
|
||||
//Debounce save to prevent spamming
|
||||
// clearTimeout(this.saveDebounce)
|
||||
// this.saveDebounce = setTimeout(() => {
|
||||
//Only notify user if saving - may help with debugging in the future
|
||||
vm.statusText = 'Saving'
|
||||
axios.post('/api/note/update', postData).then( response => {
|
||||
vm.statusText = 'Saved'
|
||||
vm.updated = Math.round((+new Date)/1000)
|
||||
this.statusText = 'Saving'
|
||||
axios.post('/api/note/update', postData).then( response => {
|
||||
this.statusText = 'Saved'
|
||||
this.updated = Math.round((+new Date)/1000)
|
||||
this.modified = true
|
||||
|
||||
//Update last saved note hash
|
||||
vm.lastNoteHash = vm.hashString( currentNoteText )
|
||||
return resolve(true)
|
||||
})
|
||||
// }, 300)
|
||||
//Update last saved note hash
|
||||
this.lastNoteHash = this.hashString( currentNoteText )
|
||||
return resolve(true)
|
||||
})
|
||||
})
|
||||
},
|
||||
checkForUpdatedNote(){
|
||||
@ -949,7 +945,9 @@
|
||||
this.sizeDown = true
|
||||
//This timeout allows animation to play before closing
|
||||
setTimeout(() => {
|
||||
this.$bus.$emit('close_active_note', {position: this.position, noteId: this.noteid})
|
||||
this.$bus.$emit('close_active_note', {
|
||||
position: this.position, noteId: this.noteid, modified: this.modified
|
||||
})
|
||||
return
|
||||
}, 300)
|
||||
})
|
||||
|
@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div class="ui form">
|
||||
<input v-model="searchTerm" @keyup="searchKeyUp" @:keyup.enter="search" placeholder="Search Notes and Files" />
|
||||
<div class="ui left icon fluid input">
|
||||
<input v-model="searchTerm" @keyup="searchKeyUp" @:keyup.enter="search" placeholder="Search Notes and Files" />
|
||||
<i class="search icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -128,7 +128,6 @@
|
||||
|
||||
if(this.styleObject && this.styleObject.noteBackground){
|
||||
this.bgColor = this.styleObject.noteBackground
|
||||
console.log(this.bgColor)
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,21 +3,39 @@
|
||||
|
||||
<div class="ui grid" :class="{ 'mush-it-up':showOneColumn() }" ref="content">
|
||||
|
||||
<div v-if="!$store.getters.getIsUserOnMobile"
|
||||
:class="{ 'sixteen wide column':showOneColumn(), 'twelve wide column':!showOneColumn() }">
|
||||
<div v-if="!$store.getters.getIsUserOnMobile" class="sixteen wide column">
|
||||
<!-- :class="{ 'sixteen wide column':showOneColumn(), 'sixteen wide column':!showOneColumn() }" -->
|
||||
|
||||
<div class="ui grid">
|
||||
|
||||
<div class="eight wide column">
|
||||
<search-input></search-input>
|
||||
</div>
|
||||
|
||||
<div class="eight wide column">
|
||||
|
||||
<div class="ui basic button" v-on:click="updateFastFilters(3)" v-if="$store.getters.totals && $store.getters.totals['sharedToNotes'] > 0" style="position: relative;">
|
||||
<i class="green mail icon"></i>Inbox
|
||||
<span class="floating ui green label" v-if="$store.getters.totals['unreadNotes'] > 0">
|
||||
{{ $store.getters.totals['unreadNotes'] }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="ui basic button" v-on:click="updateFastFilters(2)" v-if="$store.getters.totals && $store.getters.totals['archivedNotes'] > 0">
|
||||
<i class="green archive icon"></i>Archived
|
||||
<!-- <span>{{ $store.getters.totals['archivedNotes'] }}</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="eight wide column" v-if="showClear">
|
||||
<!-- <fast-filters /> -->
|
||||
<span class="ui fluid green button"
|
||||
v-if="showClear"
|
||||
|
||||
@click="reset">
|
||||
<i class="arrow circle left icon"></i>Back to All Notes
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -64,7 +82,7 @@
|
||||
<!-- pinned notes -->
|
||||
<div v-if="containsPinnednotes > 0" class="note-card-section">
|
||||
<!-- ({{containsPinnednotes}}) -->
|
||||
<h4><i class="green pin icon"></i>Pinned <span v-if="!working"></span></h4>
|
||||
<h4><i class="green pin icon"></i>Pinned</h4>
|
||||
<div class="note-card-display-area">
|
||||
<note-title-display-card
|
||||
v-for="note in notes"
|
||||
@ -80,7 +98,7 @@
|
||||
<!-- normal notes -->
|
||||
<div v-if="containsNormalNotes > 0" class="note-card-section">
|
||||
<!-- ({{containsNormalNotes}}) -->
|
||||
<h4><i class="green file icon"></i>Notes <span v-if="!working"></span></h4>
|
||||
<h4><i class="green file icon"></i>Notes</h4>
|
||||
<div class="note-card-display-area">
|
||||
<note-title-display-card
|
||||
v-for="note in notes"
|
||||
@ -194,9 +212,16 @@
|
||||
|
||||
this.$parent.loginGateway()
|
||||
|
||||
this.$bus.$on('close_active_note', ({position, noteId}) => {
|
||||
//Update totals for app
|
||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||
|
||||
this.$bus.$on('close_active_note', ({position, noteId, modified}) => {
|
||||
this.closeNote(position)
|
||||
this.updateSingleNote(noteId)
|
||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||
if(modified){
|
||||
this.updateSingleNote(noteId)
|
||||
}
|
||||
|
||||
})
|
||||
this.$bus.$on('note_deleted', (noteId) => {
|
||||
//Remove deleted note from set, its deleted
|
||||
@ -265,6 +290,7 @@
|
||||
// this.$bus.$off()
|
||||
},
|
||||
mounted() {
|
||||
|
||||
//Loads initial batch and tags
|
||||
this.reset()
|
||||
},
|
||||
@ -634,6 +660,31 @@
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
},
|
||||
updateFastFilters(index){
|
||||
|
||||
//clear out tags
|
||||
this.searchTags = []
|
||||
|
||||
//A little hacky, brings user to notes page then filters on click
|
||||
if(this.$route.name != 'NotesPage'){
|
||||
this.$router.push('/notes')
|
||||
setTimeout( () => {
|
||||
this.updateFastFilters(index)
|
||||
}, 500 )
|
||||
}
|
||||
|
||||
const options = [
|
||||
'withLinks', // 'Only Show Notes with Links'
|
||||
'withTags', // 'Only Show Notes with Tags'
|
||||
'onlyArchived', //'Only Show Archived Notes'
|
||||
'onlyShowSharedNotes', //Only show shared notes
|
||||
]
|
||||
|
||||
let filter = {}
|
||||
filter[options[index]] = 1
|
||||
|
||||
this.$bus.$emit('update_fast_filters', filter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ export default new Vuex.Store({
|
||||
isUserOnMobile: false,
|
||||
isNoteSettingsOpen: false, //Little note settings pane
|
||||
socket: null,
|
||||
userTotals: null,
|
||||
},
|
||||
mutations: {
|
||||
setLoginToken(state, userData){
|
||||
@ -88,6 +89,14 @@ export default new Vuex.Store({
|
||||
//Put socket id in axios headers
|
||||
axios.defaults.headers.common['socketId'] = socket
|
||||
state.socket = socket
|
||||
},
|
||||
setUserTotals(state, totalsObject){
|
||||
//Save all the totals for the user
|
||||
state.userTotals = totalsObject
|
||||
|
||||
// Object.keys(totalsObject).forEach( key => {
|
||||
// console.log(key + ' -- ' + totalsObject[key])
|
||||
// })
|
||||
}
|
||||
|
||||
},
|
||||
@ -114,5 +123,16 @@ export default new Vuex.Store({
|
||||
getSocket: state => {
|
||||
return state.socket
|
||||
},
|
||||
totals: state => {
|
||||
return state.userTotals
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
fetchAndUpdateUserTotals ({ commit }) {
|
||||
axios.post('/api/user/totals')
|
||||
.then( ({data}) => {
|
||||
commit('setUserTotals', data)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@ -334,6 +334,10 @@ Note.get = (userId, noteId) => {
|
||||
WHERE note.user_id = ? AND note.id = ? LIMIT 1`, [userId,noteId])
|
||||
.then((rows, fields) => {
|
||||
|
||||
const created = Math.round((+new Date)/1000)
|
||||
|
||||
db.promise().query(`UPDATE note SET opened = ? WHERE (id = ?)`, [created, noteId])
|
||||
|
||||
//Return note data
|
||||
resolve(rows[0][0])
|
||||
|
||||
|
@ -113,3 +113,56 @@ User.create = (username, password) => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
//Counts notes, pinned notes, archived notes, shared notes, unread notes, total files and types
|
||||
User.getCounts = (userId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let countTotals = {}
|
||||
|
||||
db.promise().query(
|
||||
`SELECT
|
||||
SUM(pinned = 1 && archived = 0 && share_user_id IS NULL) AS pinnedNotes,
|
||||
SUM(pinned = 0 && archived = 1 && share_user_id IS NULL) AS archivedNotes,
|
||||
SUM(share_user_id IS NULL) AS totalNotes,
|
||||
SUM(share_user_id != ?) AS sharedToNotes,
|
||||
SUM( (share_user_id != ? && opened IS null) || (share_user_id != ? && updated > opened) ) AS unreadNotes
|
||||
FROM note
|
||||
WHERE user_id = ?`, [userId, userId, userId, userId])
|
||||
.then( (rows, fields) => {
|
||||
|
||||
Object.assign(countTotals, rows[0][0]) //combine results
|
||||
|
||||
return db.promise().query(
|
||||
`SELECT count(id) AS sharedFromNotes
|
||||
FROM note WHERE share_user_id = ?`, [userId]
|
||||
)
|
||||
})
|
||||
.then( (rows, fields) => {
|
||||
|
||||
Object.assign(countTotals, rows[0][0]) //combine results
|
||||
|
||||
return db.promise().query(
|
||||
`SELECT
|
||||
SUM(attachment_type = 1) as linkFiles,
|
||||
SUM(attachment_type != 1) as otherFiles,
|
||||
COUNT(id) as totalFiles
|
||||
FROM attachment WHERE visible = 1
|
||||
AND user_id = ?
|
||||
`, [userId]
|
||||
)
|
||||
}).then( (rows, fields) => {
|
||||
|
||||
Object.assign(countTotals, rows[0][0]) //combine results
|
||||
|
||||
//Convert everything to an int or 0
|
||||
Object.keys(countTotals).forEach( key => {
|
||||
const count = parseInt(countTotals[key])
|
||||
countTotals[key] = count ? count : 0
|
||||
})
|
||||
|
||||
resolve(countTotals)
|
||||
})
|
||||
|
||||
})
|
||||
}
|
@ -46,4 +46,11 @@ router.post('/login', function (req, res) {
|
||||
})
|
||||
})
|
||||
|
||||
// fetch counts of users notes
|
||||
router.post('/totals', function (req, res) {
|
||||
User.getCounts(req.headers.userId)
|
||||
.then( countsObject => res.send( countsObject ))
|
||||
})
|
||||
|
||||
|
||||
module.exports = router
|
Loading…
Reference in New Issue
Block a user