Begins implementation of GeoCoordinate field input using leaflet.

This commit is contained in:
mateuswetah 2022-12-06 12:09:48 -03:00
parent 74ee8e1861
commit 1a9a58e78b
15 changed files with 143 additions and 38 deletions

16
package-lock.json generated
View File

@ -4305,6 +4305,11 @@
"integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
"dev": true "dev": true
}, },
"leaflet": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz",
"integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ=="
},
"levn": { "levn": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -4327,9 +4332,9 @@
"dev": true "dev": true
}, },
"loader-utils": { "loader-utils": {
"version": "2.0.3", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true, "dev": true,
"requires": { "requires": {
"big.js": "^5.2.2", "big.js": "^5.2.2",
@ -6699,6 +6704,11 @@
"resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz", "resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz",
"integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ==" "integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ=="
}, },
"vue2-leaflet": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/vue2-leaflet/-/vue2-leaflet-2.7.1.tgz",
"integrity": "sha512-K7HOlzRhjt3Z7+IvTqEavIBRbmCwSZSCVUlz9u4Rc+3xGCLsHKz4TAL4diAmfHElCQdPPVdZdJk8wPUt2fu6WQ=="
},
"vuedraggable": { "vuedraggable": {
"version": "2.24.3", "version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz", "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",

View File

@ -17,6 +17,7 @@
"countup.js": "^2.3.2", "countup.js": "^2.3.2",
"css-vars-ponyfill": "^2.4.8", "css-vars-ponyfill": "^2.4.8",
"floating-vue": "^1.0.0-beta.18", "floating-vue": "^1.0.0-beta.18",
"leaflet": "^1.9.3",
"masonry-layout": "^4.2.2", "masonry-layout": "^4.2.2",
"moment": "^2.29.4", "moment": "^2.29.4",
"node-sass": "^7.0.3", "node-sass": "^7.0.3",
@ -32,6 +33,7 @@
"vue-countup-v2": "^4.0.0", "vue-countup-v2": "^4.0.0",
"vue-router": "^3.5.4", "vue-router": "^3.5.4",
"vue-the-mask": "^0.11.1", "vue-the-mask": "^0.11.1",
"vue2-leaflet": "^2.7.1",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "8f2c4d11474275fbc1614b9098334eae.png";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "416d91365b44e4b4f4777663e6f009f3.png";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "2b3e1faf89f94a4835397e7a43b4f77d.png";

View File

@ -51,7 +51,7 @@
isInvalidDate: false, isInvalidDate: false,
} }
}, },
created(){ created() {
if (this.value) if (this.value)
this.dateValue = this.parseDateToNavigatorLanguage(this.value); this.dateValue = this.parseDateToNavigatorLanguage(this.value);
}, },

View File

@ -1,46 +1,136 @@
<template> <template>
<div> <div :id="itemMetadatumIdentifier">
<b-input <b-taginput
:id="'tainacan-item-metadatum_id-' + itemMetadatum.metadatum.id + (itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + itemMetadatum.parent_meta_id) : '')" expanded
:disabled="disabled" :disabled="disabled"
type="text" :id="'taginput--' + itemMetadatumIdentifier"
@input.native="onInput" size="is-small"
@blur="onBlur" icon="magnify"
:placeholder="itemMetadatum.metadatum.placeholder || ''" /> :allow-new="false"
<p @add="() => $emit('input', selected)"
style="font-size: 0.75em;" @remove="() => $emit('input', selected)"
class="has-text-danger is-italic">{{ $i18n.get('info_error_invalid_geocoordinate') }}</p> v-model="selected"
:maxtags="maxtags"
field="label"
:remove-on-keys="[]"
:dropdown-position="isLastMetadatum ? 'top' :'auto'"
attached
ellipsis
:aria-close-label="$i18n.get('remove_value')"
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : $i18n.get('instruction_type_geocoordinate')"
:class="{ 'has-selected': selected != undefined && selected != [] }"
:has-counter="false"
:confirm-keys="['Tab', 'Enter']"
:on-paste-separators="['|', ';']"
:before-adding="onAddValueFromTaginput" />
<l-map
:id="'map--' + itemMetadatumIdentifier"
:ref="'map--' + itemMetadatumIdentifier"
style="height: 300px; width:100%;"
:zoom="13"
:center="[-14.4086569, -51.31668]"
:zoom-animation="true"
@click="onMarkerAdd">
<l-tile-layer
:url="url"
:attribution="attribution" />
<l-marker
v-for="(markerLatLng, index) of selectedLatLng"
:key="index"
:draggable="true"
:lat-lng="markerLatLng"
@dragend="($event) => onDragMarker($event, index)"
@click.stop.prevent="() => onMarkerRemove(index)" />
</l-map>
</div> </div>
</template> </template>
<script> <script>
import { LMap, LTileLayer, LMarker } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
import { Icon, latLng } from 'leaflet';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png'
import iconUrl from 'leaflet/dist/images/marker-icon.png'
import shadowUrl from 'leaflet/dist/images/marker-shadow.png'
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
iconRetinaUrl: iconRetinaUrl,
iconUrl: iconUrl,
shadowUrl: shadowUrl,
});
export default { export default {
mixins: [ ], components: {
LMap,
LTileLayer,
LMarker,
},
props: { props: {
itemMetadatum: Object, itemMetadatum: Object,
value: [String, Array], value: [String, Array],
disabled: false, disabled: false,
maxtags: '',
isLastMetadatum: false
}, },
data() { data() {
return { return {
coordinateValue: '-14.4086569,-51.31668', selected: [],
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
} }
}, },
created(){ computed: {
itemMetadatumIdentifier() {
return 'tainacan-item-metadatum_id-' + this.itemMetadatum.metadatum.id + (this.itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + this.itemMetadatum.parent_meta_id) : '');
},
selectedLatLng() {
if ( this.selected && Array.isArray(this.selected) ) {
return this.selected.map((aSelected) => {
const coordinates = aSelected.indexOf(',') ? aSelected.split(',') : [-14.4086569, -51.31668];
return latLng(Number(coordinates[0]), Number(coordinates[1]));
});
}
return [];
},
},
watch: {
selectedLatLng() {
this.$nextTick(() => {
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
if ( this.$refs[mapComponentRef] && this.$refs[mapComponentRef].mapObject ) {
this.$refs[mapComponentRef].mapObject.panInsideBounds(this.selectedLatLng, { animate: true });
}
});
}
},
created() {
if (this.value) if (this.value)
this.coordinateValue= this.value; this.selected = Array.isArray(this.value) ? this.value : [this.value];
}, },
methods: { methods: {
onInput: _.debounce(function ($event) { onAddValueFromTaginput(textualValue) {
if ($event.target.value != '') { return textualValue.indexOf(',') && textualValue.split(',').length == 2
this.$emit('input', this.coordinateValue); },
} else { onDragMarker($event, index) {
this.$emit('input', ''); if ( $event.target && $event.target['_latlng'] ) {
this.selected.splice(index, 0, $event.target['_latlng']['lat'] + ',' + $event.target['_latlng']['lng']);
this.$emit('input', this.selected);
} }
}, 300), },
onBlur() { onMarkerAdd($event) {
this.$emit('blur'); if ($event.latlng) {
const newLocationValue = $event.latlng.lat + ',' + $event.latlng.lng;
const existintSelectedValue = this.selected.indexOf((aSelected) => aSelected == newLocationValue);
if (existintSelectedValue < 0) {
this.selected.push(newLocationValue);
this.$emit('input', this.selected);
}
}
},
onMarkerRemove(index) {
this.selected.splice(index, 1);
this.$emit('input', this.selected);
} }
} }
} }

