Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 115 #188

Open
wants to merge 8 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions components/RecurringVenueChip.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<v-chip
cols="12"
class="ma-2"
label
color="green white--text"
:to="whereTo(item)"
>
<v-avatar left>
<v-icon>{{ venueIcon(item.type) }}</v-icon>
</v-avatar>
<div>{{ item.type }}</div>
</v-chip>
</template>

<script>
import { venueIcon } from '@/helpers'

export default {
components: {},
props: {
item: {
type: Object,
required: true
},
},
methods: {
venueIcon,
whereTo(item) {
// if (this.link) {
// switch (this.type) {
// case 'keyword':
// return '/search?keywords=' + item
// case 'role':
// return '/search?author_keywords=' + item.affiliation.person.name
// case 'relation':
// return '/artifact/' + item.related_artifact_group_id
// case 'reverse-relation':
// return '/artifact/' + item.artifact_group_id
// case 'venue':
// return '/search?venue_ids=' + item.id
// }
// }
return null
}
},
}
</script>
33 changes: 33 additions & 0 deletions components/RecurringVenueList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<div>
<v-container>
<v-row v-for="venue in recurringVenues" :key="venue.id">
<v-col>
<LazyHydrate when-visible>
<RecurringVenueShort
:recurringVenue="venue"
></RecurringVenueShort>
</LazyHydrate>
</v-col>
</v-row>
</v-container>
</div>
</template>

<script>
export default {
components: {
RecurringVenueShort: () => import('@/components/RecurringVenueShort'),
LazyHydrate: () => import('vue-lazy-hydration')
},
props: {
recurringVenues: {
type: Array,
required: true
},
},
data() {
return {}
}
}
</script>
180 changes: 180 additions & 0 deletions components/RecurringVenueSearchCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<template>
<div>
<RecurringVenueList
:recurringVenues="recurringVenues"
:limit="limit"
></RecurringVenueList>
<v-btn
v-if="showScrollToTop != 0"
class="secondary"
id="scrollbtn"
@click="scrollToTop()"
elevation="10"
><v-icon large color="lightblue">mdi-chevron-up</v-icon></v-btn
>
</div>
</template>

<script>
import { mapState } from 'vuex'
import goTo from 'vuetify/es5/services/goto'

const deepClone = (obj) => JSON.parse(JSON.stringify(obj))

export default {
components: {
Logo: () => import("@/components/Logo"),
RecurringVenueList: () => import("@/components/RecurringVenueList"),
},
head() {
return {
title: 'SEARCCH Venue Search',
meta: [
{
hid: 'description',
name: 'description',
content: 'SEARCCH Hub Venue Search Results'
}
]
}
},
data() {
return {
// limit: 10,
// page: 1,
// search: '',
// searchMessage: '',
// searchInterval: null,
// submitted: false,
// adopen: 1,
// advanced: {
// types: [ 'conference', 'journal', 'magazine', 'newspaper', 'periodical', 'event', 'other' ],
// venue_ids: [],
// },
// types: [ 'conference', 'journal', 'magazine', 'newspaper', 'periodical', 'event', 'other' ],
showScrollToTop: 0
}
},
beforeMount() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
},
mounted() {
if (this.$route.query.keywords) {
this.search = this.$route.query.keywords
console.log('keywords: ', this.search)
this.onSubmit()
} else {
this.search = this.search_init
this.advanced = deepClone(this.search_advanced_init)
this.adopen = +(!this.search_advanced_isopen)
}
this.$store.dispatch('user/fetchBadges')
this.$store.dispatch('user/fetchVenues')
},
computed: {
...mapState({
recurringVenues: state => state.venues.recurringVenues.recurring_venue,
// pages: state => state.venues.recurringVenues.pages,
// total: state => state.venues.recurringVenues.total,
search_init: state => state.venues.search,
search_advanced_init: state => state.venues.search_advanced,
search_advanced_isopen: state => state.venues.search_advanced_isopen,
searchLoading: state => state.venues.loading,
}),
allRecurringVenues() {
return this.advanced.types.length === this.types.length
},
someRecurringVenues() {
return this.advanced.types.length > 0 && !this.allArtifacts
},
recurringVenueTypeIcon() {
if (this.allRecurringVenues) return 'mdi-close-box'
if (this.someRecurringVenues) return 'mdi-minus-box'
return 'mdi-checkbox-blank-outline'
},
},
methods: {
async onSubmit() {
this.submitted = true
if (this.searchInterval != null) clearTimeout(this.searchInterval)
this.searchMessage = 'Searching...'
this.$store.commit('venues/RESET_RECURRING_VENUES') // clear artifacts so the Searching... message is shown
debugger
let payload = {
keywords: this.search,
// page: this.page,
// items_per_page: this.limit,
type: this.advanced.types
}
this.$store.dispatch('venues/fetchRecurringVenues', { payload, advanced: this.advanced })
this.searchInterval = setTimeout(() => {
if (!this.searchLoading) {
this.searchMessage = 'No results found'
}
}, 3000)
this.submitted = false
},
onChange() {
this.searchMessage = ''
},
toggle() {
this.$nextTick(() => {
if (this.allRecurringVenues) {
this.advanced.types = []
} else {
this.advanced.types = this.types.slice()
}
})
},
scrollToTop() {
goTo(0)
},
handleScroll() {
this.showScrollToTop = window.scrollY
},
showOptions(val){
if (val != "None"){
this.sortEnabled = true
this.advanced.sort_criteria = val
}
else{
this.sortEnabled = false
}
},
},
watch: {
page() {
this.onSubmit()
},
searchLoading(val) {
if (val) {
this.searchMessage = 'Searching...'
} else if (this.search !== '') {
if (this.searchInterval != null) clearTimeout(this.searchInterval)
this.searchMessage = 'No results found'
} else {
this.searchMessage = ''
}
}
}
}
</script>

