* Updated color picker interface
* Updated note status bar * Added fast filters * Added pinned and archived notes options * Added loading indicators to notes and loading of notes * updated tag edit area * Updated how search results are displayed * Fixed bug with opening and closing two notes one after another * Added mobile detection to global store * Added a lot of style tweaks and UX tweaks
This commit is contained in:
96
client/src/components/FastFilters.vue
Normal file
96
client/src/components/FastFilters.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<span v-on:mouseover="open = true" v-on:mouseleave="open = false" class="relative clickable filter-header" :class="{'filter-active':open}">
|
||||
{{displayString()}} <i class="grey caret down icon"></i>
|
||||
<span class="filter-menu" v-if="open">
|
||||
<span v-for="(filter,label) in filterOptions" class="filter-option" v-on:click="updateFilter(filter, label)">{{label}}</span>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FastFilters',
|
||||
data () {
|
||||
return {
|
||||
click: 0,
|
||||
open: false,
|
||||
filter: {},
|
||||
orderString: 'Order by Last Edited',
|
||||
filterOptions:{
|
||||
'Order by Last Edited' :'lastEdited',
|
||||
'Order by Last Opened' :'lastOpened',
|
||||
'Order by Last Created' :'lastCreated',
|
||||
'Only Show Notes with Links' :'withLinks',
|
||||
'Only Show Notes with Tags' :'withTags',
|
||||
'Only Show Archived Notes' :'onlyArchived',
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeMount(){
|
||||
this.$bus.$on('reset_fast_filters', () => {
|
||||
this.orderString = 'Order by Last Edited'
|
||||
})
|
||||
},
|
||||
methods:{
|
||||
confirmDelete(){
|
||||
this.click++
|
||||
},
|
||||
displayString(){
|
||||
return this.orderString.replace('Order by','').replace('Only Show','')
|
||||
},
|
||||
updateFilter(option, label){
|
||||
|
||||
this.orderString = label
|
||||
this.open = false
|
||||
|
||||
let filter = {}
|
||||
filter[option] = 1
|
||||
|
||||
this.$bus.$emit('update_fast_filters', filter)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style type="text/css" scoped>
|
||||
|
||||
.filter-header {
|
||||
width: 270px;
|
||||
padding: 0 0 0 10px;
|
||||
border: 1px solid rgba(0,0,0,0);
|
||||
border-bottom: none;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
.filter-menu {
|
||||
|
||||
color: var(--text_color);
|
||||
background-color: var(--background_color);
|
||||
border-color: var(--border_color);
|
||||
|
||||
border: 1px solid;
|
||||
border-top: none;
|
||||
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
width: 270px;
|
||||
left: -1px;
|
||||
z-index: 10;
|
||||
padding-top: 10px;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
.filter-active {
|
||||
border: 1px solid;
|
||||
border-bottom: none;
|
||||
border-color: var(--border_color);
|
||||
}
|
||||
.filter-option {
|
||||
font-size: 17px;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
padding: 0 0 5px 10px;
|
||||
}
|
||||
</style>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<span>
|
||||
<span class="clickable" @click="confirmDelete()" v-if="click == 0">
|
||||
<span class="clickable" @click="confirmDelete()" v-if="click == 0" data-tooltip="Delete">
|
||||
<i class="grey trash alternate icon"></i>
|
||||
</span>
|
||||
<span class="clickable" @click="actuallyDelete()" @mouseleave="reset" v-if="click == 1" data-tooltip="Click again to delete." data-position="left center">
|
||||
|
@@ -5,6 +5,52 @@
|
||||
:class="[{'size-down':(sizeDown == true)}, 'position-'+position ]"
|
||||
:style="{'background-color':color, 'color':fontColor}"
|
||||
>
|
||||
|
||||
<div v-if="loading" class="loading-note">
|
||||
<div class="ui active dimmer">
|
||||
<div class="ui text loader">{{loadingMessage}}...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note-top-menu">
|
||||
<div @click="close" class="ui button"><i class="green close icon"></i>Close (ESC)</div>
|
||||
|
||||
<div @click="onToggleFancyInput" class="ui button">
|
||||
Fancy ({{fancyInput?'On':'Off'}})
|
||||
</div>
|
||||
|
||||
<div @click="onTogglePinned" class="ui button">
|
||||
<i class="pin icon" :class="{green:(pinned == 1)}"></i> {{(pinned == 1)?'pinned':'not pinned'}}
|
||||
</div>
|
||||
<div @click="onToggleArchived" class="ui button">
|
||||
<i class="archive icon" :class="{green:(archived == 1)}"></i> {{(archived == 1)?'archived':'not archived'}}
|
||||
</div>
|
||||
|
||||
<span class="relative" v-on:mouseover="showColorPicker = true" v-on:mouseleave="showColorPicker = false">
|
||||
<span class="ui icon button">
|
||||
<i class="paint brush icon"></i>
|
||||
</span>
|
||||
|
||||
<span v-if="showColorPicker" class="color-picker">
|
||||
<button @click="onChangeColor" class="ui icon white button"></button>
|
||||
<button @click="onChangeColor" class="ui icon red button"></button>
|
||||
<button @click="onChangeColor" class="ui icon orange button"></button>
|
||||
<button @click="onChangeColor" class="ui icon yellow button"></button>
|
||||
<button @click="onChangeColor" class="ui icon olive button"></button>
|
||||
<button @click="onChangeColor" class="ui icon green button"></button>
|
||||
<button @click="onChangeColor" class="ui icon teal button"></button>
|
||||
<button @click="onChangeColor" class="ui icon blue button"></button>
|
||||
<button @click="onChangeColor" class="ui icon violet button"></button>
|
||||
<button @click="onChangeColor" class="ui icon purple button"></button>
|
||||
<button @click="onChangeColor" class="ui icon pink button"></button>
|
||||
<button @click="onChangeColor" class="ui icon brown button"></button>
|
||||
<button @click="onChangeColor" class="ui icon grey button"></button>
|
||||
<button @click="onChangeColor" class="ui icon black button"></button>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="note-status-indicator">{{statusText}}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="fancyInput == 1" class="textarea-height no-flow">
|
||||
<ckeditor ref="main-edit"
|
||||
@@ -19,35 +65,6 @@
|
||||
v-on:keyup="onKeyup"
|
||||
/>
|
||||
|
||||
<div class="ui buttons">
|
||||
<div @click="close" class="ui button">Close + Save (ESC)</div>
|
||||
<div class="ui button">Delete</div>
|
||||
|
||||
<div @click="onToggleFancyInput" class="ui button">
|
||||
Fancy ({{fancyInput?'On':'Off'}})
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui buttons">
|
||||
<button @click="onChangeColor" class="ui icon white button"></button>
|
||||
<button @click="onChangeColor" class="ui icon red button"></button>
|
||||
<button @click="onChangeColor" class="ui icon orange button"></button>
|
||||
<button @click="onChangeColor" class="ui icon yellow button"></button>
|
||||
<button @click="onChangeColor" class="ui icon olive button"></button>
|
||||
<button @click="onChangeColor" class="ui icon green button"></button>
|
||||
<button @click="onChangeColor" class="ui icon teal button"></button>
|
||||
<button @click="onChangeColor" class="ui icon blue button"></button>
|
||||
<button @click="onChangeColor" class="ui icon violet button"></button>
|
||||
<button @click="onChangeColor" class="ui icon purple button"></button>
|
||||
<button @click="onChangeColor" class="ui icon pink button"></button>
|
||||
<button @click="onChangeColor" class="ui icon brown button"></button>
|
||||
<button @click="onChangeColor" class="ui icon grey button"></button>
|
||||
<button @click="onChangeColor" class="ui icon black button"></button>
|
||||
</div>
|
||||
<div class="ui right floated green button">{{statusText}}</div>
|
||||
<!-- <p>
|
||||
Last Updated: {{$helpers.timeAgo(updated)}}
|
||||
</p> -->
|
||||
|
||||
<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
|
||||
|
||||
</div>
|
||||
@@ -57,6 +74,13 @@
|
||||
|
||||
import axios from 'axios'
|
||||
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document';
|
||||
|
||||
//Start working on some plugin, tag plugin, link to other note, interactive checkbox
|
||||
class InsertImage extends Plugin {
|
||||
init() {
|
||||
console.log( 'InsertImage was initialized' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
@@ -67,6 +91,8 @@
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
loading: true,
|
||||
loadingMessage: 'Loading Note',
|
||||
currentNoteId: 0,
|
||||
noteText: '',
|
||||
statusText: 'Saved',
|
||||
@@ -77,9 +103,12 @@
|
||||
editDebounce: null,
|
||||
keyPressesCounter: 0,
|
||||
fancyInput: 0, //Default to basic text edit. Upgrade if set to 1
|
||||
color: '#FFF',
|
||||
pinned: 0,
|
||||
archived: 0,
|
||||
color: '#fff',
|
||||
fontColor: '#000',
|
||||
sizeDown: false,
|
||||
showColorPicker: false,
|
||||
|
||||
editor: DecoupledEditor,
|
||||
editorConfig: {
|
||||
@@ -116,7 +145,6 @@
|
||||
},
|
||||
methods: {
|
||||
onToggleFancyInput(){
|
||||
|
||||
if(this.fancyInput == 0){
|
||||
this.fancyInput = 1
|
||||
} else {
|
||||
@@ -125,12 +153,31 @@
|
||||
//Update last note hash, this will tell note to save next update
|
||||
this.lastNoteHash = 0
|
||||
},
|
||||
onTogglePinned(){
|
||||
if(this.pinned == 0){
|
||||
this.pinned = 1
|
||||
} else {
|
||||
this.pinned = 0;
|
||||
}
|
||||
//Update last note hash, this will tell note to save next update
|
||||
this.lastNoteHash = 0
|
||||
},
|
||||
onToggleArchived(){
|
||||
if(this.archived == 0){
|
||||
this.archived = 1
|
||||
} else {
|
||||
this.archived = 0;
|
||||
}
|
||||
//Update last note hash, this will tell note to save next update
|
||||
this.lastNoteHash = 0
|
||||
},
|
||||
onChangeColor(event){
|
||||
//Grab the color of the button clicked
|
||||
const style = getComputedStyle(event.target)
|
||||
this.color = style['background-color']
|
||||
this.fontColor = '#FFF'
|
||||
|
||||
//If background is white, default to colors in CSS
|
||||
if(this.color == "rgb(255, 255, 255)" || this.color == '#FFF'){
|
||||
this.color = null
|
||||
this.fontColor = null
|
||||
@@ -140,19 +187,33 @@
|
||||
this.save()
|
||||
},
|
||||
loadNote(noteId){
|
||||
|
||||
let vm = this
|
||||
|
||||
let doing = ['Loading','Loading','Getting','Fetching','Grabbing','Sequencing','Organizing','Untangling','Processing','Refining','Extracting','Fusing','Pruning','Expanding','Enlarging','Transfiguring','Quantizing','Ingratiating']
|
||||
let thing = ['Note','Note','Note','Note','Data','Text','Document','Algorithm','Buffer','Client','Download','File','Frame','Graphics','Hardware','HTML','Interface','Logic','Mainframe','Memory','Media','Nodes','Network','Chaos']
|
||||
let p1 = doing[Math.floor(Math.random() * doing.length)]
|
||||
let p2 = thing[Math.floor(Math.random() * thing.length)]
|
||||
vm.loadingMessage = p1 + ' ' + p2
|
||||
|
||||
|
||||
//Component is activated with NoteId in place, lookup text with associated ID
|
||||
if(this.$store.getters.getLoggedIn){
|
||||
axios.post('/api/note/get', {'noteId': noteId})
|
||||
.then(response => {
|
||||
|
||||
vm.loading = false
|
||||
|
||||
//Set up local data
|
||||
vm.currentNoteId = noteId
|
||||
vm.noteText = response.data.text
|
||||
vm.updated = response.data.updated
|
||||
vm.lastNoteHash = vm.hashString(response.data.text)
|
||||
console.log(vm.lastNoteHash)
|
||||
vm.color = response.data.color
|
||||
if(response.data.pinned != null){
|
||||
vm.pinned = response.data.pinned
|
||||
}
|
||||
vm.archived = response.data.archived
|
||||
|
||||
this.fontColor = '#FFF'
|
||||
if(this.color == "rgb(255, 255, 255)" || this.color == '#FFF' || this.color == null){
|
||||
@@ -166,6 +227,7 @@
|
||||
|
||||
//Put focus on note, at the end of the note text
|
||||
vm.$nextTick(() => {
|
||||
|
||||
// vm.$refs['custom-input'].focus()
|
||||
})
|
||||
|
||||
@@ -230,7 +292,6 @@
|
||||
|
||||
//Don't save note if its hash doesn't change
|
||||
if( this.lastNoteHash == this.hashString(this.noteText) ){
|
||||
console.log('Note was not modified')
|
||||
resolve(false)
|
||||
return
|
||||
}
|
||||
@@ -239,7 +300,9 @@
|
||||
'noteId':this.currentNoteId,
|
||||
'text': this.noteText,
|
||||
'fancyInput': this.fancyInput,
|
||||
'color': this.color
|
||||
'color': this.color,
|
||||
'pinned': this.pinned,
|
||||
'archived':this.archived,
|
||||
}
|
||||
|
||||
let vm = this
|
||||
@@ -294,7 +357,6 @@
|
||||
</script>
|
||||
|
||||
<style type="text/css" scoped>
|
||||
|
||||
|
||||
.no-flow {
|
||||
overflow: hidden;
|
||||
@@ -310,6 +372,10 @@
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.note-top-menu {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* container styles change based on mobile and number of open screens */
|
||||
.master-note-edit {
|
||||
@@ -319,11 +385,19 @@
|
||||
/*color: var(--text_color);*/
|
||||
height: 100vh;
|
||||
box-shadow: 0px 0px 5px 2px rgba(140,140,140,1);
|
||||
z-index: 1001;
|
||||
}
|
||||
.loading-note {
|
||||
position: absolute;
|
||||
top: 38px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 50px;
|
||||
}
|
||||
/* One note open, in the middle of the screen */
|
||||
.master-note-edit.position-0 {
|
||||
left: 30%;
|
||||
right: 1%;
|
||||
right: 0;
|
||||
}
|
||||
@media only screen and (max-width: 740px) {
|
||||
.master-note-edit.position-0 {
|
||||
|
@@ -1,22 +1,57 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="ui icon large label" v-for="tag in tags" :class="{ 'green':(newTagInput == tag.text) }">
|
||||
{{ucWords(tag.text)}} <i class="delete icon" v-on:click="removeTag(tag.id)"></i>
|
||||
<div v-on:mouseover="fullTagEdit = true">
|
||||
|
||||
<!-- simple string view -->
|
||||
<div v-if="!fullTagEdit" class="ui basic segment">
|
||||
<div class="simple-tag-display">
|
||||
|
||||
<!-- Show Loading -->
|
||||
<span v-if="!loaded">Loading Tags...</span>
|
||||
|
||||
<!-- Default count -->
|
||||
<span v-if="loaded">
|
||||
<i class="tags icon"></i> <b>{{tags.length}} Tags</b>
|
||||
</span>
|
||||
|
||||
<!-- No tags default text -->
|
||||
<span v-if="tags.length == 0 && loaded" class="ui small compact green button">
|
||||
<i class="plus icon"></i> Add a tag
|
||||
</span>
|
||||
|
||||
<!-- display tags in comma delimited list -->
|
||||
<span v-if="tags.length > 0">
|
||||
<span v-for="(tag, i) in tags"><span v-if="i > 0">, </span>{{ucWords(tag.text)}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui form">
|
||||
<input
|
||||
placeholder="Add Tag"
|
||||
v-model="newTagInput"
|
||||
v-on:keydown="tagInput"
|
||||
v-on:keyup="onKeyup"
|
||||
v-on:blur="onBlur"
|
||||
v-on:focus="onFocus"
|
||||
/>
|
||||
<div class="suggestion-box" v-if="suggestions.length > 0">
|
||||
<div class="suggestion-item" v-for="(item, index) in suggestions" :class="{ 'active':(index == selection) }" v-on:click="onClickTag(index)">
|
||||
{{ucWords(item.text)}} <span class="suggestion-tip" v-if="index == selection">Press Enter to add</span>
|
||||
|
||||
<!-- hover over view -->
|
||||
<div v-if="fullTagEdit" class="full-tag-area fade-in-fwd" v-on:mouseleave="fullTagEdit = false; clearSuggestions()">
|
||||
|
||||
<!-- tag input and suggestion popup -->
|
||||
<div class="ui form">
|
||||
<input
|
||||
placeholder="Tag name. Press (Up) to select suggestion. Press (Enter) to submit."
|
||||
v-model="newTagInput"
|
||||
v-on:keydown="tagInput"
|
||||
v-on:keyup="onKeyup"
|
||||
v-on:blur="onBlur"
|
||||
v-on:focus="onFocus"
|
||||
/>
|
||||
<div class="suggestion-box" v-if="suggestions.length > 0">
|
||||
<div class="suggestion-item" v-for="(item, index) in suggestions" :class="{ 'active':(index == selection) }" v-on:click="onClickTag(index)">
|
||||
{{ucWords(item.text)}} <span class="suggestion-tip" v-if="index == selection">Press Enter to add</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- existing tags -->
|
||||
<div class="delete-tag-display" v-if="tags.length > 0">
|
||||
<div class="ui icon large label" v-for="tag in tags" :class="{ 'green':(newTagInput == tag.text) }">
|
||||
{{ucWords(tag.text)}} <i class="delete icon" v-on:click="removeTag(tag.id)"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,12 +65,14 @@
|
||||
props: [ 'noteId' ],
|
||||
data () {
|
||||
return {
|
||||
tags: null,
|
||||
tags: [],
|
||||
newTagInput: '',
|
||||
typeDebounce: null,
|
||||
|
||||
suggestions: [],
|
||||
selection: 0
|
||||
selection: 0,
|
||||
fullTagEdit: false,
|
||||
loaded: false,
|
||||
}
|
||||
},
|
||||
beforeMount(){
|
||||
@@ -50,6 +87,7 @@
|
||||
let vm = this
|
||||
axios.post('/api/tag/get', {'noteId': this.noteId})
|
||||
.then(response => {
|
||||
vm.loaded = true
|
||||
//Set up local data
|
||||
vm.tags = response.data
|
||||
})
|
||||
@@ -57,10 +95,6 @@
|
||||
tagInput(event){
|
||||
let vm = this
|
||||
|
||||
if(this.newTagInput.length == 0){
|
||||
this.clearSuggestions()
|
||||
}
|
||||
|
||||
//Cancel any of the following key events
|
||||
const code = event.keyCode
|
||||
if([38, 40, 13, 9].includes(code)){
|
||||
@@ -94,6 +128,7 @@
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//Tab - 9 - Fill space with suggestion
|
||||
|
||||
//Anything else, perform search
|
||||
@@ -136,10 +171,11 @@
|
||||
vm.newTagInput = ''
|
||||
vm.clearSuggestions()
|
||||
vm.getTags()
|
||||
//Trigger focus event to reload tag suggestions
|
||||
vm.onFocus()
|
||||
})
|
||||
},
|
||||
onFocus(){
|
||||
console.log('Focused on tag edit')
|
||||
//Show suggested tags
|
||||
let vm = this
|
||||
let postData = {
|
||||
@@ -153,9 +189,13 @@
|
||||
})
|
||||
},
|
||||
onKeyup(){
|
||||
//Clear tags if backspaced
|
||||
if(this.newTagInput == ''){
|
||||
this.clearSuggestions()
|
||||
|
||||
const code = event.keyCode
|
||||
|
||||
//Backspace - clear old suggestions, load latest suggestions
|
||||
if(code == 8 && this.newTagInput.length == 0){
|
||||
//Fetch suggestions
|
||||
this.onFocus()
|
||||
}
|
||||
},
|
||||
onBlur(){
|
||||
@@ -190,6 +230,34 @@
|
||||
}
|
||||
</script>
|
||||
<style type="text/css" scoped>
|
||||
|
||||
/* note tag edit area */
|
||||
.full-tag-area {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
color: var(--text_color);
|
||||
background-color: var(--background_color);
|
||||
padding: 15px;
|
||||
border: 1px solid;
|
||||
border-color: var(--border_color);
|
||||
}
|
||||
.full-tag-area .delete-tag-display {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.full-tag-area .ui.label {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.simple-tag-display {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-height: 35px;
|
||||
}
|
||||
|
||||
/* tag suggestion box styles */
|
||||
.suggestion-box {
|
||||
position: absolute;
|
||||
bottom: 38px;
|
||||
@@ -202,6 +270,7 @@
|
||||
padding: 10px 15px;
|
||||
cursor: pointer;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
.suggestion-item.active {
|
||||
background: green;
|
||||
|
@@ -1,50 +1,71 @@
|
||||
<template>
|
||||
<div class="note-title-display-card fade-in-fwd" :style="{'background-color':color, 'color':fontColor}">
|
||||
<div class="note-title-display-card fade-in-fwd"
|
||||
:style="{'background-color':color, 'color':fontColor}"
|
||||
:class="{'currently-open':currentlyOpen}"
|
||||
>
|
||||
|
||||
<div class="ui grid max-height">
|
||||
|
||||
<div class="top aligned row">
|
||||
<!-- Show title and snippet below it -->
|
||||
<div class="top aligned row" @click.stop="onClick(note.id)">
|
||||
|
||||
<div class="sixteen wide column overflow-hidden" v-if="isShowingSearchResults()">
|
||||
<!-- Display highlights from solr results -->
|
||||
<div v-if="note.note_highlights.length > 0" class="term-usage">
|
||||
<h4><i class="paragraph icon"></i> Found in Text</h4>
|
||||
<div class="usage-row" v-for="highlight in note.note_highlights" v-html="cleanHighlight(highlight)"></div>
|
||||
</div>
|
||||
<div v-if="note.attachment_highlights.length > 0" class="term-usage">
|
||||
<h4><i class="linkify icon"></i> Found in URL</h4>
|
||||
<div class="usage-row" v-for="highlight in note.attachment_highlights" v-html="cleanHighlight(highlight)"></div>
|
||||
</div>
|
||||
<div v-if="note.tag_highlights.length > 0" class="term-usage">
|
||||
<h4><i class="tags icon"></i> Found in Tags</h4>
|
||||
<div class="usage-row" v-for="highlight in note.tag_highlights">
|
||||
<span
|
||||
v-for="tag in splitTags(highlight)"
|
||||
class="ui label"
|
||||
>
|
||||
<span v-html="tag"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sixteen wide column overflow-hidden">
|
||||
<h3 @click="onClick(note.id)" class="clickable">{{note.title}}</h3>
|
||||
<h3 class="clickable">{{note.title}}</h3>
|
||||
</div>
|
||||
<div class="sixteen wide column overflow-hidden">
|
||||
<p @click="onClick(note.id)" class="clickable">{{note.subtext}}</p>
|
||||
<p class="clickable">{{note.subtext}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom aligned row">
|
||||
<div class="ten wide column clickable" @click="onClick(note.id)">Edited: {{$helpers.timeAgo(note.updated)}}</div>
|
||||
<div class="bottom aligned row" @click.self.stop="onClick(note.id)">
|
||||
<div class="six wide column clickable" @click.stop="onClick(note.id)">
|
||||
{{$helpers.timeAgo(note.updated)}}
|
||||
</div>
|
||||
|
||||
<div class="six wide right aligned column">
|
||||
<span v-if="note.attachment_count > 0" class>
|
||||
<i class="grey linkify icon"></i> {{note.attachment_count}}
|
||||
<div class="ten wide right aligned column split-spans">
|
||||
<span v-if="note.pinned == 1" data-tooltip="Pinned">
|
||||
<i class="green pin icon"></i>
|
||||
</span>
|
||||
<span v-if="note.archived == 1" data-tooltip="Archived">
|
||||
<i class="green archive icon"></i>
|
||||
</span>
|
||||
<span v-if="note.attachment_count > 0">
|
||||
<i class="linkify icon"></i> {{note.attachment_count}}
|
||||
</span>
|
||||
<span v-if="note.tag_count == 1" data-tooltip="Note has 1 tag">
|
||||
<i class="grey tags icon"></i> {{note.tag_count}}
|
||||
<i class="tags icon"></i> {{note.tag_count}}
|
||||
</span>
|
||||
<span v-if="note.tag_count > 1" :data-tooltip="`Note has ${note.tag_count} tags`">
|
||||
<i class="grey tags icon"></i> {{note.tag_count}}
|
||||
<i class="tags icon"></i> {{note.tag_count}}
|
||||
</span>
|
||||
<delete-button :note-id="note.id" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display highlights from solr results -->
|
||||
<div v-if="note.note_highlights.length > 0" class="term-usage">
|
||||
<p><i class="paragraph icon"></i> Note Text</p>
|
||||
<div class="usage-row" v-for="highlight in note.note_highlights" v-html="highlight"></div>
|
||||
</div>
|
||||
<div v-if="note.attachment_highlights.length > 0" class="term-usage">
|
||||
<p><i class="linkify icon"></i> Note URL Text</p>
|
||||
<div class="usage-row" v-for="highlight in note.attachment_highlights" v-html="highlight"></div>
|
||||
</div>
|
||||
<div v-if="note.tag_highlights.length > 0" class="term-usage">
|
||||
<i class="tags icon"></i> Tag
|
||||
<div class="ui icon large label" v-for="highlight in note.tag_highlights" v-html="highlight"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -52,10 +73,28 @@
|
||||
|
||||
export default {
|
||||
name: 'NoteTitleDisplayCard',
|
||||
props: [ 'onClick', 'data' ],
|
||||
props: [ 'onClick', 'data', 'currentlyOpen' ],
|
||||
components: {
|
||||
'delete-button': require('@/components/NoteDeleteButtonComponent.vue').default,
|
||||
},
|
||||
methods:{
|
||||
cleanHighlight(text){
|
||||
//Basically just remove whitespace
|
||||
let updated = text.replace(/ /g, '').replace(/<br>/g,'')
|
||||
.replace(/<p><\/p>/g,'').replace(/<p> <\/p>/g,'')
|
||||
|
||||
return updated
|
||||
},
|
||||
isShowingSearchResults(){
|
||||
if(this.note.note_highlights.length > 0 || this.note.attachment_highlights.length > 0 || this.note.tag_highlights.length > 0){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
splitTags(text){
|
||||
return text.split(',')
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
note: null,
|
||||
@@ -77,13 +116,13 @@
|
||||
<style type="text/css">
|
||||
|
||||
.term-usage {
|
||||
border-top: 1px solid #DDD;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
.term-usage em {
|
||||
color: green;
|
||||
background-color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.usage-row + .usage-row {
|
||||
@@ -100,12 +139,16 @@
|
||||
border-radius: .28571429rem;
|
||||
border: 1px solid;
|
||||
border-color: var(--border_color);
|
||||
width: 31.5%;
|
||||
/*transition: width 0.2s;*/
|
||||
width: calc(33.333% - 15px);
|
||||
transition: box-shadow 0.3s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.note-title-display-card:hover {
|
||||
box-shadow: 0 1px 2px -0 rgba(34,36,38,.50);
|
||||
}
|
||||
.one-column .note-title-display-card {
|
||||
margin-right: 65%;
|
||||
width: 18%;
|
||||
width: 33%;
|
||||
}
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
@@ -116,6 +159,22 @@
|
||||
.max-height {
|
||||
height: calc(100% + 30px);
|
||||
}
|
||||
.currently-open:after {
|
||||
content: 'Open';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #000000b0;
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #cecece;
|
||||
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 740px) {
|
||||
.note-title-display-card {
|
||||
|
Reference in New Issue
Block a user