Merge branch 'Preorder/rimo-map' into 'master'
updated rimo type map See merge request fronk/thetool!1765
This commit is contained in:
@@ -216,6 +216,7 @@
|
|||||||
<ul class="submenu">
|
<ul class="submenu">
|
||||||
<?php if($me->is(["Admin","netowner","salespartner"]) || $me->can("Preorder")): ?>
|
<?php if($me->is(["Admin","netowner","salespartner"]) || $me->can("Preorder")): ?>
|
||||||
<li><a href="<?=self::getUrl("Preordercampaign")?>"><i class="far fa-fw fa-calendar-lines text-info"></i> Vorbestellungen / Kampagnen</a></li>
|
<li><a href="<?=self::getUrl("Preordercampaign")?>"><i class="far fa-fw fa-calendar-lines text-info"></i> Vorbestellungen / Kampagnen</a></li>
|
||||||
|
<li><a href="<?=self::getUrl("Preorder", "RimoTypeMap")?>"><i class="far fa-fw fa-map text-info"></i> RIMO Typen-Karte</a></li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if($me->is(["Admin","salespartner"]) && $me->can("Order")): ?>
|
<?php if($me->is(["Admin","salespartner"]) && $me->can("Order")): ?>
|
||||||
|
|||||||
@@ -1837,17 +1837,15 @@ class PreorderController extends mfBaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function RimoTypeMapAction() {
|
public function RimoTypeMapAction() {
|
||||||
$allowedCampaigns = Helper::getPreorderCampaignFromUser($this->me);
|
|
||||||
$campaignId = $this->request->preordercampaign_id ?? null;
|
|
||||||
if (!$campaignId || !in_array($campaignId, $allowedCampaigns)) {
|
|
||||||
$this->layout()->setFlash("Ungültige oder keine Kampagne ausgewählt.", "warning");
|
|
||||||
$this->redirect("Preorder", "Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
Helper::renderVue($this, "PreorderRimoTypeMap", "PreorderRimoTypeMap", [
|
Helper::renderVue($this, "PreorderRimoTypeMap", "PreorderRimoTypeMap", [
|
||||||
"MAPBOX_KEY" => TT_MAPBOX_TILE_API_TOKEN,
|
"MAPBOX_KEY" => TT_MAPBOX_TILE_API_TOKEN,
|
||||||
"USER_ID" => $this->me->id,
|
"USER_ID" => $this->me->id,
|
||||||
"ALL_USERS" => array_map(fn($u) => ["id" => $u->id, "name" => $u->name], UserModel::getAll())
|
"ALL_USERS" => array_map(fn($u) => ["id" => $u->id, "name" => $u->name], UserModel::getAll()),
|
||||||
|
"ALL_CAMPAIGNS" => array_map(fn($c) => ["id" => $c->id, "name" => $c->name], Helper::getPreorderCampaignFromUser($this->me, true)),
|
||||||
|
"PATH" => [
|
||||||
|
["text" => MFAPPNAME_SLUG, "href" => self::getUrl("Dashboard")],
|
||||||
|
["text" => "Rimo Typen Karte", "href" => self::getUrl("Preorder/RimoTypeMap")]
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1359,7 +1359,7 @@ ORDER BY
|
|||||||
h.id AS hausnummer_id, h.gps_lat, h.gps_long, h.rimo_type, h.rimo_op_state, h.rimo_ex_state, h.hausnummer,
|
h.id AS hausnummer_id, h.gps_lat, h.gps_long, h.rimo_type, h.rimo_op_state, h.rimo_ex_state, h.hausnummer,
|
||||||
s.name AS strasse_name, plz.plz AS plz_name, o.name AS ortschaft_name, h.rimo_id,
|
s.name AS strasse_name, plz.plz AS plz_name, o.name AS ortschaft_name, h.rimo_id,
|
||||||
COUNT(DISTINCT we.id) AS wohneinheit_count,
|
COUNT(DISTINCT we.id) AS wohneinheit_count,
|
||||||
COUNT(DISTINCT ps.id) AS preorder_count
|
COUNT(DISTINCT pr.id) AS preorder_count
|
||||||
FROM `{$addressDbName}`.`Hausnummer` AS h
|
FROM `{$addressDbName}`.`Hausnummer` AS h
|
||||||
LEFT JOIN `{$addressDbName}`.`Wohneinheit` AS we ON h.id = we.hausnummer_id
|
LEFT JOIN `{$addressDbName}`.`Wohneinheit` AS we ON h.id = we.hausnummer_id
|
||||||
LEFT JOIN `{$fronkDbName}`.`Preorder` AS pr ON we.id = pr.adb_wohneinheit_id AND pr.preordercampaign_id = {$safeCampaignId} AND pr.deleted = 0
|
LEFT JOIN `{$fronkDbName}`.`Preorder` AS pr ON we.id = pr.adb_wohneinheit_id AND pr.preordercampaign_id = {$safeCampaignId} AND pr.deleted = 0
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-filter-container .form-group {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.map-filter-container .filter-separator {
|
.map-filter-container .filter-separator {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
window,
|
window,
|
||||||
fetchUrl: window.TT_CONFIG.BASE_PATH + '/Preorder/RimoTypeMapData',
|
fetchUrl: window.TT_CONFIG.BASE_PATH + '/Preorder/RimoTypeMapData',
|
||||||
selectedCampaign: null,
|
selectedCampaign: null,
|
||||||
|
allCampaigns: [],
|
||||||
mapConfig: {
|
mapConfig: {
|
||||||
clusterOptions: {
|
clusterOptions: {
|
||||||
spiderfyOnMaxZoom: false,
|
spiderfyOnMaxZoom: false,
|
||||||
@@ -36,6 +37,13 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
|
campaignOptions() {
|
||||||
|
if (!this.allCampaigns) return [];
|
||||||
|
return this.allCampaigns.map(campaign => ({
|
||||||
|
value: campaign.id,
|
||||||
|
text: campaign.name
|
||||||
|
}));
|
||||||
|
},
|
||||||
filterOptions() {
|
filterOptions() {
|
||||||
return Object.entries(this.rimoTypeDefs).map(([value, defs]) => ({ value, ...defs }));
|
return Object.entries(this.rimoTypeDefs).map(([value, defs]) => ({ value, ...defs }));
|
||||||
},
|
},
|
||||||
@@ -78,10 +86,25 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
watch: {
|
||||||
|
selectedCampaign(newCampaignId) {
|
||||||
|
if (newCampaignId) {
|
||||||
|
this.fetchAllMapData();
|
||||||
|
} else {
|
||||||
|
this.mapMarkers = [];
|
||||||
|
this.fcpMarkers = [];
|
||||||
|
this.faults = {};
|
||||||
|
this.activeFilters = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.allCampaigns = window.TT_CONFIG?.ALL_CAMPAIGNS || [];
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
this.selectedCampaign = urlParams.get('preordercampaign_id');
|
const campaignIdParam = urlParams.get('preordercampaign_id');
|
||||||
if (this.selectedCampaign) await this.fetchAllMapData();
|
|
||||||
|
if (this.allCampaigns.length === 1) this.selectedCampaign = this.allCampaigns[0].id;
|
||||||
|
if (this.allCampaigns.length > 1 && campaignIdParam && this.allCampaigns.some(c => String(c.id) === campaignIdParam)) this.selectedCampaign = campaignIdParam;
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (window.TT_CONFIG?.ALL_USERS) {
|
if (window.TT_CONFIG?.ALL_USERS) {
|
||||||
@@ -116,6 +139,9 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.mapMarkers = [];
|
this.mapMarkers = [];
|
||||||
this.fcpMarkers = [];
|
this.fcpMarkers = [];
|
||||||
|
this.faults = {};
|
||||||
|
this.activeFilters = [];
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.fetchFaultData();
|
await this.fetchFaultData();
|
||||||
@@ -432,13 +458,21 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div style="height: 80vh; width: 100%; display: flex; flex-direction: column;">
|
<div style="height: 80vh; width: 100%; display: flex; flex-direction: column;">
|
||||||
<div v-if="!selectedCampaign" class="alert alert-warning m-3">
|
<tt-map ref="ttMap" :markers-data="filteredMapMarkers" :loading="isLoading" :config="mapConfig">
|
||||||
Bitte eine Kampagne über den URL-Parameter 'preordercampaign_id' auswählen (z.B. ?preordercampaign_id=44).
|
|
||||||
</div>
|
|
||||||
<tt-map v-else ref="ttMap" :markers-data="filteredMapMarkers" :loading="isLoading" :config="mapConfig">
|
|
||||||
<template v-slot:tools>
|
<template v-slot:tools>
|
||||||
<div class="map-filter-container">
|
<div class="map-filter-container">
|
||||||
<h6 class="mb-0 mr-2 font-weight-bold align-self-center">Filter:</h6>
|
<tt-select
|
||||||
|
v-model="selectedCampaign"
|
||||||
|
:options="campaignOptions"
|
||||||
|
label="Kampagne"
|
||||||
|
:sm="true"
|
||||||
|
:row="true"
|
||||||
|
:searchable="true"
|
||||||
|
style="min-width: 300px;"
|
||||||
|
></tt-select>
|
||||||
|
</div>
|
||||||
|
<div class="map-filter-container" v-if="selectedCampaign">
|
||||||
|
<h6 class="mr-2 font-weight-bold align-self-center">Filter:</h6>
|
||||||
<button v-for="filter in filterOptions"
|
<button v-for="filter in filterOptions"
|
||||||
:key="filter.value"
|
:key="filter.value"
|
||||||
@click="toggleFilter(filter.value)"
|
@click="toggleFilter(filter.value)"
|
||||||
@@ -463,7 +497,7 @@ Vue.component('PreorderRimoTypeMap', {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:legend>
|
<template v-slot:legend>
|
||||||
<div class="map-legend-container">
|
<div v-if="selectedCampaign" class="map-legend-container">
|
||||||
<h6>Legende</h6>
|
<h6>Legende</h6>
|
||||||
<div><strong>H:</strong> Homes (Wohneinheiten)</div>
|
<div><strong>H:</strong> Homes (Wohneinheiten)</div>
|
||||||
<div><strong>B:</strong> Bestellungen</div>
|
<div><strong>B:</strong> Bestellungen</div>
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ Vue.component('tt-map', {
|
|||||||
|
|
||||||
this.tileLayers.mapbox.streets = L.tileLayer(this.mapConfig.streetsTileUrl, { attribution: this.mapConfig.tileAttribution, maxZoom: 22, id: this.mapConfig.streetsTileId, tileSize: 512, zoomOffset: -1, accessToken: this.mapConfig.mapboxKey });
|
this.tileLayers.mapbox.streets = L.tileLayer(this.mapConfig.streetsTileUrl, { attribution: this.mapConfig.tileAttribution, maxZoom: 22, id: this.mapConfig.streetsTileId, tileSize: 512, zoomOffset: -1, accessToken: this.mapConfig.mapboxKey });
|
||||||
this.tileLayers.mapbox.satellite = L.tileLayer(this.mapConfig.satelliteTileUrl, { attribution: this.mapConfig.tileAttribution, maxZoom: 22, id: this.mapConfig.satelliteTileId, tileSize: 512, zoomOffset: -1, accessToken: this.mapConfig.mapboxKey });
|
this.tileLayers.mapbox.satellite = L.tileLayer(this.mapConfig.satelliteTileUrl, { attribution: this.mapConfig.tileAttribution, maxZoom: 22, id: this.mapConfig.satelliteTileId, tileSize: 512, zoomOffset: -1, accessToken: this.mapConfig.mapboxKey });
|
||||||
this.tileLayers.basemap.streets = L.tileLayer(this.mapConfig.basemapStreetsTileUrl, { attribution: this.mapConfig.basemapAttribution, maxZoom: 20 });
|
this.tileLayers.basemap.streets = L.tileLayer(this.mapConfig.basemapStreetsTileUrl, { attribution: this.mapConfig.basemapAttribution, maxZoom: 19 });
|
||||||
this.tileLayers.basemap.satellite = L.tileLayer(this.mapConfig.basemapSatelliteTileUrl, { attribution: this.mapConfig.basemapAttribution, maxZoom: 20 });
|
this.tileLayers.basemap.satellite = L.tileLayer(this.mapConfig.basemapSatelliteTileUrl, { attribution: this.mapConfig.basemapAttribution, maxZoom: 19 });
|
||||||
this.setActiveTileLayer();
|
this.setActiveTileLayer();
|
||||||
|
|
||||||
this.markerLayer = L.markerClusterGroup(this.mapConfig.clusterOptions);
|
this.markerLayer = L.markerClusterGroup(this.mapConfig.clusterOptions);
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ Vue.component('tt-page-title', {
|
|||||||
<div class="page-title-box">
|
<div class="page-title-box">
|
||||||
<div class="page-title-right">
|
<div class="page-title-right">
|
||||||
<ol class="breadcrumb m-0">
|
<ol class="breadcrumb m-0">
|
||||||
<li class="breadcrumb-item" v-for="item in path" :key="item.text">
|
<li v-for="(item, index) in path" :key="item.text">
|
||||||
|
<i v-if="index > 0" class="fa fa-chevron-right mx-1"></i>
|
||||||
<a :href="item.href">{{ item.text }}</a>
|
<a :href="item.href">{{ item.text }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|||||||
Reference in New Issue
Block a user