<style scoped>
.v-application--is-ltr .v-input__prepend-outer {
margin-right: 0px;
}
.v-text-field--outlined .v-input__prepend-outer,
.v-text-field--outlined .v-input__append-outer {
margin-top: 4px;
}
#scrollbtn {
position: fixed;
bottom: 50px;
right: 0px;
scroll-margin-bottom: 5rem;
}
</style>
93 changes: 93 additions & 0 deletions components/RecurringVenueShort.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<!-- <div> -->
<!-- <v-container> -->
<v-card>
<!-- <v-row no-gutters class="recurring-venue-container"> -->
<!-- <v-col cols="10"> -->
<v-card-title class="align-start">
<span class="headline">{{ recurringVenue.title | titlecase }}</span>
</v-card-title>
<v-card-text v-html="sanitizedDescription"> </v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" @click="onRelatedArtifactsClicked">
Related Artifacts
</v-btn>
</v-card-actions>
<!-- </v-col>
<v-col cols="2" class="recurrence-container">
<v-list density="compact" class="list">
<v-list-item v-for="item in recurringVenue.recurrences" :key="item.title" :value="item">
<v-list-item-title>{{ item.abbrev }}</v-list-item-title>
</v-list-item>
</v-list>
</v-col> -->
<!-- </v-row> -->
</v-card>
<!-- </v-container>
</div> -->
</template>

<script>
import clip from 'text-clipper'

export default {
props: {
recurringVenue: {
type: Object,
required: true
},
},
components: {
RecurringVenueChip: () => import("@/components/RecurringVenueChip"),
},
computed: {
sanitizedDescription: function () {
let description = ''
description = this.recurringVenue.description
return clip(this.$sanitize(description), 2000, {
html: true,
maxLines: 40
})
}
},
methods: {
onRelatedArtifactsClicked() {
this.$store.commit('venues/SET_RECURRENCE_ID', this.recurringVenue.recurrences[0].id)
this.$router.push('/venue/' + this.recurringVenue.id)
},
}
}
</script>

<style scoped>
.card-chip {
position: absolute;
top: 0px;
right: 0px;
}

.v-card__title {
word-break: normal;
}

.headline {
align-self: center;
}

.recurring-venue-container {
overflow: auto;
}

.recurrence-container {
border-left: 1px solid #e0e0e0;
background-color: #fafafa;
}

.recurrence-container .list {
margin-left: 10px;
background-color: transparent;
max-height: 100%;
overflow: scroll;
}
</style>
1 change: 0 additions & 1 deletion components/SearchCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@
<script>
import { mapState } from 'vuex'
import goTo from 'vuetify/es5/services/goto'
import { getCookie } from '~/helpers'

const deepClone = (obj) => JSON.parse(JSON.stringify(obj))

Expand Down
5 changes: 5 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ export default {
icon: 'mdi-cloud-search',
title: 'Search Artifacts',
to: '/search'
},
{
icon: 'mdi-cloud-search',
title: 'Artifact Venues',
to: '/venues'
}
]
if (this.$auth.loggedIn) {
Expand Down
2 changes: 1 addition & 1 deletion pages/search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<logo />
</div>
<h1>
Search
Search Artifacts
<v-dialog transition="dialog-bottom-transition" max-width="600">
<template v-slot:activator="{ on, attrs }">
<v-btn class="primary ml-4" fab small v-bind="attrs" v-on="on"
Expand Down
Loading