Skip to content

Commit

Permalink
Fix #1647
Browse files Browse the repository at this point in the history
  • Loading branch information
jlpereira committed Aug 13, 2020
1 parent 0ecab35 commit faa8fa2
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 2 deletions.
17 changes: 17 additions & 0 deletions app/assets/stylesheets/base/borders.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.rounded-circle {
border-radius: 50%;
}

.rounded-pill {
border-radius: 25%;
}

.circle-s {
width: 32px;
height: 32px;
}

.circle-m {
width: 64px;
height: 64px;
}
1 change: 1 addition & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require('../vue/initializers/default_confidence/main.js')
require('../vue/initializers/tagButton/main.js')
require('../vue/initializers/quick_citation_init/main.js')
require('../vue/initializers/browse_nomenclature/main.js')
require('../vue/initializers/pinboard_navigator/main.js')
require('../vue/tasks/type_specimens/main.js')
require('../vue/tasks/nomenclature/new_combination/main.js')
require('../vue/tasks/browse_annotations/main.js')
Expand Down
22 changes: 22 additions & 0 deletions app/javascript/vue/components/pinboard/const/shortcuts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export default {
TaxonNames: {
shortcut: 'b',
path: '/tasks/nomenclature/browse',
param: 'taxon_name_id'
},
CollectionObjects: {
shortcut: 'c',
path: '/tasks/collection_objects/browse',
param: 'collection_object_id'
},
Otus: {
shortcut: 'o',
path: '/tasks/otus/browse',
param: 'otu_id'
},
CollectingEvents: {
shortcut: 's',
path: '/tasks/collecting_events/browse',
param: 'collecting_event_id'
}
}
106 changes: 106 additions & 0 deletions app/javascript/vue/components/pinboard/navigator.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<div
v-shortkey="['ctrl', 'p']"
@shortkey="openModal">
<modal-component
@close="showModal = false"
v-if="showModal">
<h3 slot="header">Pinboard navigator - Browse tasks</h3>
<div slot="body">
<ul class="no_bullets">
<template v-for="(item, key) in defaultItems">
<li
class="margin-small-bottom"
v-if="sections[key]"
:key="key"
v-shortkey="[sections[key].shortcut]"
@shortkey="selectItem(key, item)">
<transition
v-if="selected && selected.klass == key"
name="bounce"
@after-enter="test"
appear>
<div class="horizontal-left-content cursor-pointer">
<div class="rounded-circle button-default horizontal-center-content circle-s middle margin-small-right">
<span class="capitalize"><b>{{ sections[key].shortcut }}</b></span>
</div>
<span v-html="shorten(item.label, 38)"/>
</div>
</transition>
<div
v-else
class="horizontal-left-content cursor-pointer">
<div class="rounded-circle button-default horizontal-center-content circle-s middle margin-small-right">
<span class="capitalize"><b>{{ sections[key].shortcut }}</b></span>
</div>
<span v-html="shorten(item.label, 38)"/>
</div>
</li>
</template>
</ul>
</div>
</modal-component>
</div>
</template>

<script>
import ModalComponent from 'components/modal'
import Shortcuts from './const/shortcuts.js'
import { shorten } from 'helpers/strings.js'
export default {
components: {
ModalComponent
},
data () {
return {
showModal: false,
sections: Shortcuts,
defaultItems: {},
selected: undefined
}
},
methods: {
test () {
const klass = this.selected.klass
window.open(`${this.sections[klass].path}?${this.sections[klass].param}=${this.selected.object.id}`, '_self')
},
selectItem (key, item) {
this.selected = { klass: key, object: item }
},
openModal () {
this.defaultItems = {}
document.querySelectorAll('[data-pinboard-section]').forEach(node => {
this.defaultItems[node.getAttribute('data-pinboard-section')] = {
id: node.querySelector('[data-insert="true"]').getAttribute('data-pinboard-object-id'),
label: node.querySelector('[data-insert="true"] a').textContent
}
})
this.selected = undefined
this.showModal = true
},
shorten: shorten
}
}
</script>
<style scoped>
.bounce-enter-active {
animation: bounce-in 1s;
}
.bounce-leave-active {
animation: bounce-in 1s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5) translateX(25%);
}
100% {
transform: scale(1);
}
}
</style>
8 changes: 7 additions & 1 deletion app/javascript/vue/helpers/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ function capitalize (string) {
return string.charAt(0).toUpperCase() + string.substring(1)
}

function shorten (str, maxLen, separator = ' ') {
if (str.length <= maxLen) return str
return `${str.substr(0, str.lastIndexOf(separator, maxLen))} ...`
}

export {
capitalize
capitalize,
shorten
}
19 changes: 19 additions & 0 deletions app/javascript/vue/initializers/pinboard_navigator/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Vue from 'vue'
import App from 'components/pinboard/navigator.vue'
import vueShortkey from 'vue-shortkey'

function init () {
Vue.use(vueShortkey)
new Vue({
el: '#vue-pinboard-navigator',
render: function (createElement) {
return createElement(App)
}
})
}

document.addEventListener('turbolinks:load', (event) => {
if (document.querySelector('#vue-pinboard-navigator')) {
init()
}
})
2 changes: 1 addition & 1 deletion app/views/shared/data/slideout/_pinboard.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<%= render :partial => '/pinboard_items/pinboard' %>
</div>
</div>
<div id="vue-pinboard-navigator"></div>
<% end %>
<%= render partial: '/shared/data/slideout/panel' %>

0 comments on commit faa8fa2

Please sign in to comment.