- 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
22
resources/js/app.js
Normal file
22
resources/js/app.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
/**
|
||||
* First we will load all of this project's JavaScript dependencies which
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
|
||||
require('./bootstrap');
|
||||
|
||||
window.Vue = require('vue');
|
||||
|
||||
/**
|
||||
* Next, we will create a fresh Vue application instance and attach it to
|
||||
* the page. Then, you may begin adding components to this application
|
||||
* or customize the JavaScript scaffolding to fit your unique needs.
|
||||
*/
|
||||
|
||||
Vue.component('my-vuetable', require('./components/MyVuetable.vue'));
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app'
|
||||
});
|
32
resources/js/approveDataset.js
Normal file
32
resources/js/approveDataset.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
// releaseDataset.js
|
||||
import Vue from 'vue';
|
||||
import VeeValidate from 'vee-validate';
|
||||
Vue.use(VeeValidate);
|
||||
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app1',
|
||||
data() {
|
||||
return {
|
||||
dataset: {
|
||||
firstName: '',
|
||||
reviewer_id: ''
|
||||
},
|
||||
submitted: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkForm(e) {
|
||||
// Log entire model to console
|
||||
// console.log(this.dataset);
|
||||
this.submitted = true;
|
||||
this.$validator.validate().then(result => {
|
||||
if (result) {
|
||||
console.log('From Submitted!');
|
||||
document.getElementById("approveForm").submit();
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
29
resources/js/bootstrap.js
vendored
Normal file
29
resources/js/bootstrap.js
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
window._ = require('lodash');
|
||||
|
||||
/**
|
||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||
* to our Laravel back-end. This library automatically handles sending the
|
||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||
*/
|
||||
try {
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
// require('bootstrap-sass');
|
||||
} catch (e) {}
|
||||
|
||||
window.axios = require('axios');
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Next we will register the CSRF Token as a common header with Axios so that
|
||||
* all outgoing HTTP requests automatically have it attached. This is just
|
||||
* a simple convenience so we don't have to attach every token manually.
|
||||
*/
|
||||
|
||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
if (token) {
|
||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
||||
}
|
||||
else {
|
||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
||||
}
|
37
resources/js/ckeditor.js
vendored
Normal file
37
resources/js/ckeditor.js
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// import Vue from 'vue';
|
||||
// import CKEditor from '@ckeditor/ckeditor5-vue';
|
||||
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
|
||||
// import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
|
||||
|
||||
// const app = new Vue({
|
||||
// name: 'app',
|
||||
// components: {
|
||||
// // Use the <ckeditor> component in this view.
|
||||
// ckeditor: CKEditor.component
|
||||
// },
|
||||
// props: ['desc_markup'],
|
||||
// data() {
|
||||
// return {
|
||||
// editor: ClassicEditor,
|
||||
// //desc_markup: '<p>Content of the editor.</p>',
|
||||
// editorConfig: {
|
||||
// // The configuration of the editor.
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// });
|
||||
var allEditors = document.querySelectorAll('.ckeditor');
|
||||
|
||||
for (var i = 0; i < allEditors.length; ++i) {
|
||||
ClassicEditor
|
||||
.create(allEditors[i], {
|
||||
|
||||
toolbar: ['heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote']
|
||||
})
|
||||
.then(editor => {
|
||||
console.log(editor);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
38
resources/js/components/CustomActions.vue
Normal file
38
resources/js/components/CustomActions.vue
Normal file
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div class="custom-actions">
|
||||
<button class="view" @click="itemAction('view-item', rowData, rowIndex)">
|
||||
</button>
|
||||
<a class="edit" @click="itemAction('edit-item', rowData, rowIndex)">
|
||||
</a>
|
||||
<a class="delete" @click="itemAction('delete-item', rowData, rowIndex)">
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
rowData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
rowIndex: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemAction(action, data, index) {
|
||||
console.log("custom-actions: " + action, data.full_name, index);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.custom-actions button.ui.button {
|
||||
padding: 8px 8px;
|
||||
}
|
||||
.custom-actions button.ui.button > i.icon {
|
||||
margin: auto !important;
|
||||
}
|
||||
</style>
|
87
resources/js/components/Dataset.vue
Normal file
87
resources/js/components/Dataset.vue
Normal file
|
@ -0,0 +1,87 @@
|
|||
// <script>
|
||||
import Vue from "vue";
|
||||
|
||||
//outside of the component:
|
||||
function initialState() {
|
||||
return {
|
||||
type: "",
|
||||
state: "",
|
||||
rights: null,
|
||||
project_id: "",
|
||||
|
||||
creating_corporation: "GBA Repository",
|
||||
language: "",
|
||||
embargo_date: "",
|
||||
belongs_to_bibliography: 0,
|
||||
|
||||
title_main: {
|
||||
value: "",
|
||||
language: ""
|
||||
},
|
||||
abstract_main: {
|
||||
value: "",
|
||||
language: ""
|
||||
},
|
||||
// geolocation: {
|
||||
// xmin: "",
|
||||
// ymin: "",
|
||||
// xmax: "",
|
||||
// ymax: ""
|
||||
// },
|
||||
coverage: {
|
||||
xmin: "",
|
||||
ymin: "",
|
||||
xmax: "",
|
||||
ymax: "",
|
||||
elevation_min: "",
|
||||
elevation_max: "",
|
||||
elevation_absolut: "",
|
||||
depth_min: "",
|
||||
depth_max: "",
|
||||
depth_absolut: "",
|
||||
time_min: "",
|
||||
time_max: "",
|
||||
time_absolut: ""
|
||||
},
|
||||
checkedAuthors: [],
|
||||
checkedLicenses: [], // [],
|
||||
files: [],
|
||||
keywords: [],
|
||||
references: [],
|
||||
titles: [],
|
||||
descriptions: [],
|
||||
checkedContributors: [],
|
||||
// checkedSubmitters: [],
|
||||
|
||||
persons: [],
|
||||
contributors: []
|
||||
// submitters: []
|
||||
};
|
||||
}
|
||||
|
||||
const dataset = new Vue({
|
||||
data: function() {
|
||||
return initialState();
|
||||
},
|
||||
created: function() {
|
||||
// let json = JSON.stringify(this.$data);
|
||||
// this.reset = () => {
|
||||
// Object.assign(this.$data, JSON.parse(json));
|
||||
// };
|
||||
// this.reset(json);
|
||||
},
|
||||
watch: {
|
||||
language(val) {
|
||||
this.title_main.language = val;
|
||||
this.abstract_main.language = val;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
Object.assign(this.$data, initialState());
|
||||
}
|
||||
}
|
||||
});
|
||||
export default dataset;
|
||||
//export { dataset };
|
||||
</script>
|
287
resources/js/components/LocationsMap.vue
Normal file
287
resources/js/components/LocationsMap.vue
Normal file
|
@ -0,0 +1,287 @@
|
|||
<template>
|
||||
<div style="position:relative">
|
||||
<!-- <div id="inset">
|
||||
xmin:
|
||||
<input
|
||||
type="text"
|
||||
name="xmin"
|
||||
id="xmin"
|
||||
v-model="geolocation.xmin"
|
||||
data-vv-scope="step-2"
|
||||
v-validate="'decimal'"
|
||||
>
|
||||
<br>ymin:
|
||||
<input
|
||||
type="text"
|
||||
name="ymin"
|
||||
id="ymin"
|
||||
v-model="geolocation.ymin"
|
||||
data-vv-scope="step-2"
|
||||
>
|
||||
xmax:
|
||||
<input
|
||||
type="text"
|
||||
name="xmax"
|
||||
id="xmax"
|
||||
v-model="geolocation.xmax"
|
||||
data-vv-scope="step-2"
|
||||
>
|
||||
<br>ymax:
|
||||
<input
|
||||
type="text"
|
||||
name="ymax"
|
||||
id="ymax"
|
||||
v-model="geolocation.ymax"
|
||||
data-vv-scope="step-2"
|
||||
>
|
||||
<input type="button" v-on:click="zoomTo" value="zoomTo">
|
||||
</div>-->
|
||||
<div id="map"></div>
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-u-md-1-2 pure-div">
|
||||
<label for="xmin">xmin:</label>
|
||||
<input
|
||||
name="xmin"
|
||||
type="text"
|
||||
class="pure-u-23-24"
|
||||
v-model="geolocation.xmin"
|
||||
data-vv-scope="step-2"
|
||||
id="xmin"
|
||||
v-validate="'decimal'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1 pure-u-md-1-2 pure-div">
|
||||
<label for="ymin">ymin:</label>
|
||||
<input
|
||||
name="ymin"
|
||||
type="text"
|
||||
class="pure-u-23-24"
|
||||
v-model="geolocation.ymin"
|
||||
data-vv-scope="step-2"
|
||||
id="ymin"
|
||||
v-validate="'decimal'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1 pure-u-md-1-2 pure-div">
|
||||
<label for="xmax">xmax:</label>
|
||||
<input
|
||||
name="xmax"
|
||||
type="text"
|
||||
class="pure-u-23-24"
|
||||
v-model="geolocation.xmax"
|
||||
data-vv-scope="step-2"
|
||||
id="xmax"
|
||||
v-validate="'decimal'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1 pure-u-md-1-2 pure-div">
|
||||
<label for="ymax">ymax:</label>
|
||||
<input
|
||||
name="ymax"
|
||||
type="text"
|
||||
class="pure-u-23-24"
|
||||
v-model="geolocation.ymax"
|
||||
data-vv-scope="step-2"
|
||||
id="ymax"
|
||||
v-validate="'decimal'"
|
||||
/>
|
||||
</div>
|
||||
<input type="button" v-on:click="zoomTo" value="validate coordinates" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import "leaflet";
|
||||
import * as L from "leaflet";
|
||||
import "leaflet-draw";
|
||||
|
||||
//const L = window.L;
|
||||
export default {
|
||||
inject: {
|
||||
$validator: "$validator"
|
||||
},
|
||||
props: {
|
||||
geolocation: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
map: [],
|
||||
drawnItems: null,
|
||||
locationErrors: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$validator.extend("boundingBox", {
|
||||
getMessage: field => "At least one " + field + " needs to be checked.",
|
||||
validate: (value, [testProp]) => {
|
||||
const options = this.dataset.checkedLicenses;
|
||||
return value || options.some(option => option[testProp]);
|
||||
}
|
||||
});
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
methods: {
|
||||
zoomTo() {
|
||||
var _this = this;
|
||||
_this.locationErrors.length = 0;
|
||||
this.drawnItems.clearLayers();
|
||||
var xmin = document.getElementById("xmin").value;
|
||||
var ymin = document.getElementById("ymin").value;
|
||||
var xmax = document.getElementById("xmax").value;
|
||||
var ymax = document.getElementById("ymax").value;
|
||||
var bounds = [[ymin, xmin], [ymax, xmax]];
|
||||
try {
|
||||
var boundingBox = L.rectangle(bounds, { color: "#005F6A", weight: 1 });
|
||||
// this.geolocation.xmin = xmin;
|
||||
// this.geolocation.ymin = ymin;
|
||||
// this.geolocation.xmax = xmax;
|
||||
// this.geolocation.ymax = ymax;
|
||||
|
||||
_this.drawnItems.addLayer(boundingBox);
|
||||
_this.map.fitBounds(bounds);
|
||||
_this.$toast.success("valid bounding box");
|
||||
} catch (e) {
|
||||
// _this.errors.push(e);
|
||||
_this.$toast.error(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const map = L.map("map");
|
||||
this.map = map;
|
||||
map.scrollWheelZoom.disable();
|
||||
// Construct a bounding box for this map that the user cannot
|
||||
var southWest = L.latLng(46.5, 9.9),
|
||||
northEast = L.latLng(48.9, 16.9),
|
||||
bounds = L.latLngBounds(southWest, northEast);
|
||||
// zoom the map to that bounding box
|
||||
// map.fitBounds(bounds);
|
||||
|
||||
var southWest1 = L.latLng(46.35877, 8.782379); //lowerCorner
|
||||
var northEast1 = L.latLng(49.037872, 17.189532); //upperCorner
|
||||
var layerBounds = L.latLngBounds(southWest1, northEast1);
|
||||
// var attribution = "www.basemap.at";
|
||||
// var basemap_0 = L.tileLayer(
|
||||
// "https://{s}.wien.gv.at/basemap/bmapgrau/normal/google3857/{z}/{y}/{x}.png",
|
||||
// {
|
||||
// attribution: attribution,
|
||||
// subdomains: ["maps", "maps1", "maps2", "maps3"],
|
||||
// continuousWorld: false,
|
||||
// detectRetina: false,
|
||||
// bounds: layerBounds
|
||||
// }
|
||||
// );
|
||||
//basemap_0.addTo(map);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
'© <a target="_blank" href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(this.map);
|
||||
|
||||
map.fitBounds(bounds);
|
||||
|
||||
this.map = map;
|
||||
// this.addPlaces(this.places)
|
||||
|
||||
// Initialise the FeatureGroup to store editable layers
|
||||
var drawnItems = (this.drawnItems = new L.FeatureGroup());
|
||||
map.addLayer(drawnItems);
|
||||
var drawPluginOptions = {
|
||||
position: "topright",
|
||||
draw: {
|
||||
polygon: false,
|
||||
// disable toolbar item by setting it to false
|
||||
polyline: false,
|
||||
circle: false,
|
||||
circlemarker: false,
|
||||
rectangle: {
|
||||
shapeOptions: {
|
||||
clickable: true,
|
||||
color: "#005F6A"
|
||||
}
|
||||
},
|
||||
marker: false
|
||||
},
|
||||
edit: {
|
||||
featureGroup: drawnItems, //REQUIRED!!
|
||||
remove: false
|
||||
}
|
||||
};
|
||||
|
||||
// Initialise the draw control and pass it the FeatureGroup of editable layers
|
||||
var drawControl = new L.Control.Draw(drawPluginOptions);
|
||||
map.addControl(drawControl);
|
||||
|
||||
map.on(
|
||||
L.Draw.Event.CREATED,
|
||||
function(event) {
|
||||
drawnItems.clearLayers();
|
||||
var type = event.layerType;
|
||||
var layer = event.layer;
|
||||
|
||||
// if (type === "rectancle") {
|
||||
// layer.bindPopup("A popup!" + layer.getBounds().toBBoxString());
|
||||
var bounds = layer.getBounds();
|
||||
this.geolocation.xmin = bounds.getSouthWest().lng;
|
||||
this.geolocation.ymin = bounds.getSouthWest().lat;
|
||||
// console.log(this.geolocation.xmin);
|
||||
this.geolocation.xmax = bounds.getNorthEast().lng;
|
||||
this.geolocation.ymax = bounds.getNorthEast().lat;
|
||||
// }
|
||||
|
||||
drawnItems.addLayer(layer);
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
map.on(
|
||||
L.Draw.Event.EDITED,
|
||||
function(event) {
|
||||
var layers = event.layers.getLayers();
|
||||
var layer = layers[0];
|
||||
|
||||
var bounds = layer.getBounds();
|
||||
this.geolocation.xmin = bounds.getSouthWest().lng;
|
||||
this.geolocation.ymin = bounds.getSouthWest().lat;
|
||||
// console.log(this.geolocation.xmin);
|
||||
this.geolocation.xmax = bounds.getNorthEast().lng;
|
||||
this.geolocation.ymax = bounds.getNorthEast().lat;
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
// https://github.com/vuejs-templates/webpack/issues/121
|
||||
// npm install node-sass sass-loader --save-dev
|
||||
<style lang="scss">
|
||||
// Import CSS from Leaflet and plugins.
|
||||
@import "~leaflet/dist/leaflet.css";
|
||||
@import "~leaflet-draw/dist/leaflet.draw.css";
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
text-shadow: 0 0 2px #fff;
|
||||
}
|
||||
|
||||
#inset {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border: none;
|
||||
width: 120px;
|
||||
z-index: 999;
|
||||
// height: 120px;
|
||||
}
|
||||
</style>
|
176
resources/js/components/MyAutocomplete.vue
Normal file
176
resources/js/components/MyAutocomplete.vue
Normal file
|
@ -0,0 +1,176 @@
|
|||
<!-- https://pineco.de/instant-ajax-search-laravel-vue/
|
||||
https://alligator.io/vuejs/vue-autocomplete-component/ -->
|
||||
<template>
|
||||
<div style="position:relative">
|
||||
<input type="search" @input="searchChanged" v-model="search" v-bind:readonly="isLoading == true" v-bind:title="title" v-bind:placeholder="title"
|
||||
class="pure-u-23-24" v-on:keydown.down="onArrowDown" v-on:keydown.up="onArrowUp" v-on:keydown.enter="onEnter">
|
||||
<!-- <ul class="autocomplete-results" v-show="results.length > 0"> -->
|
||||
<ul class="autocomplete-results pure-u-23-24" v-show="isOpen">
|
||||
<li class="loading" v-if="isLoading" >Loading results...</li>
|
||||
|
||||
<li
|
||||
v-else
|
||||
v-for="(suggestion, i) in results"
|
||||
:key="i"
|
||||
@click="setResult(suggestion)"
|
||||
class="autocomplete-result"
|
||||
:class="{ 'is-active': i === arrowCounter }"
|
||||
>
|
||||
<strong>{{ suggestion.full_name }}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash';
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
//data from parent component
|
||||
props: {
|
||||
title: String
|
||||
// items: {
|
||||
// type: Array,
|
||||
// required: false,
|
||||
// default: () => []
|
||||
// },
|
||||
// isAsync: {
|
||||
// type: Boolean,
|
||||
// required: false,
|
||||
// default: false
|
||||
// }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: null,
|
||||
results: [],
|
||||
isOpen: false,
|
||||
isLoading: false,
|
||||
isAsync: true,
|
||||
items: [],
|
||||
arrowCounter: -1
|
||||
};
|
||||
},
|
||||
|
||||
// watch: {
|
||||
// search(after, before) {
|
||||
// this.isOpen = true;
|
||||
// this.filterResults();
|
||||
// }
|
||||
// },
|
||||
|
||||
watch: {
|
||||
// Once the items content changes, it means the parent component
|
||||
// provided the needed data
|
||||
items: function(value, oldValue) {
|
||||
// we want to make sure we only do this when it's an async request
|
||||
if (this.isAsync) {
|
||||
this.results = value;
|
||||
this.isOpen = true;
|
||||
this.isLoading = false;
|
||||
} else {
|
||||
if (value.length !== oldValue.length) {
|
||||
this.results = value;
|
||||
this.isLoading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setResult(person) {
|
||||
// this.search = person.full_name;
|
||||
this.reset();
|
||||
this.$emit("person", person);
|
||||
},
|
||||
reset() {
|
||||
this.search = "";
|
||||
this.results = [];
|
||||
this.isOpen = false;
|
||||
},
|
||||
searchChanged() {
|
||||
// Let's warn the parent that a change was made
|
||||
this.$emit("input", this.search);
|
||||
|
||||
if (this.search.length >= 2) {
|
||||
// Is the data given by an outside ajax request?
|
||||
if (this.isAsync) {
|
||||
this.isLoading = true;
|
||||
this.filterResults();
|
||||
} else {
|
||||
// Data is sync, we can search our flat array
|
||||
this.results = this.items.filter(item => {
|
||||
return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
|
||||
});
|
||||
this.isOpen = true;
|
||||
}
|
||||
} else {
|
||||
this.items = [];
|
||||
}
|
||||
},
|
||||
filterResults: _.debounce(function() {
|
||||
var self = this;
|
||||
axios
|
||||
.get("/api/persons", { params: { filter: this.search.toLowerCase() } })
|
||||
.then(function(response) {
|
||||
return (self.items = response.data.data);
|
||||
})
|
||||
.catch(function(error) {
|
||||
alert(error);
|
||||
});
|
||||
// this.results = this.items.filter(item => {
|
||||
// return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
|
||||
// });
|
||||
}, 300),
|
||||
onArrowDown() {
|
||||
if (this.arrowCounter < this.results.length - 1) {
|
||||
this.arrowCounter = this.arrowCounter + 1;
|
||||
}
|
||||
},
|
||||
onArrowUp() {
|
||||
if (this.arrowCounter > 0) {
|
||||
this.arrowCounter = this.arrowCounter - 1;
|
||||
}
|
||||
},
|
||||
onEnter() {
|
||||
if(Array.isArray(this.results) && this.results.length && this.arrowCounter !== -1 && this.arrowCounter < this.results.length){
|
||||
//this.search = this.results[this.arrowCounter];
|
||||
var person = this.results[this.arrowCounter];
|
||||
this.$emit("person", person);
|
||||
//this.isOpen = false;
|
||||
this.reset();
|
||||
this.arrowCounter = -1;
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// isOpen() {
|
||||
// return this.results.length > 0;
|
||||
// }
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.autocomplete-results {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 1px solid #eeeeee;
|
||||
height: 120px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.autocomplete-result {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
padding: 4px 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.autocomplete-result.is-active,
|
||||
.autocomplete-result:hover {
|
||||
background-color: #4aae9b;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
107
resources/js/components/MyVuetable.vue
Normal file
107
resources/js/components/MyVuetable.vue
Normal file
|
@ -0,0 +1,107 @@
|
|||
// MyVuetable.vue
|
||||
<!-- :fields="['name', 'email', 'birthdate']" -->
|
||||
// "https://vuetable.ratiw.net/api/users"
|
||||
<template>
|
||||
<vuetable ref="vuetable"
|
||||
api-url="/api/persons"
|
||||
v-bind:fields="fields" pagination-path=""
|
||||
v-bind:css="css.table"
|
||||
></vuetable>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vuetable from "vuetable-2/src/components/Vuetable";
|
||||
import VuetablePagination from 'vuetable-2/src/components/VuetablePagination'
|
||||
import VuetablePaginationInfo from 'vuetable-2/src/components/VuetablePaginationInfo'
|
||||
import CustomActions from './CustomActions'
|
||||
|
||||
Vue.component('custom-actions', CustomActions)
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Vuetable,
|
||||
VuetablePagination,
|
||||
VuetablePaginationInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fields: [
|
||||
{
|
||||
name: "full_name",
|
||||
// sortField: "full_name"
|
||||
},
|
||||
{
|
||||
name: "email",
|
||||
sortField: "email"
|
||||
},
|
||||
{
|
||||
name: "date_of_birth",
|
||||
sortField: "date_of_birth",
|
||||
// titleClass: "text-center",
|
||||
// dataClass: "text-center",
|
||||
// callback: "formatDate|DD-MM-YYYY"
|
||||
},
|
||||
{
|
||||
name: "__component:custom-actions",
|
||||
title: "Actions",
|
||||
// titleClass: "text-center",
|
||||
// dataClass: "text-center"
|
||||
}
|
||||
],
|
||||
css: {
|
||||
table: {
|
||||
tableClass: "table pure-table pure-table-horizontal",
|
||||
ascendingIcon: "glyphicon glyphicon-chevron-up",
|
||||
descendingIcon: "glyphicon glyphicon-chevron-down"
|
||||
},
|
||||
icons: {
|
||||
first: "glyphicon glyphicon-step-backward",
|
||||
prev: "glyphicon glyphicon-chevron-left",
|
||||
next: "glyphicon glyphicon-chevron-right",
|
||||
last: "glyphicon glyphicon-step-forward"
|
||||
}
|
||||
},
|
||||
sortOrder: [{ field: "email", sortField: "email", direction: "asc" }],
|
||||
moreParams: {}
|
||||
};
|
||||
}//data end
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pagination {
|
||||
margin: 0;
|
||||
float: right;
|
||||
}
|
||||
.pagination a.page {
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 10px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.page.active {
|
||||
color: white;
|
||||
background-color: #337ab7;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 10px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.btn-nav {
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 7px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.pagination a.btn-nav.disabled {
|
||||
color: lightgray;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 3px;
|
||||
padding: 5px 7px;
|
||||
margin-right: 2px;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.pagination-info {
|
||||
float: left;
|
||||
}
|
||||
</style>
|
132
resources/js/components/PersonTable.vue
Normal file
132
resources/js/components/PersonTable.vue
Normal file
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<div>
|
||||
<h3 v-if="heading && personlist.length">{{ heading }}</h3>
|
||||
<table class="pure-table pure-table-horizontal" v-if="personlist.length">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">First Name</th>
|
||||
<th scope="col">Last Name</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">Orcid</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<draggable v-bind:list="personlist" tag="tbody" v-on:start="isDragging=true" v-on:end="isDragging=false">
|
||||
<tr
|
||||
v-for="(item, index) in personlist"
|
||||
v-bind:key="item.id"
|
||||
v-bind:class="[item.status==1 ? 'activeClass' : 'inactiveClass']"
|
||||
>
|
||||
<td scope="row">{{ index + 1 }}</td>
|
||||
<td>
|
||||
<input
|
||||
name="first_name"
|
||||
class="form-control"
|
||||
placeholder="[FIRST NAME]"
|
||||
v-model="item.first_name"
|
||||
v-bind:readonly="item.status==1"
|
||||
v-validate="'required'"
|
||||
data-vv-scope="step-1"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
name="last_name"
|
||||
class="form-control"
|
||||
placeholder="[LAST NAME]"
|
||||
v-model="item.last_name"
|
||||
v-bind:readonly="item.status==1"
|
||||
v-validate="'required'"
|
||||
data-vv-scope="step-1"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
name="email"
|
||||
class="form-control"
|
||||
placeholder="[EMAIL]"
|
||||
v-model="item.email"
|
||||
v-validate="'required|email'"
|
||||
v-bind:readonly="item.status==1"
|
||||
data-vv-scope="step-1"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
name="identifier_orcid"
|
||||
class="form-control"
|
||||
placeholder="[ORCID optional]"
|
||||
v-model="item.identifier_orcid"
|
||||
v-bind:readonly="item.status==1"
|
||||
data-vv-scope="step-1"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<button class="pure-button button-small is-warning" @click.prevent="removeAuthor(index)"> <i class="fa fa-trash"></i> </button>
|
||||
</td>
|
||||
</tr>
|
||||
</draggable>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from "vuedraggable";
|
||||
export default {
|
||||
inject: {
|
||||
$validator: "$validator"
|
||||
},
|
||||
name: "person-table",
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// list: [
|
||||
// { id: 1, name: "Abby", sport: "basket" },
|
||||
// { id: 2, name: "Brooke", sport: "foot" },
|
||||
// { id: 3, name: "Courtenay", sport: "volley" },
|
||||
// { id: 4, name: "David", sport: "rugby" }
|
||||
// ],
|
||||
editable: true,
|
||||
isDragging: false,
|
||||
delayedDragging: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
personlist: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
rowIndex: {
|
||||
type: Number
|
||||
},
|
||||
heading: String
|
||||
},
|
||||
methods: {
|
||||
itemAction(action, data, index) {
|
||||
console.log("custom-actions: " + action, data.full_name, index);
|
||||
},
|
||||
removeAuthor(key) {
|
||||
this.personlist.splice(key, 1);
|
||||
},
|
||||
onMove({ relatedContext, draggedContext }) {
|
||||
const relatedElement = relatedContext.element;
|
||||
const draggedElement = draggedContext.element;
|
||||
return (
|
||||
(!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.custom-actions button.ui.button {
|
||||
padding: 8px 8px;
|
||||
}
|
||||
.custom-actions button.ui.button > i.icon {
|
||||
margin: auto !important;
|
||||
}
|
||||
</style>
|
222
resources/js/components/ShowModal.vue
Normal file
222
resources/js/components/ShowModal.vue
Normal file
|
@ -0,0 +1,222 @@
|
|||
// https://alligator.io/vuejs/vue-modal-component/
|
||||
<template>
|
||||
<div class="modal-backdrop">
|
||||
<div class="popup">
|
||||
<div class="fm_overlay" >
|
||||
<header class="popupbar">
|
||||
<slot name="header">
|
||||
<b class="popuptitle">Help</b>
|
||||
</slot>
|
||||
<button class="btn-close" @click="close">x</button>
|
||||
</header>
|
||||
<section class="pageinfo">
|
||||
<slot name="body">I'm the default body!</slot>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "modal",
|
||||
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit("close");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.popup_close {
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH3AgBFSI5w7714wAAAYlJREFUSMfd1c9KFWEYBvCfJz15NI8RoRnpLohuILyMll1CG0taibhqERkJQWFBixbZpkSwlRs3kdfhBYgaBHU4h8bNGwzTfDNzIgh8YWBmeL7n/TPP8w7/MUb+BbaVeD+NO+g0IG9hEVeaVtPFGjK8wIUa/KPAvsVsHfk0VuNAhh420E7gl/Eth39TlWQsV02GX7kkzzBeGMtDnOawv/GbqdF28A79kkM/8CSSjGAJxyW4DPsxidJoR5uDksM/8TgqP0qQf8bluu/QwetEJ4PcfZF8B1ebKmkSLxNJyp4/YWZYo3VDpt9zRMWrjw+Y+1s3X8dBRYJD3K5zYSpGcRfzNV3ew8SwlbfwoEKKRXU9LfikNpZwkiAvS9LDenRdG8sV5Fsh4V6ik+dVY29jJbdbiuQfcQ1TIeFBopNXIfM/4mLIsox8uyDFbhCV+WQPl1JdLOB9YdY7CRNNxmLr57BfQraVP6sbMesMuzX2H4/dleErbjVV0QLuN3ToREj65rBeGB0CO+bcxhlxQrBXIUNRlQAAAABJRU5ErkJggg==")
|
||||
/*icons/close.png*/ no-repeat;
|
||||
}
|
||||
/* anything but phone */
|
||||
@media all and (min-width: 768px) {
|
||||
.popup_close {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
/*margin: 5px;*/
|
||||
background-size: 20px 20px;
|
||||
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
z-index: 800;
|
||||
}
|
||||
|
||||
.fm_overlay {
|
||||
top: 10em;
|
||||
left: 30%;
|
||||
max-width: 480px;
|
||||
min-width: 300px;
|
||||
/*max-height: 90%;*/
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* only phone - bigger buttons */
|
||||
@media all and (max-width: 767px) {
|
||||
.popup_close {
|
||||
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH3AcXFyot5RvgagAAAbdJREFUaN7t2DFOAkEUxvE/6AFMUBMoIDExHsMDqJVgZ+KJKIyFBSjGxCN4DbUSC6XRys5GZDXYMAkh7rLz5s0smPmSLXnDj2Hhm4WYmJiYlFSAG2DTw+wS0AZ2fSOqQB8YA09ATXF2GbiczB4CeyEQY2VMGbiYmT0E9kMgtDB/IbxgahkIV0wWQhWTByHF5EGY68sFY4OwxdggpjEHEsit5ULmegDW5/zEnglnfwAbtpA68CxcsJ+yM2WgK5w5Ag6lXy9NjCui6XrD14EXB0x1ERAm28Cr8I3cA+fC134Dx9p/ii47I7kSzZ0oCuMVEQoTBGHS8IQJivCFKQShjUmAVtEnxgYwWHaE6U7XDpCBpD9pR9JibbpZMERX8WYvBKONKATjCzFbNJcaEQQTCuEVUwJOHar4u8MRoLIIO2Fqh8bhzBnRUepOhWE0ERqYRymmLVzwBzjJmLsDvAln3wFrtpDW5JP1UQClrfkKWJHsig3GtsXaYnpShEkzB0ZaxfMeAXqTe9Y5WZgEOPJ4nlFDZGFcEfMw6ohpzEgZkYbxhpjGfCojZjHeESZbnp8BrBITExPzr/MLneElMzKD908AAAAASUVORK5CYII=")
|
||||
/*mobile_icons/close.png*/ no-repeat;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
background-size: 25px 25px;
|
||||
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
z-index: 800;
|
||||
}
|
||||
|
||||
.fm_overlay {
|
||||
bottom: 4em;
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
|
||||
max-height: 70%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/*.touch .fm_basemap_list{ max-height: 80%; overflow-y: auto;}*/
|
||||
}
|
||||
|
||||
.popup .fm_overlay {
|
||||
position: fixed;
|
||||
width: 300px;
|
||||
|
||||
left: 50%;
|
||||
margin-left: -150px;
|
||||
top: 50%;
|
||||
margin-top: -150px;
|
||||
|
||||
z-index: 9999;
|
||||
padding: 10px;
|
||||
|
||||
border-radius: 1px;
|
||||
box-shadow: 0 0 0 10px rgba(34, 34, 34, 0.6);
|
||||
}
|
||||
|
||||
.popupbar {
|
||||
background: dimgray;
|
||||
/* color: white; */
|
||||
padding-left: 4px;
|
||||
height: 25px;
|
||||
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
color: #4aae9b;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.popup_close {
|
||||
color: rgb(220, 220, 220);
|
||||
/*background: gray;*/
|
||||
border: 1px solid darkgray;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
text-align: center;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
.fm_overlay {
|
||||
background-color: white;
|
||||
padding: 2px 5px 2px;
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pageinfo {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.pageinfo h1 {
|
||||
background-color: gray;
|
||||
color: white;
|
||||
font-size: small;
|
||||
font-weight: normal;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 3px;
|
||||
padding: 1px;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.license {
|
||||
font-size: xx-small;
|
||||
}
|
||||
|
||||
.star {
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal {
|
||||
background: #ffffff;
|
||||
box-shadow: 2px 2px 20px 1px;
|
||||
overflow-x: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-header,
|
||||
.modal-footer {
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
color: #4aae9b;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
border-top: 1px solid #eeeeee;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
position: relative;
|
||||
padding: 20px 10px;
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #4aae9b;
|
||||
background: transparent;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-green {
|
||||
color: white;
|
||||
background: #4aae9b;
|
||||
border: 1px solid #4aae9b;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
574
resources/js/datasetPublish.js
Normal file
574
resources/js/datasetPublish.js
Normal file
|
@ -0,0 +1,574 @@
|
|||
/**
|
||||
* First we will load all of this project's JavaScript dependencies which
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
// window.axios = require('axios');
|
||||
// window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Next we will register the CSRF Token as a common header with Axios so that
|
||||
* all outgoing HTTP requests automatically have it attached. This is just
|
||||
* a simple convenience so we don't have to attach every token manually.
|
||||
*/
|
||||
// let token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
// if (token) {
|
||||
// window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
||||
// }
|
||||
// else {
|
||||
// console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
||||
// }
|
||||
// window._ = require('lodash');
|
||||
// window.Vue = require('vue');
|
||||
// Vue.prototype.$http = axios;
|
||||
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
|
||||
// Vue.component('example', require('./components/Example.vue'));
|
||||
//Vue.component('my-autocomplete', require('./components/MyAutocomplete.vue'));
|
||||
import MyAutocomplete from './components/MyAutocomplete.vue';
|
||||
import messagesEN from './strings/messages/en.js';
|
||||
import VeeValidate from 'vee-validate';
|
||||
import dataset from './components/Dataset';
|
||||
import LocationsMap from './components/LocationsMap.vue';
|
||||
import PersonTable from './components/PersonTable.vue';
|
||||
import modal from './components/ShowModal.vue';
|
||||
// import datetime from 'vuejs-datetimepicker';
|
||||
// import { Validator } from 'vee-validate';
|
||||
import VueToast from 'vue-toast-notification';
|
||||
import 'vue-toast-notification/dist/index.css';
|
||||
Vue.use(VueToast);
|
||||
|
||||
const dict = {
|
||||
custom: {
|
||||
keyword_list: {
|
||||
keywords_length: 'Minimum 3 keywords are required'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Vue.use(VeeValidate);
|
||||
Vue.use(VeeValidate, {
|
||||
// validity: true
|
||||
locale: 'en',
|
||||
useConstraintAttrs: true,
|
||||
dictionary: {
|
||||
en: { messages: messagesEN }
|
||||
}
|
||||
});
|
||||
|
||||
const STATUS_INITIAL = 0, STATUS_SAVING = 1, STATUS_SUCCESS = 2, STATUS_FAILED = 3;
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
components: { MyAutocomplete, LocationsMap, modal, PersonTable },
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{ id: 1, name: "Abby", sport: "basket" },
|
||||
{ id: 2, name: "Brooke", sport: "foot" },
|
||||
{ id: 3, name: "Courtenay", sport: "volley" },
|
||||
{ id: 4, name: "David", sport: "rugby" }
|
||||
],
|
||||
dragging: true,
|
||||
rows: [
|
||||
//initial data
|
||||
// { qty: 5, value: "Something", language: 10, type: "additional", sort_order: 0 },
|
||||
// { qty: 2, value: "Something else", language: 20, type: "additional", sort_order: 0 },
|
||||
],
|
||||
serrors: [],
|
||||
|
||||
uploadedFiles: [],
|
||||
uploadError: null,
|
||||
currentStatus: null,
|
||||
uploadFieldName: 'photos',
|
||||
fileCount: 0,
|
||||
releaseLink: null,
|
||||
deleteLink: null,
|
||||
|
||||
isModalVisible: false,
|
||||
|
||||
step: 0,
|
||||
dataset: dataset,
|
||||
elevation: "no_elevation",
|
||||
depth: "no_depth",
|
||||
time: "no_time",
|
||||
// dataset: {
|
||||
// type: '',
|
||||
// state: '',
|
||||
// rights: null,
|
||||
// project_id: '',
|
||||
|
||||
// creating_corporation: "GBA",
|
||||
// embargo_date: '',
|
||||
// belongs_to_bibliography: 0,
|
||||
|
||||
// title_main: {
|
||||
// value: '',
|
||||
// language: ''
|
||||
// },
|
||||
// abstract_main: {
|
||||
// value: '',
|
||||
// language: ''
|
||||
// },
|
||||
// checkedAuthors: [],
|
||||
// checkedLicenses: [],// [],
|
||||
// files: [],
|
||||
// references: [],
|
||||
// checkedContributors: [],
|
||||
// checkedSubmitters: [],
|
||||
// }
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
VeeValidate.Validator.extend('Name', {
|
||||
getMessage: field => '* Enter valid ' + field + '',
|
||||
validate: value => /^[a-zA-Z]*$/.test(value)
|
||||
});
|
||||
// add the required rule
|
||||
VeeValidate.Validator.extend('oneChecked', {
|
||||
getMessage: field => 'At least one ' + field + ' needs to be checked.',
|
||||
validate: (value, [testProp]) => {
|
||||
const options = this.dataset.checkedLicenses;
|
||||
return value || options.some((option) => option[testProp]);
|
||||
}
|
||||
});
|
||||
// add the required rule
|
||||
VeeValidate.Validator.extend('translatedLanguage', {
|
||||
getMessage: field => 'The translated ' + field + ' must be in a language other than than the dataset language.',
|
||||
validate: (value, [mainLanguage, type]) => {
|
||||
if (type == "translated") {
|
||||
return value !== mainLanguage;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
//this.step = 2;
|
||||
this.reset();
|
||||
},
|
||||
computed: {
|
||||
keywords_length() {
|
||||
return this.dataset.keywords.length;
|
||||
},
|
||||
isInitial() {
|
||||
return this.currentStatus === STATUS_INITIAL;
|
||||
},
|
||||
isSaving() {
|
||||
return this.currentStatus === STATUS_SAVING;
|
||||
},
|
||||
isSuccess() {
|
||||
return this.currentStatus === STATUS_SUCCESS;
|
||||
},
|
||||
isFailed() {
|
||||
return this.currentStatus === STATUS_FAILED;
|
||||
},
|
||||
isElevationAbsolut() {
|
||||
return this.elevation === "absolut";
|
||||
},
|
||||
isElevationRange() {
|
||||
return this.elevation === "range";
|
||||
},
|
||||
isDepthAbsolut() {
|
||||
return this.depth === "absolut";
|
||||
},
|
||||
isDepthRange() {
|
||||
return this.depth === "range";
|
||||
},
|
||||
isTimeAbsolut() {
|
||||
return this.time === "absolut";
|
||||
},
|
||||
isTimeRange() {
|
||||
return this.time === "range";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
showModal() {
|
||||
this.isModalVisible = true;
|
||||
},
|
||||
closeModal() {
|
||||
this.isModalVisible = false;
|
||||
},
|
||||
reset() {
|
||||
// reset form to initial state
|
||||
this.currentStatus = STATUS_INITIAL;
|
||||
this.uploadedFiles = [];
|
||||
this.uploadError = null;
|
||||
this.dataset.reset();//reset methods will trigger property changed.
|
||||
this.step = 0;
|
||||
},
|
||||
retry() {
|
||||
// reset form to initial state
|
||||
this.currentStatus = STATUS_INITIAL;
|
||||
// this.uploadedFiles = [];
|
||||
// this.uploadError = null;
|
||||
// this.dataset.reset();//reset methods will trigger property changed.
|
||||
// this.step = 1;
|
||||
},
|
||||
releaseNewDataset() {
|
||||
window.location = this.releaseLink;
|
||||
},
|
||||
deleteNewDataset() {
|
||||
window.location = this.deleteLink;
|
||||
},
|
||||
resetDropbox() {
|
||||
// reset form to initial state
|
||||
this.currentStatus = STATUS_INITIAL;
|
||||
this.dataset.files = [];
|
||||
},
|
||||
save(status) {
|
||||
// upload data to the server
|
||||
var _this = this;
|
||||
this.currentStatus = STATUS_SAVING;
|
||||
this.serrors = [];
|
||||
/*
|
||||
Initialize the form data
|
||||
*/
|
||||
let formData = new FormData();
|
||||
/*
|
||||
Iteate over any file sent over appending the files
|
||||
to the form data.
|
||||
*/
|
||||
// formData.append('files', []);
|
||||
for (var i = 0; i < this.dataset.files.length; i++) {
|
||||
let file = this.dataset.files[i];
|
||||
formData.append('files[' + i + '][file]', file.file);
|
||||
formData.append('files[' + i + '][label]', file.label);
|
||||
formData.append('files[' + i + '][sorting]', i + 1);
|
||||
|
||||
// formData.append('files[' + i + ']', JSON.stringify(file));
|
||||
}
|
||||
/*
|
||||
Additional POST Data
|
||||
*/
|
||||
formData.append('server_state', status);
|
||||
formData.append('type', this.dataset.type);
|
||||
formData.append('language', this.dataset.language);
|
||||
// formData.append('server_state', this.dataset.state);
|
||||
formData.append('rights', Number(this.dataset.rights));
|
||||
formData.append('creating_corporation', this.dataset.creating_corporation);
|
||||
formData.append('project_id', this.dataset.project_id);
|
||||
formData.append('embargo_date', this.dataset.embargo_date);
|
||||
formData.append('belongs_to_bibliography', this.dataset.belongs_to_bibliography);
|
||||
formData.append('title_main[value]', this.dataset.title_main.value);
|
||||
formData.append('title_main[language]', this.dataset.title_main.language);
|
||||
formData.append('abstract_main[value]', this.dataset.abstract_main.value);
|
||||
formData.append('abstract_main[language]', this.dataset.abstract_main.language);
|
||||
|
||||
if (this.dataset.coverage.xmin !== "" && this.dataset.coverage.ymin != '' &&
|
||||
this.dataset.coverage.xmax !== '' && this.dataset.coverage.ymax !== '') {
|
||||
formData.append('coverage[x_min]', this.dataset.coverage.xmin);
|
||||
formData.append('coverage[y_min]', this.dataset.coverage.ymin);
|
||||
formData.append('coverage[x_max]', this.dataset.coverage.xmax);
|
||||
formData.append('coverage[y_max]', this.dataset.coverage.ymax);
|
||||
}
|
||||
|
||||
if (this.isElevationAbsolut) {
|
||||
formData.append('coverage[elevation_absolut]', this.dataset.coverage.elevation_absolut);
|
||||
}
|
||||
else if (this.isElevationRange) {
|
||||
formData.append('coverage[elevation_min]', this.dataset.coverage.elevation_min);
|
||||
formData.append('coverage[elevation_max]', this.dataset.coverage.elevation_max);
|
||||
}
|
||||
if (this.isDepthAbsolut) {
|
||||
formData.append('coverage[depth_absolut]', this.dataset.coverage.depth_absolut);
|
||||
}
|
||||
else if (this.isDepthRange) {
|
||||
formData.append('coverage[depth_min]', this.dataset.coverage.depth_min);
|
||||
formData.append('coverage[depth_max]', this.dataset.coverage.depth_max);
|
||||
}
|
||||
if (this.isTimeAbsolut) {
|
||||
formData.append('coverage[time_absolut]', this.dataset.coverage.time_absolut);
|
||||
}
|
||||
else if (this.isTimeRange) {
|
||||
formData.append('coverage[time_min]', this.dataset.coverage.time_min);
|
||||
formData.append('coverage[time_max]', this.dataset.coverage.time_max);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < this.dataset.checkedLicenses.length; i++) {
|
||||
formData.append('licenses[' + i + ']', this.dataset.checkedLicenses[i]);
|
||||
}
|
||||
|
||||
|
||||
// for (var i = 0; i < this.dataset.checkedAuthors.length; i++) {
|
||||
// formData.append('authors[' + i + ']', this.dataset.checkedAuthors[i]);
|
||||
// }
|
||||
for (var i = 0; i < this.dataset.persons.length; i++) {
|
||||
let person = this.dataset.persons[i];
|
||||
formData.append('authors[' + i + '][first_name]', person.first_name);
|
||||
formData.append('authors[' + i + '][last_name]', person.last_name);
|
||||
formData.append('authors[' + i + '][email]', person.email);
|
||||
formData.append('authors[' + i + '][identifier_orcid]', person.identifier_orcid);
|
||||
formData.append('authors[' + i + '][status]', person.status);
|
||||
if (person.id !== undefined) {
|
||||
formData.append('authors[' + i + '][id]', person.id);
|
||||
}
|
||||
}
|
||||
|
||||
// for (var i = 0; i < this.dataset.checkedContributors.length; i++) {
|
||||
// formData.append('contributors[' + i + ']', this.dataset.checkedContributors[i]);
|
||||
// }
|
||||
for (var i = 0; i < this.dataset.contributors.length; i++) {
|
||||
let contributor = this.dataset.contributors[i];
|
||||
formData.append('contributors[' + i + '][first_name]', contributor.first_name);
|
||||
formData.append('contributors[' + i + '][last_name]', contributor.last_name);
|
||||
formData.append('contributors[' + i + '][email]', contributor.email);
|
||||
formData.append('contributors[' + i + '][identifier_orcid]', contributor.identifier_orcid);
|
||||
formData.append('contributors[' + i + '][status]', contributor.status);
|
||||
if (contributor.id !== undefined) {
|
||||
formData.append('contributors[' + i + '][id]', contributor.id);
|
||||
}
|
||||
}
|
||||
// for (var i = 0; i < this.dataset.checkedSubmitters.length; i++) {
|
||||
// formData.append('submitters[' + i + ']', this.dataset.checkedSubmitters[i]);
|
||||
// }
|
||||
|
||||
for (var i = 0; i < this.dataset.references.length; i++) {
|
||||
let reference = this.dataset.references[i];
|
||||
formData.append('references[' + i + '][value]', reference.value);
|
||||
formData.append('references[' + i + '][label]', reference.label);
|
||||
formData.append('references[' + i + '][type]', reference.type);
|
||||
formData.append('references[' + i + '][relation]', reference.relation);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.dataset.keywords.length; i++) {
|
||||
let keyword = this.dataset.keywords[i];
|
||||
formData.append('keywords[' + i + '][value]', keyword.value);
|
||||
formData.append('keywords[' + i + '][type]', keyword.type);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.dataset.titles.length; i++) {
|
||||
let title = this.dataset.titles[i];
|
||||
formData.append('titles[' + i + '][value]', title.value);
|
||||
formData.append('titles[' + i + '][language]', title.language);
|
||||
formData.append('titles[' + i + '][type]', title.type);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.dataset.descriptions.length; i++) {
|
||||
let description = this.dataset.descriptions[i];
|
||||
formData.append('descriptions[' + i + '][value]', description.value);
|
||||
formData.append('descriptions[' + i + '][language]', description.language);
|
||||
formData.append('descriptions[' + i + '][type]', description.type);
|
||||
}
|
||||
|
||||
/*
|
||||
Make the request to the POST /multiple-files URL
|
||||
*/
|
||||
axios.post('/publish/dataset/store',
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
.then((response) => {
|
||||
// success callback
|
||||
console.log(response.data);
|
||||
// this.loading = false;
|
||||
// this.items = response.data;
|
||||
//Vue.set(app.skills, 1, "test55");
|
||||
_this.currentStatus = STATUS_SUCCESS;
|
||||
_this.releaseLink = response.data.release;
|
||||
_this.deleteLink = response.data.delete;
|
||||
// if (response.data.redirect) {
|
||||
// window.location = response.data.redirect;
|
||||
// }
|
||||
})
|
||||
.catch((error) => {
|
||||
// this.loading = false;
|
||||
this.uploadError = error.response;
|
||||
console.log('FAILURE!!');
|
||||
let errorObject = JSON.parse(JSON.stringify(error));
|
||||
// console.log(errorObject);
|
||||
if (errorObject.response.data.errors) {
|
||||
var errorsArray = errorObject.response.data.errors;
|
||||
for (var index in errorsArray) {
|
||||
console.log(errorsArray[index]);
|
||||
_this.serrors.push(errorsArray[index]);
|
||||
}
|
||||
}
|
||||
//fill with server error
|
||||
if (errorObject.response.data.error) {
|
||||
var error = errorObject.response.data.error;
|
||||
_this.serrors.push(error.message);
|
||||
}
|
||||
//raundtrip to server was not possible
|
||||
if (error.message && error.message.includes('413')) {
|
||||
console.log('The file you tried to upload is too large.')
|
||||
var error = 'The file you tried to upload is too large.';
|
||||
_this.serrors.push(error);
|
||||
}
|
||||
_this.currentStatus = STATUS_FAILED;
|
||||
});
|
||||
},
|
||||
// filesChange(fieldName, fileList) {
|
||||
// // handle file changes
|
||||
// // const formData = new FormData();
|
||||
// if (!fileList.length) return;
|
||||
// // append the files to FormData
|
||||
// Array
|
||||
// .from(Array(fileList.length).keys())
|
||||
// .map(x => {
|
||||
// dataset.files.append(fieldName, fileList[x], fileList[x].name);
|
||||
// });
|
||||
// // save it
|
||||
// // this.save(formData);
|
||||
|
||||
// },
|
||||
/*
|
||||
Handles a change on the file upload
|
||||
*/
|
||||
addReference() {
|
||||
let newReference = { value: '', label: '', relation: '', type: '' };
|
||||
//this.dataset.files.push(uploadedFiles[i]);
|
||||
this.dataset.references.push(newReference);
|
||||
},
|
||||
/*
|
||||
Removes a selected reference
|
||||
*/
|
||||
removeReference(key) {
|
||||
this.dataset.references.splice(key, 1);
|
||||
},
|
||||
/*
|
||||
adds a new Keyword
|
||||
*/
|
||||
addKeyword() {
|
||||
let newKeyword = { value: '', type: '', language: this.dataset.language };
|
||||
//this.dataset.files.push(uploadedFiles[i]);
|
||||
this.dataset.keywords.push(newKeyword);
|
||||
},
|
||||
/*
|
||||
Removes a selected keyword
|
||||
*/
|
||||
removeKeyword(key) {
|
||||
this.dataset.keywords.splice(key, 1);
|
||||
},
|
||||
addTitle() {
|
||||
let newTitle = { value: '', language: '', type: '' };
|
||||
//this.dataset.files.push(uploadedFiles[i]);
|
||||
this.dataset.titles.push(newTitle);
|
||||
},
|
||||
/*
|
||||
Removes a selected title
|
||||
*/
|
||||
removeTitle(key) {
|
||||
this.dataset.titles.splice(key, 1);
|
||||
},
|
||||
addDescription() {
|
||||
let newTitle = { value: '', language: '', type: '' };
|
||||
//this.dataset.files.push(uploadedFiles[i]);
|
||||
this.dataset.descriptions.push(newTitle);
|
||||
},
|
||||
/*
|
||||
Removes a selected description
|
||||
*/
|
||||
removeDescription(key) {
|
||||
this.dataset.descriptions.splice(key, 1);
|
||||
},
|
||||
filesChange(fieldName, fileList) {
|
||||
this.fileCount = fileList.length
|
||||
// this.dataset.files = this.$refs.files.files;
|
||||
let uploadedFiles = fileList;
|
||||
|
||||
/*
|
||||
Adds the uploaded file to the files array
|
||||
*/
|
||||
for (var i = 0; i < uploadedFiles.length; i++) {
|
||||
let fileName = uploadedFiles[i].name.replace(/\.[^/.]+$/, '');
|
||||
let uploadeFile = { file: uploadedFiles[i], label: fileName, sorting: 0 };
|
||||
//this.dataset.files.push(uploadedFiles[i]);
|
||||
this.dataset.files.push(uploadeFile);
|
||||
}
|
||||
// if (this.dataset.files.length > 0)
|
||||
// {
|
||||
// this.currentStatus = STATUS_SAVING;
|
||||
// }
|
||||
|
||||
},
|
||||
addNewAuthor() {
|
||||
let newAuthor = { status: 0, first_name: '', last_name: '', email: '', academic_title: '', identifier_orcid: '' };
|
||||
this.dataset.persons.push(newAuthor);
|
||||
},
|
||||
removeAuthor(key) {
|
||||
this.dataset.persons.splice(key, 1);
|
||||
},
|
||||
onAddAuthor(person) {
|
||||
//if person is not in person array
|
||||
//if (this.persons.includes(person) == false) {
|
||||
if (this.dataset.persons.filter(e => e.id === person.id).length > 0) {
|
||||
this.$toast.error("person is already defined as author");
|
||||
} else if (this.dataset.contributors.filter(e => e.id === person.id).length > 0) {
|
||||
this.$toast.error("person is already defined as contributor");
|
||||
} else {
|
||||
//person.sort_order = this.dataset.persons.length;
|
||||
this.dataset.persons.push(person);
|
||||
this.dataset.checkedAuthors.push(person.id);
|
||||
this.$toast.success("person has been successfully added as author");
|
||||
}
|
||||
},
|
||||
addNewContributor() {
|
||||
let newContributor = { status: 0, first_name: '', last_name: '', email: '', academic_title: '', identifier_orcid: '' };
|
||||
this.dataset.contributors.push(newContributor);
|
||||
},
|
||||
onAddContributor(person) {
|
||||
//if person is not in contributors array
|
||||
//if (this.contributors.includes(person) == false) {
|
||||
if (this.dataset.contributors.filter(e => e.id === person.id).length > 0) {
|
||||
this.$toast.error("person is already defined as contributor");
|
||||
} else if (this.dataset.persons.filter(e => e.id === person.id).length > 0) {
|
||||
this.$toast.error("person is already defined as author");
|
||||
} else {
|
||||
this.dataset.contributors.push(person);
|
||||
this.dataset.checkedContributors.push(person.id);
|
||||
this.$toast.success("person has been successfully added as contributor");
|
||||
}
|
||||
},
|
||||
// onAddSubmitter(person) {
|
||||
// //if person is not in submitters array
|
||||
// //if (this.submitters.includes(person) == false) {
|
||||
// if (this.dataset.submitters.filter(e => e.id === person.id).length == 0) {
|
||||
// this.dataset.submitters.push(person);
|
||||
// this.dataset.checkedSubmitters.push(person.id);
|
||||
// }
|
||||
// },
|
||||
/*
|
||||
Removes a select file the user has uploaded
|
||||
*/
|
||||
removeFile(key) {
|
||||
this.dataset.files.splice(key, 1);
|
||||
},
|
||||
|
||||
prev() {
|
||||
this.step--;
|
||||
},
|
||||
next(scope) {
|
||||
// if(this.validate(scope)) {
|
||||
// this.step++;
|
||||
// }
|
||||
this.$validator.validateAll(scope).then((result) => {
|
||||
if (result) {
|
||||
this.step++;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
validate: function (scope) {
|
||||
this.$validator.validateAll(scope);
|
||||
if (this.errors.any()) {
|
||||
console.log('The form is invalid');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
submit(status) {
|
||||
// alert('Submit to blah and show blah and etc.');
|
||||
// save it
|
||||
this.save(status);
|
||||
}
|
||||
}
|
||||
});
|
6
resources/js/jquery-global.js
vendored
Normal file
6
resources/js/jquery-global.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
//https://stackoverflow.com/questions/35358625/jquery-is-not-defined-when-use-es6-import
|
||||
|
||||
// jquery-global.js
|
||||
import jquery from 'jquery';
|
||||
window.jQuery = jquery;
|
||||
window.$ = jquery;
|
26
resources/js/lib.js
Normal file
26
resources/js/lib.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* First we will load all of this project's JavaScript dependencies which
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
// require('./bootstrap');
|
||||
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
|
||||
// window.Vue = require('vue');
|
||||
// import Vue from 'vue';
|
||||
|
||||
// Vue.prototype.$http = axios;
|
||||
|
||||
// Vue.component('example', require('./components/Example.vue'));
|
||||
|
||||
// const app = new Vue({
|
||||
// el: '#app',
|
||||
|
||||
// data: {
|
||||
// loading: false,
|
||||
// downloading: false,
|
||||
// items: [],
|
||||
// message: "Just a test",
|
||||
// }
|
||||
// });
|
52
resources/js/releaseDataset.js
Normal file
52
resources/js/releaseDataset.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
// releaseDataset.js
|
||||
import Vue from 'vue';
|
||||
import VeeValidate from 'vee-validate';
|
||||
Vue.use(VeeValidate);
|
||||
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app1',
|
||||
data() {
|
||||
return {
|
||||
// dataset: {
|
||||
// firstName: '',
|
||||
// preferred_reviewer: null,
|
||||
// preferred_reviewer_email: null
|
||||
// },
|
||||
dataset: window.Laravel.dataset,
|
||||
submitted: false,
|
||||
preferation: "yes_preferation",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isPreferationRequired() {
|
||||
return this.preferation === "yes_preferation";
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
preferation(val) {
|
||||
if (val === "no_preferation") {
|
||||
this.dataset.preferred_reviewer = "";
|
||||
this.dataset.preferred_reviewer_email = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkForm(e) {
|
||||
// Log entire model to console
|
||||
// console.log(this.dataset);
|
||||
this.submitted = true;
|
||||
this.$validator.validate().then(result => {
|
||||
if (result) {
|
||||
if (this.preferation === "no_preferation") {
|
||||
this.dataset.preferred_reviewer = "";
|
||||
this.dataset.preferred_reviewer_email = "";
|
||||
}
|
||||
// console.log('From Submitted!');
|
||||
document.getElementById("releaseForm").submit();
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
86
resources/js/scripts.js
Normal file
86
resources/js/scripts.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
import './jquery-global.js';
|
||||
import 'single-page-nav/jquery.singlePageNav.js';
|
||||
//bind plugin definition to jQuery
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// =Hero
|
||||
// Alway make hero-container height equal to window height
|
||||
|
||||
var $heroContainer = $('.hero');
|
||||
|
||||
$heroContainer.height(window.innerHeight);
|
||||
|
||||
// When user resize browser window, hero container needs to have the same
|
||||
// height as browser window height.
|
||||
$(window).resize(function () {
|
||||
$heroContainer.height(window.innerHeight);
|
||||
});
|
||||
|
||||
// =Work
|
||||
// Isotope filters
|
||||
// var $workFilterLinks = $('.work-filters li');
|
||||
// var $container = $('.work-items');
|
||||
|
||||
// $workFilterLinks.find('a').click(function(){
|
||||
// $workFilterLinks.removeClass('active');
|
||||
// $container.isotope({
|
||||
// // options
|
||||
// filter: $(this).attr('data-filter'),
|
||||
// itemSelector: '.isotope-item',
|
||||
// animationEngine : "best-available",
|
||||
// masonry: {
|
||||
// columnWidth: '.isotope-item'
|
||||
// }
|
||||
// });
|
||||
// $(this).parent().addClass('active');
|
||||
// return false;
|
||||
// });
|
||||
|
||||
// Menu initialization
|
||||
|
||||
var $menuIcon = $('.menu-icon'),
|
||||
$navigation = $('.navigation'),
|
||||
$menu = $('.menu'),
|
||||
$navigationLink = $('.menu a');
|
||||
|
||||
if (location.pathname == "/") {
|
||||
$(window).scroll(function () {
|
||||
if (window.scrollY > window.outerHeight) {
|
||||
$menuIcon.addClass('active');
|
||||
} else {
|
||||
$menuIcon.removeClass('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$menuIcon.click(function (e) {
|
||||
e.preventDefault();
|
||||
$navigation.toggleClass('active');
|
||||
});
|
||||
|
||||
// $menu.singlePageNav({
|
||||
// filter: ':not(.external)',
|
||||
// speed: 1000,
|
||||
// currentClass: 'current',
|
||||
// easing: 'swing',
|
||||
// updateHash: false,
|
||||
// beforeStart: function() {
|
||||
// },
|
||||
// onComplete: function() {
|
||||
// $navigation.removeClass('active');
|
||||
// }
|
||||
// });
|
||||
|
||||
//// Scrollreveal initialize
|
||||
// var config = {
|
||||
// easing: 'hustle',
|
||||
// reset: false,
|
||||
// delay: 'onload',
|
||||
// opacity: .2,
|
||||
// vFactor: 0.2,
|
||||
// mobile: false
|
||||
// }
|
||||
// window.sr = new scrollReveal(config);
|
||||
|
||||
});
|
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>
|
4
resources/js/strings/messages/en.js
Normal file
4
resources/js/strings/messages/en.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
const messages={
|
||||
min_value: (field, num) => field +' cannot be empty! ' + num + ' items are required.',
|
||||
};
|
||||
export default messages;
|
3
resources/js/tinyDatePicker.js
Normal file
3
resources/js/tinyDatePicker.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import TinyDatePicker from 'tiny-date-picker';
|
||||
|
||||
TinyDatePicker(document.querySelector("input[name='time_absolut']"));
|
4
resources/js/typings.d.ts
vendored
Normal file
4
resources/js/typings.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
}
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue