Show map with nuisance and water on status page
Leverages the new declarative map logic. Still missing a bunch of features
This commit is contained in:
parent
3bfcfff1eb
commit
203d2014b0
5 changed files with 107 additions and 16 deletions
17
api/api.go
17
api/api.go
|
|
@ -273,15 +273,24 @@ func parseTime(x string) (*time.Time, error) {
|
|||
}
|
||||
|
||||
type about struct {
|
||||
Environment string `json:"environment"`
|
||||
SentryDSN string `json:"sentry_dsn"`
|
||||
Version string `json:"version"`
|
||||
Environment string `json:"environment"`
|
||||
SentryDSN string `json:"sentry_dsn"`
|
||||
Tegola tegolaURLs `json:"tegola"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
type tegolaURLs struct {
|
||||
Nidus string `json:"nidus"`
|
||||
RMO string `json:"rmo"`
|
||||
}
|
||||
|
||||
func getRoot(ctx context.Context, r *http.Request, q resource.QueryParams) (*about, *nhttp.ErrorWithStatus) {
|
||||
return &about{
|
||||
Environment: config.Environment,
|
||||
SentryDSN: config.SentryDSNFrontend,
|
||||
Version: version,
|
||||
Tegola: tegolaURLs{
|
||||
Nidus: config.MakeURLTegola("/maps/nidus/{z}/{x}/{y}?id={organization_id}"),
|
||||
RMO: config.MakeURLTegola("/maps/rmo/{z}/{x}/{y}"),
|
||||
},
|
||||
Version: version,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,16 +67,18 @@
|
|||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="container my-4">
|
||||
<div class="container my-4" v-if="tegola">
|
||||
<!-- Search Box -->
|
||||
<div class="card search-box mb-4">
|
||||
<div class="card-body">
|
||||
<form class="row g-3 align-items-center" action="#" id="lookup-form">
|
||||
<div class="col-md-9">
|
||||
<!--
|
||||
<address-or-report-input
|
||||
name="address-or-report"
|
||||
placeholder="Enter a report ID, address, neighborhood, or zip code"
|
||||
></address-or-report-input>
|
||||
-->
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<span
|
||||
|
|
@ -132,15 +134,16 @@
|
|||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="map-container">
|
||||
<map-multipoint
|
||||
id="map"
|
||||
xmax="-118.0"
|
||||
ymax="37.0"
|
||||
xmin="-119.0"
|
||||
ymin="36.0"
|
||||
tegola="{{ .URL.Tegola }}"
|
||||
zoom="9"
|
||||
></map-multipoint>
|
||||
<Map class="map" tegola="tegola">
|
||||
<Layer
|
||||
id="nuisance"
|
||||
:paint="paintConfigNuisance"
|
||||
source="tegola"
|
||||
sourceLayer="nuisance_location"
|
||||
type="circle"
|
||||
/>
|
||||
<Source id="tegola" type="vector" :tiles="[tegola]" />
|
||||
</Map>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -159,7 +162,9 @@
|
|||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<!--
|
||||
<table-report />
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
|
|
@ -181,4 +186,37 @@
|
|||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>loading...</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
import Map from "@/map/Map.vue";
|
||||
import Layer, { MouseEvent } from "@/map/Layer.vue";
|
||||
import Source from "@/map/Source.vue";
|
||||
import { apiClient } from "@/client";
|
||||
import { useStoreAPI } from "@/store/api";
|
||||
|
||||
const storeAPI = useStoreAPI();
|
||||
const tegola = ref<string | null>(null);
|
||||
const paintConfigNuisance = {
|
||||
"circle-color": "#DC4535",
|
||||
"circle-radius": 7,
|
||||
"circle-stroke-color": "#9C1C28",
|
||||
"circle-stroke-width": 2,
|
||||
};
|
||||
const paintConfigWater = {
|
||||
"circle-color": "#0D6EfD",
|
||||
"circle-radius": 7,
|
||||
"circle-stroke-color": "#024AB6",
|
||||
"circle-stroke-width": 2,
|
||||
};
|
||||
onMounted(() => {
|
||||
const a = storeAPI.get().then((a) => {
|
||||
tegola.value = a.tegola.rmo;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
36
ts/store/api.ts
Normal file
36
ts/store/api.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
|
||||
import { apiClient } from "@/client";
|
||||
import { APIProperties } from "@/type/api";
|
||||
|
||||
export const useStoreAPI = defineStore("api", () => {
|
||||
// State
|
||||
const _response = ref<APIProperties | null>(null);
|
||||
const loading = ref(false);
|
||||
const ongoingFetch = ref<Promise<APIProperties> | null>(null);
|
||||
|
||||
// Actions
|
||||
async function doFetch(): Promise<APIProperties> {
|
||||
loading.value = true;
|
||||
const url = "/api";
|
||||
const resp = (await apiClient.JSONGet(url)) as APIProperties;
|
||||
return resp;
|
||||
}
|
||||
async function get(): Promise<APIProperties> {
|
||||
if (_response.value) {
|
||||
return _response.value;
|
||||
}
|
||||
if (ongoingFetch.value !== null) {
|
||||
return ongoingFetch.value;
|
||||
}
|
||||
ongoingFetch.value = doFetch().finally(() => {
|
||||
ongoingFetch.value = null;
|
||||
});
|
||||
return ongoingFetch.value;
|
||||
}
|
||||
return {
|
||||
// Actions
|
||||
get,
|
||||
};
|
||||
});
|
||||
|
|
@ -31,6 +31,16 @@ export class Address {
|
|||
public location?: Location,
|
||||
) {}
|
||||
}
|
||||
export interface TegolaURLs {
|
||||
nidus: string;
|
||||
rmo: string;
|
||||
}
|
||||
export interface APIProperties {
|
||||
environment: string;
|
||||
sentry_dsn: string;
|
||||
tegola: TegolaURLs;
|
||||
version: string;
|
||||
}
|
||||
export interface Bounds {
|
||||
min: Location;
|
||||
max: Location;
|
||||
|
|
|
|||
|
|
@ -137,8 +137,6 @@
|
|||
:cursor="mapCursor"
|
||||
class="map"
|
||||
:markers="[]"
|
||||
:organizationId="session.organization?.id ?? 1"
|
||||
:tegola="session.urls?.tegola ?? ''"
|
||||
>
|
||||
<Layer
|
||||
@click="doClickMap"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue