Feature: show list of geographical units which covers address in address details modal

This commit is contained in:
Julien Fastré 2023-03-15 15:56:46 +01:00
parent 71d0785ab4
commit 21e24c60c7
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
8 changed files with 119 additions and 9 deletions

View File

@ -0,0 +1,15 @@
<?php
namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\Address;
use Symfony\Component\HttpFoundation\JsonResponse;
class AddressToReferenceMatcher
{
public function markAddressAsMatching(Address $address): JsonResponse
{
}
}

View File

@ -46,6 +46,7 @@ use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType;
use Chill\MainBundle\Doctrine\Type\PointType; use Chill\MainBundle\Doctrine\Type\PointType;
use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Entity\Country; use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\GeographicalUnitLayer;
use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Entity\Language;
use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\LocationType; use Chill\MainBundle\Entity\LocationType;
@ -732,6 +733,20 @@ class ChillMainExtension extends Extension implements
], ],
], ],
], ],
[
'class' => GeographicalUnitLayer::class,
'name' => 'geographical-unit-layer',
'base_path' => '/api/1.0/main/geographical-unit-layer',
'base_role' => 'ROLE_USER',
'actions' => [
'_index' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true,
],
],
],
]
], ],
]); ]);
} }

View File

@ -14,6 +14,7 @@ namespace Chill\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
/** /**
* @ORM\Table(name="chill_main_geographical_unit_layer", uniqueConstraints={ * @ORM\Table(name="chill_main_geographical_unit_layer", uniqueConstraints={
@ -27,16 +28,19 @@ class GeographicalUnitLayer
* @ORM\Id * @ORM\Id
* @ORM\GeneratedValue * @ORM\GeneratedValue
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/ */
private ?int $id = null; private ?int $id = null;
/** /**
* @ORM\Column(type="json", nullable=false, options={"default": "[]"}) * @ORM\Column(type="json", nullable=false, options={"default": "[]"})
* @Serializer\Groups({"read"})
*/ */
private array $name = []; private array $name = [];
/** /**
* @ORM\Column(type="text", nullable=false, options={"default": ""}) * @ORM\Column(type="text", nullable=false, options={"default": ""})
* @Serializer\Groups({"read"})
*/ */
private string $refId = ''; private string $refId = '';

View File

@ -1,4 +1,5 @@
import {Address} from "../../types"; import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../types";
import {fetchResults, makeFetch} from "./apiMethods";
export const getAddressById = async (address_id: number): Promise<Address> => export const getAddressById = async (address_id: number): Promise<Address> =>
{ {
@ -12,3 +13,11 @@ export const getAddressById = async (address_id: number): Promise<Address> =>
throw Error('Error with request resource response'); throw Error('Error with request resource response');
}; };
export const getGeographicalUnitsByAddress = async (address: Address): Promise<SimpleGeographicalUnit[]> => {
return fetchResults<SimpleGeographicalUnit>(`/api/1.0/main/geographical-unit/by-address/${address.address_id}.json`);
}
export const getAllGeographicalUnitLayers = async (): Promise<GeographicalUnitLayer[]> => {
return fetchResults<GeographicalUnitLayer>(`/api/1.0/main/geographical-unit-layer.json`);
}

View File

@ -115,6 +115,19 @@ export interface AddressReference {
updatedAt: DateTime | null; updatedAt: DateTime | null;
} }
export interface SimpleGeographicalUnit {
id: number;
layerId: number;
unitName: string;
unitRefId: string;
}
export interface GeographicalUnitLayer {
id: number;
name: TranslatableString;
refId: string;
}
export interface Location { export interface Location {
type: "location"; type: "location";
id: number; id: number;

View File

@ -1,13 +1,14 @@
<template> <template>
<address-details-map :address="props.address"></address-details-map>
<address-render-box :address="props.address"></address-render-box> <address-render-box :address="props.address"></address-render-box>
<address-details-map :address="props.address"></address-details-map>
<address-details-geographical-layers :address="props.address"></address-details-geographical-layers>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {Address} from "../../../types"; import {Address} from "../../../types";
import AddressDetailsMap from "./Parts/AddressDetailsMap.vue"; import AddressDetailsMap from "./Parts/AddressDetailsMap.vue";
import AddressRenderBox from "../Entity/AddressRenderBox.vue"; import AddressRenderBox from "../Entity/AddressRenderBox.vue";
import AddressDetailsGeographicalLayers from "./Parts/AddressDetailsGeographicalLayers.vue";
interface AddressModalContentProps { interface AddressModalContentProps {
address: Address, address: Address,

View File

@ -0,0 +1,55 @@
<template>
<template v-for="container in data.containers">
<h4>{{ container.layer.name.fr }}</h4>
<ul>
<li v-for="unit in container.units">{{ unit.unitName }} ({{ unit.unitRefId }})</li>
</ul>
</template>
</template>
<script lang="ts" setup>
import {Address, GeographicalUnitLayer, SimpleGeographicalUnit} from "../../../../types";
import {getGeographicalUnitsByAddress, getAllGeographicalUnitLayers} from "../../../../lib/api/address";
import {onMounted, reactive} from "vue";
export interface AddressDetailsGeographicalLayersProp {
address: Address
};
interface GeographicalUnitContainer {
layer: GeographicalUnitLayer;
units: SimpleGeographicalUnit[];
}
const props = defineProps<AddressDetailsGeographicalLayersProp>();
const data: {
containers: GeographicalUnitContainer[]
} = reactive({
containers: []
});
onMounted(async () => {
const [units, layers] = await Promise.all([
getGeographicalUnitsByAddress(props.address),
getAllGeographicalUnitLayers()
]) as [SimpleGeographicalUnit[], GeographicalUnitLayer[]];
for (let layer of layers) {
let us = units.filter((u) => u.layerId === layer.id);
if (us.length > 0) {
data.containers.push({
layer,
units: us
});
}
}
})
</script>
<style scoped>
</style>

View File

@ -3,8 +3,7 @@
Cette adresse est incomplète. La position géographique est approximative. Cette adresse est incomplète. La position géographique est approximative.
</div> </div>
<div v-if="props.address.point !== null" class="address_details_map" ref="map_div"></div> <div v-if="props.address.point !== null" class="address_details_map" ref="map_div"></div>
<a :href="makeUrlGoogleMap(props.address)" target="_blank">Google Maps</a> <p>Voir sur <a :href="makeUrlGoogleMap(props.address)" target="_blank">Google Maps</a> <a :href="makeUrlOsm(props.address)" target="_blank">OSM</a></p>
<a :href="makeUrlOsm(props.address)" target="_blank">OSM</a>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -29,14 +28,13 @@ let map: L.Map|null = null;
let marker: L.Marker|null = null; let marker: L.Marker|null = null;
onMounted(() => { onMounted(() => {
console.log(map_div.value);
if (map_div.value === null) { if (map_div.value === null) {
throw new Error('map div not found'); throw new Error('map div not found');
} }
if (props.address.point !== null) { if (props.address.point !== null) {
map = L.map(map_div.value); map = L.map(map_div.value);
map.setView(lonLatForLeaflet(props.address.point), 15); map.setView(lonLatForLeaflet(props.address.point), 18);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
@ -57,7 +55,7 @@ onMounted(() => {
const makeUrlGoogleMap = (address: Address): string => { const makeUrlGoogleMap = (address: Address): string => {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append('api', '1'); params.append('api', '1');
if (address.point !== null) { if (address.point !== null && address.addressReference !== null) {
params.append('query', `${address.point.coordinates[1]} ${address.point.coordinates[0]}`); params.append('query', `${address.point.coordinates[1]} ${address.point.coordinates[0]}`);
} else { } else {
params.append('query', address.lines.join(', ')); params.append('query', address.lines.join(', '));
@ -67,7 +65,7 @@ const makeUrlGoogleMap = (address: Address): string => {
} }
const makeUrlOsm = (address: Address): string => { const makeUrlOsm = (address: Address): string => {
if (address.point !== null) { if (address.point !== null && address.addressReference !== null) {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append('mlat', `${address.point.coordinates[1]}`); params.append('mlat', `${address.point.coordinates[1]}`);
params.append('mlon', `${address.point.coordinates[0]}`); params.append('mlon', `${address.point.coordinates[0]}`);