View File

@ -112,7 +112,7 @@
</template> </template>
</div> </div>
<!-- Non-textual metadata such as taxonomy, relationship and compound manage multiple state in different ways --> <!-- Non-textual metadata such as taxonomy, relationship, geocoordinate and compound manage multiple state in different ways -->
<div <div
v-show="hideCollapses || isCollapsed" v-show="hideCollapses || isCollapsed"
v-else> v-else>
@ -183,7 +183,7 @@
) ? this.itemMetadatum.metadatum.cardinality : undefined; ) ? this.itemMetadatum.metadatum.cardinality : undefined;
}, },
isTextInputComponent() { isTextInputComponent() {
const array = ['tainacan-relationship','tainacan-taxonomy', 'tainacan-compound', 'tainacan-user']; const array = ['tainacan-relationship','tainacan-taxonomy', 'tainacan-compound', 'tainacan-user', 'tainacan-geocoordinate'];
return !(array.indexOf(this.metadatumComponent) >= 0 ); return !(array.indexOf(this.metadatumComponent) >= 0 );
}, },
metadatumFormClasses() { metadatumFormClasses() {

View File

@ -72,17 +72,16 @@
} }
}, },
watch: { watch: {
selected(){ selected() {
if (this.allowSelectToCreate && this.selected[0]) { if (this.allowSelectToCreate && this.selected[0]) {
this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`); this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`);
this.selected[0].label = this.selected[0].label.split('(')[0]; this.selected[0].label = this.selected[0].label.split('(')[0];
} }
} }
}, },
created(){ created() {
if (this.value && this.value.length > 0){ if (this.value && this.value.length > 0)
this.selected = this.value; this.selected = this.value;
}
}, },
methods: { methods: {
...mapActions('taxonomy', [ ...mapActions('taxonomy', [

View File

@ -738,6 +738,7 @@ return apply_filters( 'tainacan-i18n', [
'instruction_edit_item_status' => __( 'To alter the item status, select a different update strategy in the footer below.', 'tainacan' ), 'instruction_edit_item_status' => __( 'To alter the item status, select a different update strategy in the footer below.', 'tainacan' ),
/* translators: At the end of this sentence there will be a search query typed by the user wrapped in quotes. */ /* translators: At the end of this sentence there will be a search query typed by the user wrapped in quotes. */
'instruction_press_enter_to_search_for' => __( 'Press <kbd>ENTER</kbd> to search for', 'tainacan' ), 'instruction_press_enter_to_search_for' => __( 'Press <kbd>ENTER</kbd> to search for', 'tainacan' ),
'instruction_type_geocoordinate' => __( 'Type a geo coordinate in the form of lat,lng', 'tainacan' ),
// Info. Other feedback to user. // Info. Other feedback to user.
'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ), 'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ),