- 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
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>
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue