- larvale version 5.6 to 5.8
This commit is contained in:
parent
a2967b90ee
commit
265cfbcd30
43 changed files with 925 additions and 246 deletions
82
resources/js/search/App.vue
Normal file
82
resources/js/search/App.vue
Normal file
|
@ -0,0 +1,82 @@
|
|||
<template v-if="loaded">
|
||||
<div class="search-container row">
|
||||
<div class="four columns left-bar">
|
||||
<div id="left-bar" class="sidebar left-bar">
|
||||
<div class="sidebar-image"></div>
|
||||
<!-- <h2 class="indexheader">DataXplore</h2> -->
|
||||
|
||||
<!-- <div class="card" v-for="item in facets.language" :key="item.id">
|
||||
<span>{{ item }}</span>
|
||||
</div>-->
|
||||
|
||||
<!-- <facet-list v-bind:data="facets"></facet-list> -->
|
||||
<!-- <div class="card" v-for="(item, index) in facets" :key="index"> -->
|
||||
<div class="card" v-for="(values, key, index) in facets" :key="index">
|
||||
<facet-list :data="values" :filterName="key" @filter="onFilter"></facet-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="eight columns right-bar">
|
||||
<div id="right-bar" class="sidebar right-bar">
|
||||
<!-- Search input section -->
|
||||
<div class="row">
|
||||
<div class="twelve columns">
|
||||
<vs-input @search="onSearch"></vs-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="results.length > 0" class="result-list-info">
|
||||
<div class="resultheader">
|
||||
Your search yielded
|
||||
<strong>{{ numFound }}</strong> results:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="active-filter-items twelve columns">
|
||||
<a class="filter-link" v-for="(value, key, index) in activeFilterItems" :key="index">
|
||||
<span>{{ key + ": " }}</span>
|
||||
<span v-if="value && value.length > 0">{{ value.join(', ') }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Results section -->
|
||||
<vs-results v-bind:data="results"></vs-results>
|
||||
|
||||
<!-- pagination -->
|
||||
<div class="row">
|
||||
<div class="twelve columns">
|
||||
<vs-pagination v-bind:data="pagination" @paginate="onPaginate"></vs-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="card" v-for="item in results" :key="item.id">
|
||||
<img
|
||||
v-if="item.thumb"
|
||||
class="card-img-top"
|
||||
:src="item.thumb"
|
||||
:alt="item.title"
|
||||
@error="error(item)"
|
||||
/>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{item.name}}</h5>
|
||||
<p class="card-text" v-html="truncate(item.description || item.abstract, 50)"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import App from "./app-class";
|
||||
export default App;
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#app {
|
||||
color: #56b983;
|
||||
}
|
||||
</style>
|
147
resources/js/search/app-class.ts
Normal file
147
resources/js/search/app-class.ts
Normal file
|
@ -0,0 +1,147 @@
|
|||
import { Component, Vue, Prop, Provide } from 'vue-property-decorator';
|
||||
import VsInput from './text-search/vs-input.vue';
|
||||
import VsResults from './search-results/vs-results.vue';
|
||||
import FacetList from './search-results/facet-list.vue';
|
||||
import VsPagination from './search-results/vs-pagination.vue';
|
||||
import rdrApi from './search-results/dataservice';
|
||||
import FilterItem from './models/filter-item';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
VsInput,
|
||||
VsResults,
|
||||
FacetList,
|
||||
VsPagination
|
||||
}
|
||||
})
|
||||
export default class App extends Vue {
|
||||
|
||||
results: Array<any> = [];
|
||||
facets: Object = {};
|
||||
searchTerm: string = '';
|
||||
activeFilterItems: Object = {};
|
||||
pagination: Object = {
|
||||
total: 0,
|
||||
per_page: 2,
|
||||
current_page: 0,
|
||||
// last_page: 0,
|
||||
data: []
|
||||
};
|
||||
loaded = false;
|
||||
numFound: number;
|
||||
|
||||
async onPaginate(start: number): Promise<void> {
|
||||
console.log(start);
|
||||
var res = await rdrApi.search(this.searchTerm, this.activeFilterItems, start.toString());
|
||||
this.results = res.response.docs;
|
||||
}
|
||||
|
||||
async onFilter(filter): Promise<void> {
|
||||
// console.log(filter.value);
|
||||
// if (!this.activeFilterItems.some(e => e.value === filter.value)) {
|
||||
// this.activeFilterItems.push(filter);
|
||||
if (!this.activeFilterItems.hasOwnProperty(filter.Category)) {
|
||||
this.activeFilterItems[filter.Category] = [];
|
||||
}
|
||||
if (!this.activeFilterItems[filter.Category].some(e => e === filter.value)) {
|
||||
this.activeFilterItems[filter.Category].push(filter.value);
|
||||
|
||||
var res = await rdrApi.search(this.searchTerm, this.activeFilterItems);
|
||||
this.results = res.response.docs;
|
||||
this.numFound = res.response.numFound;
|
||||
|
||||
// pagination
|
||||
this.pagination['total'] = res.response.numFound;
|
||||
this.pagination['per_page'] = res.responseHeader.params.rows;
|
||||
this.pagination['current_page'] = 1;
|
||||
this.pagination['data'] = res.response.docs;
|
||||
|
||||
var facet_fields = res.facet_counts.facet_fields;
|
||||
for (var prop in facet_fields) {
|
||||
var facetValues = facet_fields[prop].map((facetValue, i) => {
|
||||
if (i % 2 === 0) {
|
||||
// var rObj = { value: facetValue, count: facet_fields[prop][i + 1] };
|
||||
var rObj;
|
||||
if (filter.value == facetValue) {
|
||||
rObj = filter;
|
||||
} else if (this.facets[prop].some(e => e.value === facetValue)) {
|
||||
console.log(facetValue + " is included")
|
||||
var indexOfFacetValue = this.facets[prop].findIndex(i => i.value === facetValue);
|
||||
console.log(indexOfFacetValue);
|
||||
rObj = this.facets[prop][indexOfFacetValue];
|
||||
rObj.count = facet_fields[prop][i + 1];
|
||||
} else {
|
||||
rObj = new FilterItem(facetValue, facet_fields[prop][i + 1]);
|
||||
}
|
||||
return rObj;
|
||||
}
|
||||
}).filter(function (el) {
|
||||
return el != null && el.count > 0;
|
||||
});
|
||||
// this.facets.push({ filterName: prop, values: facetValues });
|
||||
this.facets[prop] = facetValues;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async onSearch(term): Promise<void> {
|
||||
if (term){
|
||||
term = term.trim();
|
||||
} else {
|
||||
term = "*%3A*";
|
||||
}
|
||||
|
||||
this.activeFilterItems = {};
|
||||
// while (this.facets.length > 0) {
|
||||
// this.facets.pop();
|
||||
// }
|
||||
this.facets = {};
|
||||
this.searchTerm = term;
|
||||
var res = await rdrApi.search(this.searchTerm, this.activeFilterItems);
|
||||
this.results = res.response.docs;
|
||||
this.numFound = res.response.numFound;
|
||||
|
||||
// pagination
|
||||
this.pagination['total'] = res.response.numFound;
|
||||
this.pagination['per_page'] = res.responseHeader.params.rows;
|
||||
this.pagination['current_page'] = 1;
|
||||
this.pagination['data'] = res.response.docs;
|
||||
|
||||
// facets
|
||||
var facet_fields = res.facet_counts.facet_fields;
|
||||
for (var prop in facet_fields) {
|
||||
var facetValues = facet_fields[prop].map((facet, i) => {
|
||||
if (i % 2 === 0) {
|
||||
//var rObj = { value: facet, count: facet_fields[prop][i + 1] };
|
||||
var rObj = new FilterItem(facet, facet_fields[prop][i + 1])
|
||||
return rObj;
|
||||
}
|
||||
}).filter(function (el) {
|
||||
return el != null && el.count > 0;
|
||||
});
|
||||
//this.facets.push({ filterName: prop, values: facetValues });
|
||||
this.facets[prop] = facetValues;
|
||||
}
|
||||
// console.log(this.facets.toString());
|
||||
}
|
||||
|
||||
// When the window loads, read query parameters and perform search
|
||||
async mounted() {
|
||||
var query = this.getParameterByName("q");
|
||||
if (query) query = query.trim();
|
||||
await this.onSearch("*%3A*");
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
getParameterByName(name: string, url?: string) {
|
||||
if (!url) url = window.location.href;
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return "";
|
||||
return decodeURIComponent(results[2].replace(/\+/g, " "));
|
||||
}
|
||||
|
||||
}
|
7
resources/js/search/main.ts
Normal file
7
resources/js/search/main.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Vue from 'vue';
|
||||
import App from './App.vue';
|
||||
|
||||
new Vue({
|
||||
el: '#test',
|
||||
render: h => h(App)
|
||||
});
|
31
resources/js/search/models/filter-item.ts
Normal file
31
resources/js/search/models/filter-item.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
export default class FilterItem {
|
||||
private category: string;
|
||||
value: string;
|
||||
count: number;
|
||||
private active: boolean;
|
||||
|
||||
constructor(value: string, count: number) {
|
||||
this.value = value;
|
||||
this.count = count;
|
||||
this.active = false;
|
||||
this.category = "";
|
||||
}
|
||||
|
||||
//#region properties
|
||||
|
||||
get Category(): string {
|
||||
return this.category;
|
||||
}
|
||||
set Category(theCategory: string) {
|
||||
this.category = theCategory;
|
||||
}
|
||||
|
||||
get Active(): boolean {
|
||||
return this.active;
|
||||
}
|
||||
set Active(isActive: boolean) {
|
||||
this.active = isActive;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
75
resources/js/search/search-results/dataservice.ts
Normal file
75
resources/js/search/search-results/dataservice.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
import axios from "axios";
|
||||
|
||||
var SOLR_CONFIG = {
|
||||
"server": "https://arcticdata.io/metacat/d1/mn/v2/query/solr?", // Solr server
|
||||
"filter": "knb-lter-bnz", // Filter results for an organization or user
|
||||
"limit": 4, // Max number of results to retrieve per page
|
||||
"resultsElementId": "searchResults", // Element to contain results
|
||||
"urlElementId": "searchUrl", // Element to display search URL
|
||||
"countElementId": "resultCount", // Element showing number of results
|
||||
"pagesElementId": "pagination", // Element to display result page links
|
||||
"showPages": 5 // MUST BE ODD NUMBER! Max number of page links to show
|
||||
};
|
||||
|
||||
export default {
|
||||
|
||||
|
||||
async search(term: string, filterItems: Object, start?: string): Promise<any> {
|
||||
// solr endpoint
|
||||
// const host = 'http://voyagerdemo.com/';
|
||||
const host = 'https://repository.geologie.ac.at/';
|
||||
const path = 'solr/rdr_data/select?';
|
||||
var base = host + path;
|
||||
|
||||
//const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned
|
||||
var fields = ["id",
|
||||
"server_date_published",
|
||||
"abstract_output",
|
||||
"title_output",
|
||||
"title_additional",
|
||||
"author",
|
||||
"subject"].toString();
|
||||
var limit = "&rows=" + SOLR_CONFIG["limit"];
|
||||
// var limit = solrConfig.limit;
|
||||
|
||||
var dismaxFields = "title^3 abstract^2 subject^1";
|
||||
var params = "fl=" + fields;
|
||||
if (term == "*%3A*") {
|
||||
params += "&defType=edismax&wt=json&indent=on"; //edismax
|
||||
} else {
|
||||
params += "&defType=dismax&qf=" + dismaxFields + "&wt=json&indent=on"; //dismax
|
||||
}
|
||||
|
||||
if (start === undefined) start = "0";
|
||||
start = "&start=" + start;
|
||||
|
||||
|
||||
const facetFields = "&facet=on&facet.field=language&facet.field={!key=datatype}doctype&facet.field=subject";//&fq=year:(2019)";//&facet.query=year:2018";
|
||||
|
||||
var filterFields = "";
|
||||
// filterItems.forEach(function (item) {
|
||||
// console.log(item.value + " " + item.category);
|
||||
// filterFields += "&fq=" + item.category +":("+ item.value + ")";
|
||||
// });
|
||||
Object.entries(filterItems).forEach(([key, valueArray]) => {
|
||||
// console.log(`${key} ${valueArray}`);
|
||||
valueArray.forEach(function (value) {
|
||||
filterFields += "&fq=" + key + ":(" + value + ")";
|
||||
});
|
||||
|
||||
});
|
||||
var query = "&q=" + term;
|
||||
|
||||
|
||||
// $dismax->setQueryFields('title^3 abstract^2 subject^1');
|
||||
//const api = `${host}${path}?defType=dismax&q=${term}&fl=${fields}&qf=${dismaxFields}&facet=on&${facetFields}&${filterFields}&wt=json&rows=20&indent=on`;
|
||||
//const api = `${host}${path}?q=${term}&fl=${fields}&facet=on&${facetFields}&${filterFields}&wt=json&rows=20&indent=on`;
|
||||
|
||||
var api = base + params + limit + start + query + filterFields + facetFields;
|
||||
|
||||
let res = await axios.get(api);
|
||||
// let { data } = res.data;
|
||||
return res.data;//.response;//.docs;
|
||||
}
|
||||
|
||||
}
|
80
resources/js/search/search-results/facet-list-class.ts
Normal file
80
resources/js/search/search-results/facet-list-class.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { Component, Vue, Prop, Provide } from 'vue-property-decorator';
|
||||
import FilterItem from '../models/filter-item';
|
||||
|
||||
@Component
|
||||
export default class FacetList extends Vue {
|
||||
|
||||
ITEMS_PER_FILTER = 2;
|
||||
bar = '';
|
||||
collapsed = true;
|
||||
// filterItems = [];
|
||||
|
||||
@Prop()
|
||||
data;
|
||||
@Prop([String])
|
||||
filterName;
|
||||
// @Prop([String])
|
||||
// alias;
|
||||
|
||||
get alias(): string {
|
||||
return this.filterName == 'datatype' ? 'doctype' : this.filterName
|
||||
}
|
||||
// get filterItems() {
|
||||
// var facetValues = this.data.map((facet, i) => {
|
||||
// if (i % 2 === 0) {
|
||||
// // var rObj = {};
|
||||
// // rObj['value'] = facet;
|
||||
// // rObj['count'] = solrArray[i +1];
|
||||
// var rObj = { value: facet, count: this.data[i + 1], category: this.alias };
|
||||
// return rObj;
|
||||
// }
|
||||
// }).filter(function (el) {
|
||||
// return el != null && el.count > 0;
|
||||
// });
|
||||
// // var facetValues = this.data.language.filter(function(facet, i) {
|
||||
// // return i % 2 === 0;
|
||||
// // }).map(function (facet, i) {
|
||||
// // var rObj = { value: facet, count: this.data.language[i + 1] };
|
||||
// // return rObj;
|
||||
// // }, this);
|
||||
// return facetValues;
|
||||
// }
|
||||
get filterItems(): Array<FilterItem> {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
get overflowing(): boolean {
|
||||
//ko.observable(self.filterItems().length - self.activeFilterItems().length > ITEMS_PER_FILTER);
|
||||
return (this.filterItems.length) > this.ITEMS_PER_FILTER;
|
||||
}
|
||||
|
||||
get uncollapseLabelText() : string {
|
||||
if (this.collapsed == true) {
|
||||
// return myLabels.viewer.sidePanel.more; //"More results";
|
||||
return "More results";
|
||||
}
|
||||
else {
|
||||
// return myLabels.viewer.sidePanel.collapse; //"Collapse";
|
||||
return "Collapse";
|
||||
}
|
||||
}
|
||||
|
||||
toggle = function (): void {
|
||||
if (this.collapsed == true) {
|
||||
this.collapsed = false;
|
||||
}
|
||||
else if (this.collapsed == false) {
|
||||
this.collapsed = true;
|
||||
//list.children("li:gt(4)").hide();
|
||||
}
|
||||
}
|
||||
|
||||
activateItem = function (filterItem: FilterItem): void {
|
||||
filterItem.Category = this.alias;
|
||||
filterItem.Active = true;
|
||||
this.$emit("filter", filterItem);
|
||||
}
|
||||
|
||||
mounted() {
|
||||
}
|
||||
}
|
44
resources/js/search/search-results/facet-list.vue
Normal file
44
resources/js/search/search-results/facet-list.vue
Normal file
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<!-- <span>property: {{ filterName }}</span>
|
||||
<span>value: {{ myLanguageFilters }}</span>-->
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<h3 class="panel-title filterViewModelName">{{ filterName }}</h3>
|
||||
<!-- e.g.language -->
|
||||
<ul class="filter-items" v-bind:class="{'limited':filterItems.length > 1 && collapsed }">
|
||||
<li v-for="(item, index) in filterItems" :key="index" class="list-group-item">
|
||||
<!-- <input
|
||||
class="css-w1gpbi"
|
||||
name="language"
|
||||
v-bind:id="item.value"
|
||||
type="radio"
|
||||
v-bind:value="item.value"
|
||||
/>
|
||||
<label :for="item.value">
|
||||
<span click: @click="activateItem(item)">{{ item.value }} ({{ item.count }})</span>
|
||||
</label>-->
|
||||
<a :class="item.Active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.value }} ({{ item.count }})</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="overflowing" v-if="overflowing == true">
|
||||
<li>
|
||||
<span @click="toggle()">{{ uncollapseLabelText }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import FacetList from "./facet-list-class";
|
||||
export default FacetList;
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* local styles */
|
||||
.disabled {
|
||||
/* color: #EBEBE4; */
|
||||
color:lightgray;
|
||||
pointer-events: none;
|
||||
text-decoration:line-through;
|
||||
}
|
||||
</style>
|
50
resources/js/search/search-results/vs-pagination-class.ts
Normal file
50
resources/js/search/search-results/vs-pagination-class.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { Vue, Component, Prop } from 'vue-property-decorator';
|
||||
// import Vue from "vue";
|
||||
|
||||
@Component
|
||||
export default class VsPagination extends Vue {
|
||||
|
||||
pageNumber: number = 0; // default to page 0
|
||||
|
||||
@Prop()
|
||||
data;
|
||||
|
||||
@Prop({ default: 4 }) readonly offset: number;
|
||||
|
||||
changePage(page) {
|
||||
if (page == this.data.current_page) {
|
||||
return;
|
||||
}
|
||||
this.data.current_page = page;
|
||||
let from = (page * this.data.per_page) - this.data.per_page;
|
||||
this.$emit('paginate', from);
|
||||
}
|
||||
|
||||
get numberOfPages() {
|
||||
return Math.ceil(this.data.total / this.data.per_page);
|
||||
}
|
||||
|
||||
get pages() {
|
||||
let numberOfPages = Math.ceil(this.data.total / this.data.per_page);
|
||||
|
||||
// if (!this.data.to) {
|
||||
// return [];
|
||||
// }
|
||||
let from = this.data.current_page - this.data.per_page;
|
||||
if (from < 1) {
|
||||
from = 1;
|
||||
}
|
||||
let to = from + (this.data.per_page * 2);
|
||||
if (to >= numberOfPages) {
|
||||
to = numberOfPages;
|
||||
}
|
||||
let pagesArray = [];
|
||||
for (let page = from; page <= to; page++) {
|
||||
pagesArray.push(page);
|
||||
}
|
||||
return pagesArray;
|
||||
}
|
||||
|
||||
mounted() {
|
||||
}
|
||||
}
|
278
resources/js/search/search-results/vs-pagination.vue
Normal file
278
resources/js/search/search-results/vs-pagination.vue
Normal file
|
@ -0,0 +1,278 @@
|
|||
<template>
|
||||
<nav v-if="pages.length > 1" class="pagination is-rounded is-medium" role="navigation" aria-label="pagination">
|
||||
<ul class="pagination-list">
|
||||
|
||||
<!-- Previous Page Link -->
|
||||
<li v-if="data.current_page > 1">
|
||||
<a class="pagination-previous" href="javascript:void(0)" rel="prev" v-on:click.prevent="changePage(data.current_page - 1)">«</a>
|
||||
</li>
|
||||
<li v-else>
|
||||
<a class="pagination-previous disabled" disabled href="javascript:void(0)" rel="prev">«</a>
|
||||
</li>
|
||||
|
||||
<li v-for="(page, index) in pages" :key="index" >
|
||||
<a href="javascript:void(0)" v-on:click.prevent="changePage(page)" v-bind:class="['pagination-link', page == data.current_page ? 'is-current' : '']">{{ page }}</a>
|
||||
</li>
|
||||
|
||||
<!-- Previous Page Link -->
|
||||
<li v-if="data.current_page < numberOfPages">
|
||||
<a class="pagination-next" href="javascript:void(0)" v-on:click.prevent="changePage(data.current_page + 1)" rel="next">»</a>
|
||||
</li>
|
||||
<li v-else>
|
||||
<a class="pagination-next disabled" disabled href="javascript:void(0)" rel="next">»</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import VsPagination from "./vs-pagination-class";
|
||||
export default VsPagination;
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* local styles */
|
||||
/* vom cms Pagination */
|
||||
.pagination {
|
||||
text-align: center;
|
||||
margin: 80px 0 0 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.pagination a {
|
||||
/*font-size:1.1em;*/
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
/* selbst Pagination */
|
||||
.pagination-previous,
|
||||
.pagination-next,
|
||||
.pagination-link,
|
||||
.pagination-dots {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
align-items: center;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
display: inline-flex;
|
||||
/*display: inline-block;*/
|
||||
font-size: 1rem;
|
||||
height: 2.25em;
|
||||
justify-content: flex-start;
|
||||
line-height: 1.5;
|
||||
padding: calc(0.375em - 1px) calc(0.625em - 1px) calc(0.375em - 1px)
|
||||
calc(0.625em - 1px);
|
||||
/*padding-top: calc(0.375em - 1px);
|
||||
padding-right: calc(0.625em - 1px);
|
||||
padding-bottom: calc(0.375em - 1px);
|
||||
padding-left: calc(0.625em - 1px);*/
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.pagination-previous:focus,
|
||||
.pagination-next:focus,
|
||||
.pagination-link:focus,
|
||||
.pagination-dots:focus,
|
||||
.is-focused.pagination-next,
|
||||
.is-focused.pagination-link,
|
||||
.is-focused.pagination-dots,
|
||||
.pagination-previous:active,
|
||||
.pagination-next:active,
|
||||
.pagination-link:active,
|
||||
.pagination-dots:active,
|
||||
.is-active.pagination-previous,
|
||||
.is-active.pagination-next,
|
||||
.is-active.pagination-link,
|
||||
.is-active.pagination-dots {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.pagination-previous.disabled,
|
||||
.pagination-next.disabled,
|
||||
.pagination-link.disabled,
|
||||
.pagination-dots.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
/*background-color:azure;*/
|
||||
font-size: 1rem;
|
||||
margin: -0.25rem;
|
||||
}
|
||||
|
||||
.pagination.is-small {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.pagination.is-medium {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.pagination.is-large {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.pagination.is-rounded .pagination-previous,
|
||||
.pagination.is-rounded .pagination-next {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
border-radius: 290486px;
|
||||
}
|
||||
|
||||
.pagination.is-rounded .pagination-link {
|
||||
border-radius: 290486px;
|
||||
}
|
||||
|
||||
/*.pagination,*/
|
||||
.pagination-list {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.pagination-previous,
|
||||
.pagination-next,
|
||||
.pagination-link,
|
||||
.pagination-dots {
|
||||
font-size: 1em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
justify-content: center;
|
||||
margin: 0.25rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pagination-previous,
|
||||
.pagination-next,
|
||||
.pagination-link {
|
||||
border-color: #dbdbdb;
|
||||
color: #363636;
|
||||
min-width: 2.25em;
|
||||
}
|
||||
|
||||
.pagination-previous:hover,
|
||||
.pagination-next:hover,
|
||||
.pagination-link:hover {
|
||||
border-color: #b5b5b5;
|
||||
color: #363636;
|
||||
}
|
||||
|
||||
.pagination-previous:focus,
|
||||
.pagination-next:focus,
|
||||
.pagination-link:focus {
|
||||
border-color: #3273dc;
|
||||
}
|
||||
|
||||
.pagination-previous:active,
|
||||
.pagination-next:active,
|
||||
.pagination-link:active {
|
||||
box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2);
|
||||
}
|
||||
|
||||
.pagination-previous.disabled,
|
||||
.pagination-next.disabled,
|
||||
.pagination-link.disabled {
|
||||
background-color: #dbdbdb;
|
||||
border-color: #dbdbdb;
|
||||
box-shadow: none;
|
||||
color: #7a7a7a;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.pagination-previous,
|
||||
.pagination-next {
|
||||
padding-left: 0.75em;
|
||||
padding-right: 0.75em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pagination-link.is-current {
|
||||
background-color: #3abac4; /*#3273dc;*/
|
||||
border-color: #3abac4;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pagination-dots {
|
||||
color: #b5b5b5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.pagination-list {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.pagination {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.pagination-previous,
|
||||
.pagination-next {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.pagination-list li {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px), print {
|
||||
.pagination-list {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
justify-content: center;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.pagination-previous {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.pagination-next {
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.pagination.is-centered .pagination-previous {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.pagination.is-centered .pagination-list {
|
||||
justify-content: center;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.pagination.is-centered .pagination-next {
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.pagination.is-right .pagination-previous {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.pagination.is-right .pagination-next {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.pagination.is-right .pagination-list {
|
||||
justify-content: flex-end;
|
||||
order: 3;
|
||||
}
|
||||
}
|
||||
</style>
|
51
resources/js/search/search-results/vs-results-class.ts
Normal file
51
resources/js/search/search-results/vs-results-class.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { Component, Vue, Prop, Provide } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class VsResults extends Vue {
|
||||
|
||||
@Prop()
|
||||
data;
|
||||
|
||||
get results() {
|
||||
return this.data;
|
||||
};
|
||||
|
||||
truncate(text, limit) {
|
||||
text = text === undefined ? '' : text;
|
||||
const content = text.split(' ').slice(0, limit);
|
||||
return content.join(' ');
|
||||
};
|
||||
|
||||
error(item) {
|
||||
delete item.thumb;
|
||||
this.$forceUpdate();
|
||||
};
|
||||
|
||||
convert(unixtimestamp: number) {
|
||||
|
||||
// Unixtimestamp
|
||||
// var unixtimestamp = document.getElementById('timestamp').value;
|
||||
// Months array
|
||||
var months_arr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
// Convert timestamp to milliseconds
|
||||
var date = new Date(unixtimestamp * 1000);
|
||||
// Year
|
||||
var year = date.getFullYear();
|
||||
// Month
|
||||
var month = months_arr[date.getMonth()];
|
||||
// Day
|
||||
var day = date.getDate();
|
||||
// Hours
|
||||
var hours = date.getHours();
|
||||
// Minutes
|
||||
var minutes = "0" + date.getMinutes();
|
||||
// Seconds
|
||||
var seconds = "0" + date.getSeconds();
|
||||
// Display date time in MM-dd-yyyy h:m:s format
|
||||
var convdataTime = month + '-' + day + '-' + year + ' ' + hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
|
||||
// document.getElementById('datetime').innerHTML = convdataTime;
|
||||
return convdataTime;
|
||||
};
|
||||
|
||||
|
||||
}
|
63
resources/js/search/search-results/vs-results.vue
Normal file
63
resources/js/search/search-results/vs-results.vue
Normal file
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<!-- <div class="card-columns" >
|
||||
<div class="card" v-for="item in results" :key="item.id">
|
||||
<img v-if="item.thumb" class="card-img-top" :src="item.thumb" :alt="item.title" @error="error(item)">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{item.name}}</h5>
|
||||
<p class="card-text" v-html="truncate(item.description || item.abstract, 50)"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="results">
|
||||
|
||||
<!-- <div class="result-list-info">
|
||||
<div class="resultheader">
|
||||
Your search yielded
|
||||
<strong>{{ results.length }}</strong> results:
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<section class="result-list-container">
|
||||
<div class="row">
|
||||
<ul class="search-items isotope js-isotope u-cf">
|
||||
<li v-for="document in results" :key="document.id" class="six columns post">
|
||||
<div class="search-detail">
|
||||
<div>
|
||||
<a
|
||||
v-bind:href="'dataset/' + document.id"
|
||||
>{{ document.title_output }}</a>
|
||||
</div>
|
||||
{{ convert(document.server_date_published) }}
|
||||
|
||||
<p v-if="document.title_additional && document.title_additional.length > 0">
|
||||
<em>Additional Title:{{ document.title_additional.join(', ') }}</em>
|
||||
</p>
|
||||
|
||||
<div v-if="document.author && document.author.length > 0">
|
||||
<em>Author: {{ document.author.join(', ') }}</em>
|
||||
</div>
|
||||
|
||||
<p class="clamped clamped-2">
|
||||
<span class="text">
|
||||
Abstract: {{ document.abstract_output }}
|
||||
<span class="ellipsis">...</span>
|
||||
<span class="fill"></span>
|
||||
</span>
|
||||
</p>
|
||||
<div class="css-subject" v-if="document.subject && document.subject.length > 0">
|
||||
<div v-for="(item, index) in document.subject" :key="index" class="css-keyword">#{{ item }}</div>
|
||||
<!-- <div class="css-keyword">#graphql</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import VgResults from "./vs-results-class";
|
||||
export default VgResults;
|
||||
</script>
|
||||
|
47
resources/js/search/text-search/vs-input.vue
Normal file
47
resources/js/search/text-search/vs-input.vue
Normal file
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div class="sidebar-simplesearch">
|
||||
<!-- <form method="GET" action="//repository.geologie.ac.at/search" accept-charset="UTF-8"> -->
|
||||
<div>
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="Enter your search term..."
|
||||
name="q"
|
||||
type="text"
|
||||
v-model="term" v-on:keyup.enter="search()"
|
||||
/>
|
||||
|
||||
<!-- <button @click="search()" class="css-1gklxk5 ekqohx90"> -->
|
||||
<button class="css-1gklxk5 ekqohx90">
|
||||
<svg
|
||||
alt="Search"
|
||||
@click="search()"
|
||||
class="search-icon"
|
||||
height="14"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<title>Search</title>
|
||||
<path
|
||||
d=" M6.02945,10.20327a4.17382,4.17382,0,1,1,4.17382-4.17382A4.15609,4.15609, 0,0,1,6.02945,10.20327Zm9.69195,4.2199L10.8989,9.59979A5.88021,5.88021, 0,0,0,12.058,6.02856,6.00467,6.00467,0,1,0,9.59979,10.8989l4.82338, 4.82338a.89729.89729,0,0,0,1.29912,0,.89749.89749,0,0,0-.00087-1.29909Z "
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script lange="ts">
|
||||
import Vue from "vue";
|
||||
import { Component, Provide } from "vue-property-decorator";
|
||||
|
||||
@Component({})
|
||||
export default class VsInput extends Vue {
|
||||
term = "";
|
||||
bar = "bar";
|
||||
search() {
|
||||
//console.log(this.term);
|
||||
this.$emit("search", this.term);
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue