@dative-gpi/foundation-shared-components 1.0.137 → 1.0.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/images/map/snow.png +0 -0
- package/components/FSCheckbox.vue +1 -0
- package/components/FSChipGroup.vue +69 -0
- package/components/FSRadio.vue +1 -0
- package/components/FSSlider.vue +2 -1
- package/components/FSSwitch.vue +38 -44
- package/components/fields/FSBaseField.vue +1 -0
- package/components/fields/FSEntityFieldUI.vue +7 -4
- package/components/fields/FSRichTextField.vue +2 -1
- package/components/fields/FSTranslateRichTextField.vue +3 -1
- package/components/map/FSMap.vue +74 -126
- package/components/map/FSMapMarker.vue +6 -6
- package/components/map/FSMapMarkerClusterGroup.vue +1 -1
- package/components/map/FSMapOverlay.vue +14 -11
- package/components/map/FSMapTileLayer.vue +14 -8
- package/components/selects/FSSelectMapLayer.vue +68 -0
- package/components/tiles/FSTile.vue +42 -38
- package/models/map.ts +12 -10
- package/package.json +4 -4
- package/styles/components/fs_map.scss +46 -10
- package/tools/index.ts +1 -0
- package/tools/reportsTools.ts +38 -0
|
Binary file
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSWrapGroup
|
|
3
|
+
v-if="$props.variant === 'wrap'"
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
>
|
|
6
|
+
<FSChip
|
|
7
|
+
v-for="(label, index) in $props.labels"
|
|
8
|
+
:key="index"
|
|
9
|
+
:variant="$props.chipVariant"
|
|
10
|
+
:color="$props.color"
|
|
11
|
+
:label="label"
|
|
12
|
+
/>
|
|
13
|
+
<slot />
|
|
14
|
+
</FSWrapGroup>
|
|
15
|
+
<FSSlideGroup
|
|
16
|
+
v-if="$props.variant === 'slide'"
|
|
17
|
+
v-bind="$attrs"
|
|
18
|
+
>
|
|
19
|
+
<FSChip
|
|
20
|
+
v-for="(label, index) in $props.labels"
|
|
21
|
+
:key="index"
|
|
22
|
+
:variant="$props.chipVariant"
|
|
23
|
+
:color="$props.color"
|
|
24
|
+
:label="label"
|
|
25
|
+
/>
|
|
26
|
+
<slot />
|
|
27
|
+
</FSSlideGroup>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts">
|
|
31
|
+
import { defineComponent, type PropType } from "vue";
|
|
32
|
+
|
|
33
|
+
import { type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
|
|
34
|
+
|
|
35
|
+
import FSSlideGroup from "./FSSlideGroup.vue";
|
|
36
|
+
import FSWrapGroup from "./FSWrapGroup.vue";
|
|
37
|
+
import FSChip from "./FSChip.vue";
|
|
38
|
+
|
|
39
|
+
export default defineComponent({
|
|
40
|
+
name: "FSChipGroup",
|
|
41
|
+
components: {
|
|
42
|
+
FSSlideGroup,
|
|
43
|
+
FSWrapGroup,
|
|
44
|
+
FSChip
|
|
45
|
+
},
|
|
46
|
+
props: {
|
|
47
|
+
labels: {
|
|
48
|
+
type: Array as PropType<string[]>,
|
|
49
|
+
required: false,
|
|
50
|
+
default: () => []
|
|
51
|
+
},
|
|
52
|
+
variant: {
|
|
53
|
+
type: String as PropType<"wrap" | "slide">,
|
|
54
|
+
required: false,
|
|
55
|
+
default: "wrap"
|
|
56
|
+
},
|
|
57
|
+
chipVariant: {
|
|
58
|
+
type: String as PropType<"standard" | "full" | "borderless">,
|
|
59
|
+
required: false,
|
|
60
|
+
default: "full"
|
|
61
|
+
},
|
|
62
|
+
color: {
|
|
63
|
+
type: String as PropType<ColorBase>,
|
|
64
|
+
required: false,
|
|
65
|
+
default: ColorEnum.Light
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
</script>
|
package/components/FSRadio.vue
CHANGED
package/components/FSSlider.vue
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
:elevation="0"
|
|
36
36
|
:tickSize="4"
|
|
37
37
|
:modelValue="$props.modelValue ?? undefined"
|
|
38
|
-
@update:modelValue="
|
|
38
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
39
39
|
v-bind="$attrs"
|
|
40
40
|
>
|
|
41
41
|
<template
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
v-if="$props.description"
|
|
56
56
|
class="fs-slider-description"
|
|
57
57
|
font="text-overline"
|
|
58
|
+
:lineClamp="2"
|
|
58
59
|
:style="style"
|
|
59
60
|
>
|
|
60
61
|
{{ $props.description }}
|
package/components/FSSwitch.vue
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
width="hug"
|
|
4
|
-
align="top-left"
|
|
5
|
-
gap="16px"
|
|
2
|
+
<FSCol
|
|
6
3
|
padding="8px 0px"
|
|
7
|
-
:wrap="false"
|
|
8
4
|
>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
>
|
|
5
|
+
<FSRow
|
|
6
|
+
gap="16px"
|
|
7
|
+
:wrap="false"
|
|
8
|
+
>
|
|
9
|
+
<v-switch
|
|
10
|
+
v-if="variant == 'left'"
|
|
11
|
+
class="fs-switch"
|
|
12
|
+
hide-details
|
|
13
|
+
inset
|
|
14
|
+
:validateOn="validateOn"
|
|
15
|
+
:rules="$props.rules"
|
|
16
|
+
:ripple="false"
|
|
17
|
+
:style="style"
|
|
18
|
+
:modelValue="$props.modelValue"
|
|
19
|
+
@update:modelValue="onToggle"
|
|
20
|
+
v-bind="$attrs"
|
|
21
|
+
/>
|
|
22
|
+
<FSCol>
|
|
27
23
|
<FSSpan
|
|
28
24
|
v-if="$props.label"
|
|
29
25
|
class="fs-switch-label"
|
|
@@ -41,33 +37,31 @@
|
|
|
41
37
|
class="fs-switch-description"
|
|
42
38
|
font="text-overline"
|
|
43
39
|
:style="style"
|
|
40
|
+
:lineClamp="2"
|
|
44
41
|
>
|
|
45
42
|
{{ $props.description }}
|
|
46
43
|
</FSSpan>
|
|
47
44
|
</slot>
|
|
48
|
-
<slot
|
|
49
|
-
name="footer"
|
|
50
|
-
/>
|
|
51
45
|
</FSCol>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
46
|
+
<FSRow
|
|
47
|
+
v-if="variant == 'right'"
|
|
48
|
+
align="center-right"
|
|
49
|
+
>
|
|
50
|
+
<v-switch
|
|
51
|
+
class="fs-switch"
|
|
52
|
+
hide-details
|
|
53
|
+
inset
|
|
54
|
+
:validateOn="validateOn"
|
|
55
|
+
:rules="$props.rules"
|
|
56
|
+
:ripple="false"
|
|
57
|
+
:style="style"
|
|
58
|
+
:modelValue="$props.modelValue"
|
|
59
|
+
@update:modelValue="onToggle"
|
|
60
|
+
v-bind="$attrs"
|
|
61
|
+
/>
|
|
62
|
+
</FSRow>
|
|
69
63
|
</FSRow>
|
|
70
|
-
</
|
|
64
|
+
</FSCol>
|
|
71
65
|
</template>
|
|
72
66
|
|
|
73
67
|
<script lang="ts">
|
|
@@ -14,18 +14,20 @@
|
|
|
14
14
|
:wrap="false"
|
|
15
15
|
>
|
|
16
16
|
<FSSelectField
|
|
17
|
+
:editable="$props.editable"
|
|
18
|
+
:items="actualEntityTypes"
|
|
17
19
|
:hideHeader="true"
|
|
20
|
+
:clearable="false"
|
|
18
21
|
:modelValue="$props.entityType"
|
|
19
22
|
@update:modelValue="$emit('update:entityType', $event)"
|
|
20
|
-
:items="actualEntityTypes"
|
|
21
|
-
:clearable="false"
|
|
22
23
|
/>
|
|
23
24
|
<template
|
|
24
25
|
v-if="itemsCount > 0"
|
|
25
26
|
>
|
|
26
27
|
<FSButton
|
|
27
|
-
:label="$tr('ui.common.edit', 'Edit')"
|
|
28
28
|
icon="mdi-pencil"
|
|
29
|
+
:label="$tr('ui.common.edit', 'Edit')"
|
|
30
|
+
:editable="$props.editable"
|
|
29
31
|
@click="$emit('click:select')"
|
|
30
32
|
/>
|
|
31
33
|
</template>
|
|
@@ -33,8 +35,9 @@
|
|
|
33
35
|
v-else
|
|
34
36
|
>
|
|
35
37
|
<FSButton
|
|
36
|
-
:label="$tr('ui.common.select', 'Select')"
|
|
37
38
|
icon="mdi-plus-circle-multiple-outline"
|
|
39
|
+
:label="$tr('ui.common.select', 'Select')"
|
|
40
|
+
:editable="$props.editable"
|
|
38
41
|
@click="$emit('click:select')"
|
|
39
42
|
/>
|
|
40
43
|
</template>
|
package/components/map/FSMap.vue
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
v-if="map"
|
|
15
15
|
>
|
|
16
16
|
<FSMapTileLayer
|
|
17
|
-
:
|
|
17
|
+
:layers="actualLayer"
|
|
18
18
|
/>
|
|
19
19
|
<FSMapMarker
|
|
20
20
|
v-if="gpsPosition"
|
|
@@ -22,38 +22,7 @@
|
|
|
22
22
|
:color="ColorEnum.Primary"
|
|
23
23
|
:latlng="gpsPosition"
|
|
24
24
|
/>
|
|
25
|
-
|
|
26
|
-
<FSMapFeatureGroup
|
|
27
|
-
v-if="$props.areas"
|
|
28
|
-
:expected-layers="$props.areas.length"
|
|
29
|
-
@update:bounds="(bounds) => areaGroupBounds = bounds"
|
|
30
|
-
>
|
|
31
|
-
<FSMapPolygon
|
|
32
|
-
v-for="area in areas"
|
|
33
|
-
:key="area.id"
|
|
34
|
-
:color="area.color"
|
|
35
|
-
:latlngs="area.coordinates.map((coord) => ({lat: coord.latitude, lng: coord.longitude}))"
|
|
36
|
-
@click="$emit('update:selectedAreaId', area.id)"
|
|
37
|
-
/>
|
|
38
|
-
</FSMapFeatureGroup>
|
|
39
|
-
|
|
40
|
-
<FSMapMarkerClusterGroup
|
|
41
|
-
v-if="$props.locations"
|
|
42
|
-
:expected-layers="$props.locations.length"
|
|
43
|
-
:disableClusteringAtZoom="defaultZoom"
|
|
44
|
-
@update:bounds="(bounds) => locationGroupBounds = bounds"
|
|
45
|
-
>
|
|
46
|
-
<FSMapMarker
|
|
47
|
-
v-for="location in $props.locations"
|
|
48
|
-
:selected="location.id === $props.selectedLocationId"
|
|
49
|
-
:key="location.id"
|
|
50
|
-
:label="location.label"
|
|
51
|
-
:color="location.color ?? ColorEnum.Primary"
|
|
52
|
-
:icon="location.icon ?? 'mdi-map-marker'"
|
|
53
|
-
:latlng="{lat: location.address.latitude, lng: location.address.longitude}"
|
|
54
|
-
@click="$emit('update:selectedLocationId', location.id)"
|
|
55
|
-
/>
|
|
56
|
-
</FSMapMarkerClusterGroup>
|
|
25
|
+
<slot />
|
|
57
26
|
</template>
|
|
58
27
|
</div>
|
|
59
28
|
|
|
@@ -100,6 +69,7 @@
|
|
|
100
69
|
</FSCol>
|
|
101
70
|
|
|
102
71
|
<FSMapOverlay
|
|
72
|
+
v-if="overlaySlots && Object.keys(overlaySlots).length"
|
|
103
73
|
:mode="$props.overlayMode"
|
|
104
74
|
@update:mode="$emit('update:overlayMode', $event)"
|
|
105
75
|
@update:height="(height) => overlayHeight = height"
|
|
@@ -125,10 +95,9 @@ import type {} from "leaflet.markercluster";
|
|
|
125
95
|
import { map as createMap, control, tileLayer, latLngBounds, latLng, type LatLng, type FitBoundsOptions, type ZoomPanOptions, type LatLngBounds } from "leaflet";
|
|
126
96
|
|
|
127
97
|
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
128
|
-
import { type FSArea } from '@dative-gpi/foundation-shared-domain/models';
|
|
129
98
|
|
|
130
99
|
import { useBreakpoints, useColors, useSlots } from "../../composables";
|
|
131
|
-
import { ColorEnum,
|
|
100
|
+
import { ColorEnum, MapLayers, MapOverlayPositions, type MapLayer } from "../../models";
|
|
132
101
|
|
|
133
102
|
import FSMapLayerButton from "./FSMapLayerButton.vue";
|
|
134
103
|
import FSMapOverlay from "./FSMapOverlay.vue";
|
|
@@ -138,19 +107,12 @@ import FSCol from "../FSCol.vue";
|
|
|
138
107
|
|
|
139
108
|
import FSMapMarker from "./FSMapMarker.vue";
|
|
140
109
|
import FSMapTileLayer from "./FSMapTileLayer.vue";
|
|
141
|
-
import FSMapFeatureGroup from "./FSMapFeatureGroup.vue";
|
|
142
|
-
import FSMapMarkerClusterGroup from "./FSMapMarkerClusterGroup.vue";
|
|
143
|
-
import FSMapPolygon from "./FSMapPolygon.vue";
|
|
144
110
|
|
|
145
111
|
export default defineComponent({
|
|
146
112
|
name: "FSMap",
|
|
147
113
|
components: {
|
|
148
114
|
FSMapMarker,
|
|
149
115
|
FSMapTileLayer,
|
|
150
|
-
FSMapFeatureGroup,
|
|
151
|
-
FSMapMarkerClusterGroup,
|
|
152
|
-
FSMapPolygon,
|
|
153
|
-
|
|
154
116
|
FSMapLayerButton,
|
|
155
117
|
FSMapOverlay,
|
|
156
118
|
FSButton,
|
|
@@ -174,9 +136,9 @@ export default defineComponent({
|
|
|
174
136
|
default: false
|
|
175
137
|
},
|
|
176
138
|
overlayMode: {
|
|
177
|
-
type: String as PropType<
|
|
139
|
+
type: String as PropType<MapOverlayPositions>,
|
|
178
140
|
required: false,
|
|
179
|
-
default:
|
|
141
|
+
default: MapOverlayPositions.Collapse
|
|
180
142
|
},
|
|
181
143
|
showMyLocation: {
|
|
182
144
|
type: Boolean,
|
|
@@ -194,39 +156,29 @@ export default defineComponent({
|
|
|
194
156
|
default: false
|
|
195
157
|
},
|
|
196
158
|
center: {
|
|
197
|
-
type: Array as PropType<number[]>,
|
|
159
|
+
type: Array as PropType<number[] | null>,
|
|
198
160
|
required: false,
|
|
199
|
-
default:
|
|
200
|
-
},
|
|
201
|
-
locations: {
|
|
202
|
-
type: Array as PropType<FSLocation[]>,
|
|
203
|
-
required: false,
|
|
204
|
-
default: () => [],
|
|
161
|
+
default: null
|
|
205
162
|
},
|
|
206
|
-
|
|
207
|
-
type:
|
|
163
|
+
bounds: {
|
|
164
|
+
type: Object as PropType<LatLngBounds | null>,
|
|
208
165
|
required: false,
|
|
209
|
-
default:
|
|
166
|
+
default: null
|
|
210
167
|
},
|
|
211
168
|
currentLayer: {
|
|
212
|
-
type: String as PropType<
|
|
169
|
+
type: String as PropType<MapLayers>,
|
|
213
170
|
required: false,
|
|
214
|
-
default:
|
|
171
|
+
default: MapLayers.Map
|
|
215
172
|
},
|
|
216
173
|
allowedLayers: {
|
|
217
|
-
type: Array as PropType<
|
|
174
|
+
type: Array as PropType<MapLayers[]>,
|
|
218
175
|
required: false,
|
|
219
|
-
default: () => [
|
|
176
|
+
default: () => [MapLayers.Map, MapLayers.Imagery]
|
|
220
177
|
},
|
|
221
|
-
|
|
222
|
-
type:
|
|
178
|
+
dirtyZoom: {
|
|
179
|
+
type: Number,
|
|
223
180
|
required: false,
|
|
224
|
-
default:
|
|
225
|
-
},
|
|
226
|
-
selectedAreaId: {
|
|
227
|
-
type: String as PropType<string | null>,
|
|
228
|
-
required: false,
|
|
229
|
-
default: null
|
|
181
|
+
default: 16
|
|
230
182
|
}
|
|
231
183
|
},
|
|
232
184
|
emits: ["update:modelValue", "update:selectedLocationId", "update:selectedAreaId", 'update:overlayMode', 'update:currentLayer', "click:latlng"],
|
|
@@ -246,7 +198,7 @@ export default defineComponent({
|
|
|
246
198
|
|
|
247
199
|
provide('map', map);
|
|
248
200
|
|
|
249
|
-
const defaultZoom =
|
|
201
|
+
const defaultZoom = ref(props.dirtyZoom);
|
|
250
202
|
const mapResizeObserver = new ResizeObserver(() => {
|
|
251
203
|
if(!map.value) {
|
|
252
204
|
return;
|
|
@@ -256,29 +208,53 @@ export default defineComponent({
|
|
|
256
208
|
|
|
257
209
|
const mapLayers: MapLayer[] = [
|
|
258
210
|
{
|
|
259
|
-
name:
|
|
211
|
+
name: MapLayers.Map,
|
|
260
212
|
label: $tr("ui.map-layer.map", "Map"),
|
|
261
213
|
image: new URL("../../assets/images/map/map.png", import.meta.url).href,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
214
|
+
layers: [
|
|
215
|
+
tileLayer(`https://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&key=${import.meta.env.VITE_GOOGLE_MAPS_API_KEY ?? ""}`, {
|
|
216
|
+
maxZoom: 22,
|
|
217
|
+
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
|
|
218
|
+
attribution: '© Google Map Data',
|
|
219
|
+
className: 'fs-map-tile-base-layer'
|
|
220
|
+
})
|
|
221
|
+
]
|
|
267
222
|
},
|
|
268
223
|
{
|
|
269
|
-
name:
|
|
224
|
+
name: MapLayers.Imagery,
|
|
270
225
|
label: $tr("ui.map-layer.imagery", "Imagery"),
|
|
271
226
|
image: new URL("../../assets/images/map/imagery.png", import.meta.url).href,
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
227
|
+
layers: [
|
|
228
|
+
tileLayer(`https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}&key=${import.meta.env.VITE_GOOGLE_MAPS_API_KEY ?? ""}`, {
|
|
229
|
+
maxZoom: 22,
|
|
230
|
+
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
|
|
231
|
+
attribution: '© Google Map Data',
|
|
232
|
+
className: 'fs-map-tile-base-layer'
|
|
233
|
+
})
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: MapLayers.Snow,
|
|
238
|
+
label: $tr("ui.map-layer.snow", "Snow ski map"),
|
|
239
|
+
image: new URL("../../assets/images/map/snow.png", import.meta.url).href,
|
|
240
|
+
layers: [
|
|
241
|
+
tileLayer(`https://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&key=${import.meta.env.VITE_GOOGLE_MAPS_API_KEY ?? ""}`, {
|
|
242
|
+
maxZoom: 22,
|
|
243
|
+
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
|
|
244
|
+
attribution: '© Google Map Data',
|
|
245
|
+
className: 'fs-map-tile-base-layer fs-map-tile-grayscale-layer'
|
|
246
|
+
}),
|
|
247
|
+
tileLayer(`https://tiles.opensnowmap.org/pistes/{z}/{x}/{y}.png`, {
|
|
248
|
+
maxZoom: 18,
|
|
249
|
+
attribution: 'Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors & ODbL, © <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
|
|
250
|
+
className: 'fs-map-tile-base-layer'
|
|
251
|
+
})
|
|
252
|
+
]
|
|
277
253
|
}
|
|
278
254
|
];
|
|
279
255
|
|
|
280
256
|
const bottomOffset = computed(() => {
|
|
281
|
-
if (props.overlayMode !==
|
|
257
|
+
if (props.overlayMode !== MapOverlayPositions.Expand && overlayHeight.value && isExtraSmall.value) {
|
|
282
258
|
return overlayHeight.value;
|
|
283
259
|
}
|
|
284
260
|
return 0;
|
|
@@ -300,20 +276,7 @@ export default defineComponent({
|
|
|
300
276
|
}));
|
|
301
277
|
|
|
302
278
|
const actualLayer = computed(() => {
|
|
303
|
-
return mapLayers.find((
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
const bounds = computed<LatLngBounds | null>(() => {
|
|
307
|
-
if(!locationGroupBounds.value && !areaGroupBounds.value) {
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
let bounds = locationGroupBounds.value;
|
|
311
|
-
if(bounds && areaGroupBounds.value) {
|
|
312
|
-
bounds.extend(areaGroupBounds.value);
|
|
313
|
-
} else if(areaGroupBounds.value) {
|
|
314
|
-
bounds = areaGroupBounds.value;
|
|
315
|
-
}
|
|
316
|
-
return bounds as LatLngBounds;
|
|
279
|
+
return mapLayers.find((mapLayer) => mapLayer.name === props.currentLayer)?.layers ?? mapLayers[0].layers;
|
|
317
280
|
});
|
|
318
281
|
|
|
319
282
|
const overlaySlots = computed(() => {
|
|
@@ -332,7 +295,7 @@ export default defineComponent({
|
|
|
332
295
|
return map.value.unproject(targetPoint, zoom);
|
|
333
296
|
}
|
|
334
297
|
|
|
335
|
-
const flyTo = (lat: number, lng: number, zoom: number = defaultZoom, options?: ZoomPanOptions) => {
|
|
298
|
+
const flyTo = (lat: number, lng: number, zoom: number = defaultZoom.value, options?: ZoomPanOptions) => {
|
|
336
299
|
if(!map.value) {
|
|
337
300
|
return;
|
|
338
301
|
}
|
|
@@ -360,7 +323,7 @@ export default defineComponent({
|
|
|
360
323
|
if(!map.value) {
|
|
361
324
|
return;
|
|
362
325
|
}
|
|
363
|
-
map.value.setView(calculateTargetPosition(latLng(lat, lng)), zoom);
|
|
326
|
+
map.value.setView(calculateTargetPosition(latLng(lat, lng), zoom), zoom);
|
|
364
327
|
}
|
|
365
328
|
|
|
366
329
|
const fitBounds = (bounds: LatLngBounds, options?: FitBoundsOptions) => {
|
|
@@ -394,11 +357,12 @@ export default defineComponent({
|
|
|
394
357
|
minZoom: 2,
|
|
395
358
|
maxZoom: 22,
|
|
396
359
|
maxBounds: latLngBounds(latLng(-90, -180), latLng(90, 180)),
|
|
397
|
-
maxBoundsViscosity: 1.0
|
|
360
|
+
maxBoundsViscosity: 1.0,
|
|
361
|
+
zoom: defaultZoom.value,
|
|
362
|
+
center: props.center ? latLng(props.center[0], props.center[1]) : latLng(48.85782, 2.29521)
|
|
398
363
|
};
|
|
399
364
|
|
|
400
365
|
map.value = markRaw(createMap(leafletContainer.value, mapOptions));
|
|
401
|
-
setView(props.center[0], props.center[1], defaultZoom);
|
|
402
366
|
|
|
403
367
|
map.value.on('click', (e: L.LeafletMouseEvent) => {
|
|
404
368
|
emit('click:latlng', e.latlng);
|
|
@@ -428,42 +392,26 @@ export default defineComponent({
|
|
|
428
392
|
mapResizeObserver.disconnect();
|
|
429
393
|
});
|
|
430
394
|
|
|
431
|
-
watch (() => props.center, (
|
|
432
|
-
if(!map.value) {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
setView(center[0], center[1], defaultZoom);
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
watch (() => props.selectedLocationId, (selectedLocationId) => {
|
|
439
|
-
if(!map.value) {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
const selectedLocation = props.locations.find((location) => location.id === selectedLocationId);
|
|
443
|
-
if(!selectedLocation) {
|
|
395
|
+
watch ([() => props.center, () => map.value], () => {
|
|
396
|
+
if(!map.value || !props.center) {
|
|
444
397
|
return;
|
|
445
398
|
}
|
|
446
|
-
|
|
399
|
+
setView(props.center[0], props.center[1], defaultZoom.value);
|
|
447
400
|
}, { immediate: true });
|
|
448
401
|
|
|
449
|
-
watch(() => props.
|
|
450
|
-
if(!map.value) {
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
const selectedArea = props.areas.find((area) => area.id === selectedAreaId);
|
|
454
|
-
if(!selectedArea) {
|
|
402
|
+
watch([() => props.bounds, () => map.value], () => {
|
|
403
|
+
if(!map.value || !props.bounds) {
|
|
455
404
|
return;
|
|
456
405
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}, { immediate: true });
|
|
406
|
+
fitBounds(props.bounds, { maxZoom: defaultZoom.value });
|
|
407
|
+
});
|
|
460
408
|
|
|
461
|
-
watch(
|
|
462
|
-
|
|
463
|
-
|
|
409
|
+
watch(() => props.dirtyZoom, (newZoom) => {
|
|
410
|
+
defaultZoom.value = newZoom;
|
|
411
|
+
if(map.value) {
|
|
412
|
+
map.value.setZoom(newZoom);
|
|
464
413
|
}
|
|
465
|
-
|
|
466
|
-
});
|
|
414
|
+
}, { immediate: true });
|
|
467
415
|
|
|
468
416
|
return {
|
|
469
417
|
ColorEnum,
|
|
@@ -82,20 +82,20 @@ export default {
|
|
|
82
82
|
iconSize: [size, size],
|
|
83
83
|
iconAnchor: [size / 2, size / 2],
|
|
84
84
|
});
|
|
85
|
-
} else if(props.variant === 'location'
|
|
85
|
+
} else if(props.variant === 'location') {
|
|
86
86
|
const size = 36;
|
|
87
87
|
icon = divIcon({
|
|
88
|
-
html: locationMarkerHtml(props.icon, getColors(props.color).base, props.label),
|
|
88
|
+
html: locationMarkerHtml(props.icon ?? "mdi-map-marker", getColors(props.color).base, props.label),
|
|
89
89
|
iconSize: [size, size],
|
|
90
|
-
className: props.selected ? 'fs-map-location fs-map-location-selected' : 'fs-map-location',
|
|
90
|
+
className: props.selected ? 'fs-map-marker fs-map-location fs-map-location-selected' : 'fs-map-marker fs-map-location',
|
|
91
91
|
iconAnchor: [size / 2, size / 2],
|
|
92
92
|
});
|
|
93
93
|
} else {
|
|
94
|
-
const size =
|
|
94
|
+
const size = 16;
|
|
95
95
|
icon = divIcon({
|
|
96
|
-
html: pinMarkerHtml(getColors(props.color).base),
|
|
96
|
+
html: pinMarkerHtml(getColors(props.color).base, props.label),
|
|
97
97
|
iconSize: [size, size],
|
|
98
|
-
className: props.selected ? 'fs-map-
|
|
98
|
+
className: props.selected ? 'fs-map-marker fs-map-pin fs-map-pin-selected' : 'fs-map-marker fs-map-pin',
|
|
99
99
|
iconAnchor: [size / 2, size / 2],
|
|
100
100
|
});
|
|
101
101
|
}
|
|
@@ -45,7 +45,7 @@ export default {
|
|
|
45
45
|
|
|
46
46
|
return divIcon({
|
|
47
47
|
html: clusterMarkerHtml(cluster.getChildCount()),
|
|
48
|
-
className: 'fs-map-
|
|
48
|
+
className: 'fs-map-marker fs-map-cluster-marker',
|
|
49
49
|
iconSize: [size, size],
|
|
50
50
|
iconAnchor: [size / 2, size / 2],
|
|
51
51
|
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-overlay
|
|
3
3
|
v-if="isExtraSmall"
|
|
4
|
-
:modelValue="$props.mode ===
|
|
4
|
+
:modelValue="$props.mode === MapOverlayPositions.Expand"
|
|
5
5
|
:contained="true"
|
|
6
|
-
@click="$emit('update:mode',
|
|
6
|
+
@click="$emit('update:mode', MapOverlayPositions.Collapse)"
|
|
7
7
|
zIndex="0"
|
|
8
8
|
/>
|
|
9
9
|
<div
|
|
10
10
|
v-show="isExtraSmall"
|
|
11
11
|
ref="mobileOverlayWrapper"
|
|
12
12
|
class="fs-map-overlay-mobile"
|
|
13
|
-
:style="{ height: $props.mode ===
|
|
13
|
+
:style="{ height: $props.mode === MapOverlayPositions.Expand ? '90%' : ($props.mode === MapOverlayPositions.Half ? '60%' : 'auto') }"
|
|
14
14
|
>
|
|
15
15
|
<FSCard
|
|
16
16
|
width="100%"
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
@mousedown="onClick"
|
|
30
30
|
>
|
|
31
31
|
<FSIcon>
|
|
32
|
-
{{ $props.mode ===
|
|
32
|
+
{{ $props.mode === MapOverlayPositions.Expand ? 'mdi-chevron-down' : 'mdi-chevron-up' }}
|
|
33
33
|
</FSIcon>
|
|
34
34
|
</FSRow>
|
|
35
35
|
<slot
|
|
36
|
-
v-if="$props.mode ===
|
|
36
|
+
v-if="$props.mode === MapOverlayPositions.Collapse"
|
|
37
37
|
name="collapsed"
|
|
38
38
|
/>
|
|
39
39
|
<FSCol
|
|
40
|
-
v-if="$props.mode !==
|
|
40
|
+
v-if="$props.mode !== MapOverlayPositions.Collapse"
|
|
41
41
|
height="fill"
|
|
42
42
|
style="min-height: 0;"
|
|
43
43
|
>
|
|
@@ -70,6 +70,8 @@ import { defineComponent, type PropType, onUnmounted, onMounted, ref } from "vue
|
|
|
70
70
|
|
|
71
71
|
import { useBreakpoints } from "../../composables";
|
|
72
72
|
|
|
73
|
+
import { MapOverlayPositions } from '@dative-gpi/foundation-shared-components/models';
|
|
74
|
+
|
|
73
75
|
import FSCard from "../FSCard.vue";
|
|
74
76
|
import FSIcon from "../FSIcon.vue";
|
|
75
77
|
import FSCol from "../FSCol.vue";
|
|
@@ -85,9 +87,9 @@ export default defineComponent({
|
|
|
85
87
|
},
|
|
86
88
|
props: {
|
|
87
89
|
mode: {
|
|
88
|
-
type: String as PropType<
|
|
90
|
+
type: String as PropType<MapOverlayPositions>,
|
|
89
91
|
required: false,
|
|
90
|
-
default:
|
|
92
|
+
default: MapOverlayPositions.Collapse
|
|
91
93
|
}
|
|
92
94
|
},
|
|
93
95
|
emits: ["update:mode", "update:height", "update:width"],
|
|
@@ -101,11 +103,11 @@ export default defineComponent({
|
|
|
101
103
|
const desktopResizeObserver = ref<ResizeObserver | null>(null);
|
|
102
104
|
|
|
103
105
|
const onClick = (): void => {
|
|
104
|
-
if (props.mode ===
|
|
105
|
-
emit("update:mode",
|
|
106
|
+
if (props.mode === MapOverlayPositions.Expand) {
|
|
107
|
+
emit("update:mode", MapOverlayPositions.Collapse);
|
|
106
108
|
return;
|
|
107
109
|
}
|
|
108
|
-
emit("update:mode",
|
|
110
|
+
emit("update:mode", MapOverlayPositions.Expand);
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
onMounted(() => {
|
|
@@ -144,6 +146,7 @@ export default defineComponent({
|
|
|
144
146
|
return {
|
|
145
147
|
mobileOverlayWrapper,
|
|
146
148
|
isTouchScreenEnabled,
|
|
149
|
+
MapOverlayPositions,
|
|
147
150
|
desktopOverlay,
|
|
148
151
|
isExtraSmall,
|
|
149
152
|
onClick
|
|
@@ -12,15 +12,15 @@ import { MAP } from './keys';
|
|
|
12
12
|
export default {
|
|
13
13
|
name: 'FSMapTileLayer',
|
|
14
14
|
props: {
|
|
15
|
-
|
|
16
|
-
type: Object as PropType<Layer>,
|
|
15
|
+
layers: {
|
|
16
|
+
type: Object as PropType<Layer[]>,
|
|
17
17
|
required: false
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
setup(props) {
|
|
21
21
|
const map = inject<Ref<Map | null>>(MAP);
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
let lastLayers = props.layers;
|
|
24
24
|
|
|
25
25
|
if(!map) {
|
|
26
26
|
throw new Error('FSMapTileLayer must be used inside a FSMap component');
|
|
@@ -31,20 +31,26 @@ export default {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const updateLayer = () => {
|
|
34
|
-
if (!props.
|
|
34
|
+
if (!props.layers || !map.value) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
if(
|
|
39
|
-
|
|
38
|
+
if(lastLayers) {
|
|
39
|
+
lastLayers.forEach(layer => {
|
|
40
|
+
layer.removeFrom(map.value!);
|
|
41
|
+
});
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
lastLayers = [];
|
|
45
|
+
|
|
46
|
+
props.layers.forEach(layer => {
|
|
47
|
+
lastLayers?.push(layer.addTo(map.value!));
|
|
48
|
+
});
|
|
43
49
|
};
|
|
44
50
|
|
|
45
51
|
onMounted(updateLayer);
|
|
46
52
|
|
|
47
|
-
watch(() => props.
|
|
53
|
+
watch(() => props.layers, updateLayer);
|
|
48
54
|
}
|
|
49
55
|
};
|
|
50
56
|
</script>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FSSelectField
|
|
3
|
+
:items="items"
|
|
4
|
+
:modelValue="$props.modelValue"
|
|
5
|
+
@update:modelValue="$emit('update:modelValue', $event)"
|
|
6
|
+
v-bind="$attrs"
|
|
7
|
+
>
|
|
8
|
+
<template
|
|
9
|
+
#item-prepend="{ item }"
|
|
10
|
+
>
|
|
11
|
+
<FSIcon
|
|
12
|
+
:icon="item.icon"
|
|
13
|
+
/>
|
|
14
|
+
</template>
|
|
15
|
+
</FSSelectField>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="ts">
|
|
19
|
+
import type { PropType} from "vue";
|
|
20
|
+
import { defineComponent } from "vue";
|
|
21
|
+
|
|
22
|
+
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
23
|
+
|
|
24
|
+
import { MapLayers } from '@dative-gpi/foundation-shared-components/models';
|
|
25
|
+
|
|
26
|
+
import FSSelectField from "../fields/FSSelectField.vue";
|
|
27
|
+
import FSIcon from '@dative-gpi/foundation-shared-components/components/FSIcon.vue';
|
|
28
|
+
|
|
29
|
+
export default defineComponent({
|
|
30
|
+
name: "FSSelectMapLayer",
|
|
31
|
+
components: {
|
|
32
|
+
FSIcon,
|
|
33
|
+
FSSelectField
|
|
34
|
+
},
|
|
35
|
+
props: {
|
|
36
|
+
modelValue: {
|
|
37
|
+
type: [String, Array] as PropType<MapLayers | MapLayers[]>,
|
|
38
|
+
required: false
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
emits: ["update:modelValue"],
|
|
42
|
+
setup() {
|
|
43
|
+
const { $tr } = useTranslationsProvider();
|
|
44
|
+
|
|
45
|
+
const items = [
|
|
46
|
+
{
|
|
47
|
+
id: MapLayers.Map,
|
|
48
|
+
icon: 'mdi-map',
|
|
49
|
+
label: $tr("ui.map-layer.map", "Map")
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: MapLayers.Imagery,
|
|
53
|
+
icon: 'mdi-satellite',
|
|
54
|
+
label: $tr("ui.map-layer.imagery", "Imagery")
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: MapLayers.Snow,
|
|
58
|
+
icon: 'mdi-snowflake',
|
|
59
|
+
label: $tr("ui.map-layer.snow", "Snow ski map")
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
items
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
</script>
|
|
@@ -4,48 +4,52 @@
|
|
|
4
4
|
:height="$props.height"
|
|
5
5
|
:width="$props.width"
|
|
6
6
|
>
|
|
7
|
-
<
|
|
8
|
-
v-if="$props.
|
|
9
|
-
padding="12px"
|
|
10
|
-
:variant="variant"
|
|
11
|
-
:color="color"
|
|
12
|
-
:style="style"
|
|
13
|
-
width="100%"
|
|
14
|
-
height="100%"
|
|
15
|
-
@click="() => $emit('update:modelValue', !$props.modelValue)"
|
|
16
|
-
v-bind="$attrs"
|
|
17
|
-
>
|
|
18
|
-
<slot />
|
|
19
|
-
</FSClickable>
|
|
20
|
-
<FSClickable
|
|
21
|
-
v-else-if="$props.href || $props.to || $attrs.onClick"
|
|
22
|
-
variant="background"
|
|
23
|
-
class="fs-tile"
|
|
24
|
-
padding="12px"
|
|
25
|
-
:color="ColorEnum.Background"
|
|
26
|
-
:href="$props.href"
|
|
27
|
-
width="100%"
|
|
28
|
-
height="100%"
|
|
29
|
-
:to="$props.to"
|
|
30
|
-
:style="style"
|
|
31
|
-
v-bind="$attrs"
|
|
7
|
+
<template
|
|
8
|
+
v-if="$props.editable"
|
|
32
9
|
>
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
10
|
+
<FSClickable
|
|
11
|
+
v-if="$props.singleSelect"
|
|
12
|
+
padding="12px"
|
|
13
|
+
:variant="variant"
|
|
14
|
+
:color="color"
|
|
15
|
+
:style="style"
|
|
16
|
+
width="100%"
|
|
17
|
+
height="100%"
|
|
18
|
+
@click="() => $emit('update:modelValue', !$props.modelValue)"
|
|
19
|
+
v-bind="$attrs"
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</FSClickable>
|
|
23
|
+
<FSClickable
|
|
24
|
+
v-else-if="$props.href || $props.to || $attrs.onClick"
|
|
37
25
|
variant="background"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
:
|
|
26
|
+
class="fs-tile"
|
|
27
|
+
padding="12px"
|
|
28
|
+
:color="ColorEnum.Background"
|
|
29
|
+
:href="$props.href"
|
|
30
|
+
width="100%"
|
|
31
|
+
height="100%"
|
|
32
|
+
:to="$props.to"
|
|
33
|
+
:style="style"
|
|
41
34
|
v-bind="$attrs"
|
|
42
35
|
>
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
<slot />
|
|
37
|
+
<FSCard
|
|
38
|
+
v-if="$props.editable"
|
|
39
|
+
class="fs-tile-checkbox"
|
|
40
|
+
variant="background"
|
|
41
|
+
:height="['40px', '32px']"
|
|
42
|
+
:width="['40px', '32px']"
|
|
43
|
+
:border="false"
|
|
44
|
+
v-bind="$attrs"
|
|
45
|
+
>
|
|
46
|
+
<FSCheckbox
|
|
47
|
+
:modelValue="$props.modelValue"
|
|
48
|
+
@update:modelValue="() => $emit('update:modelValue', !$props.modelValue)"
|
|
49
|
+
/>
|
|
50
|
+
</FSCard>
|
|
51
|
+
</FSClickable>
|
|
52
|
+
</template>
|
|
49
53
|
<FSCard
|
|
50
54
|
v-else
|
|
51
55
|
variant="background"
|
package/models/map.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { type Layer } from "leaflet";
|
|
2
2
|
|
|
3
|
-
import { type Address } from "@dative-gpi/foundation-shared-domain/models";
|
|
4
|
-
|
|
5
3
|
export interface MapLayer {
|
|
6
|
-
name :
|
|
4
|
+
name : MapLayers;
|
|
7
5
|
label: string;
|
|
8
6
|
image: string;
|
|
9
|
-
|
|
7
|
+
layers: Layer[];
|
|
10
8
|
}
|
|
11
9
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
export enum MapLayers {
|
|
11
|
+
Map = "map",
|
|
12
|
+
Imagery = "imagery",
|
|
13
|
+
Snow= "snow"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum MapOverlayPositions {
|
|
17
|
+
Expand = "expand",
|
|
18
|
+
Half = "half",
|
|
19
|
+
Collapse = "collapse",
|
|
18
20
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dative-gpi/foundation-shared-components",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.138",
|
|
5
5
|
"description": "",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dative-gpi/foundation-shared-domain": "1.0.
|
|
14
|
-
"@dative-gpi/foundation-shared-services": "1.0.
|
|
13
|
+
"@dative-gpi/foundation-shared-domain": "1.0.138",
|
|
14
|
+
"@dative-gpi/foundation-shared-services": "1.0.138"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@dative-gpi/bones-ui": "^1.0.0",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"sass": "1.71.1",
|
|
36
36
|
"sass-loader": "13.3.2"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "ec1370eef99afdec2bd4425c7010c1012c23563e"
|
|
39
39
|
}
|
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
.fs-leaflet-container {
|
|
7
7
|
width: 100%;
|
|
8
8
|
height: 100%;
|
|
9
|
-
|
|
9
|
+
z-index: 0;
|
|
10
|
+
|
|
11
|
+
.fs-map-tile-base-layer {
|
|
12
|
+
filter: grayscale(var(--fs-map-container-grayscale));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.fs-map-tile-grayscale-layer {
|
|
16
|
+
filter: grayscale(100%);
|
|
17
|
+
}
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
.fs-map-overlay-mobile {
|
|
@@ -77,17 +85,10 @@
|
|
|
77
85
|
}
|
|
78
86
|
}
|
|
79
87
|
|
|
80
|
-
.fs-map-
|
|
81
|
-
background-color: var(--fs-map-point-pin-color);
|
|
82
|
-
border-radius: 100%;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.fs-map-location > div {
|
|
88
|
+
.fs-map-marker > div {
|
|
86
89
|
display: flex;
|
|
87
90
|
height: 100%;
|
|
88
|
-
color: var(--fs-map-location-pin-color);
|
|
89
91
|
border-radius: 50%;
|
|
90
|
-
background-color: white;
|
|
91
92
|
filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.4));
|
|
92
93
|
align-items: center;
|
|
93
94
|
justify-content: center;
|
|
@@ -103,7 +104,7 @@
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
.fs-map-
|
|
107
|
+
.fs-map-cluster-marker > div {
|
|
107
108
|
background-color: var(--fs-map-location-pin-color);
|
|
108
109
|
color: white;
|
|
109
110
|
}
|
|
@@ -126,6 +127,41 @@
|
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
.fs-map-location > div {
|
|
131
|
+
color: var(--fs-map-location-pin-color);
|
|
132
|
+
background-color: white;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.fs-map-pin > div {
|
|
136
|
+
background-color: var(--fs-map-point-pin-color);
|
|
137
|
+
position: relative;
|
|
138
|
+
|
|
139
|
+
transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.fs-map-pin > div::before {
|
|
143
|
+
content: "";
|
|
144
|
+
position: absolute;
|
|
145
|
+
top: -4px;
|
|
146
|
+
left: -4px;
|
|
147
|
+
width: calc(100% + 8px);
|
|
148
|
+
height: calc(100% + 8px);
|
|
149
|
+
border-radius: 50%;
|
|
150
|
+
border: 2px solid var(--fs-map-point-pin-color);
|
|
151
|
+
opacity: 0.4;
|
|
152
|
+
|
|
153
|
+
@include clickscreen {
|
|
154
|
+
&:hover {
|
|
155
|
+
opacity: 1;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.fs-map-pin-selected > div {
|
|
161
|
+
transform: scale(1.35);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
129
165
|
.fs-map-site {
|
|
130
166
|
opacity: 0.6;
|
|
131
167
|
transition: opacity 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
package/tools/index.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
2
|
+
import { ColorEnum } from "../models";
|
|
3
|
+
import { JobState } from "@dative-gpi/foundation-shared-domain/enums";
|
|
4
|
+
|
|
5
|
+
const { $tr } = useTranslationsProvider();
|
|
6
|
+
|
|
7
|
+
export const getColorByState = (state: number | JobState | undefined) => {
|
|
8
|
+
switch (state) {
|
|
9
|
+
case JobState.Succeeded:
|
|
10
|
+
return ColorEnum.Success;
|
|
11
|
+
case JobState.Failed:
|
|
12
|
+
return ColorEnum.Error;
|
|
13
|
+
default:
|
|
14
|
+
return ColorEnum.Primary;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getIconByState = (state: number | JobState | undefined) => {
|
|
19
|
+
switch (state) {
|
|
20
|
+
case JobState.Succeeded:
|
|
21
|
+
return 'mdi-check-circle-outline';
|
|
22
|
+
case JobState.Failed:
|
|
23
|
+
return 'mdi-alert-circle-outline';
|
|
24
|
+
default:
|
|
25
|
+
return 'mdi-alert-circle-outline';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getLabelByState = (state: number | JobState | undefined) => {
|
|
30
|
+
switch (state) {
|
|
31
|
+
case JobState.Succeeded:
|
|
32
|
+
return $tr('ui.common.success', 'Success');
|
|
33
|
+
case JobState.Failed:
|
|
34
|
+
return $tr('ui.common.error', 'Error');
|
|
35
|
+
default:
|
|
36
|
+
return $tr('ui.common.executed', 'Executed');
|
|
37
|
+
}
|
|
38
|
+
};
|