Skip to content

Commit 7884753

Browse files
author
hung.pv
committed
feat: add dataset control
1 parent 7d45f37 commit 7884753

6 files changed

Lines changed: 239 additions & 5 deletions

File tree

apps/demo-map/src/views/AllMapView.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
createMultiLegend,
4343
createMultiMapboxLayerComponent,
4444
DatasetComposite,
45+
DatasetControl,
4546
findSiblingOrNearestLeaf,
4647
IdentifyControl,
4748
IdentifyShowFirstControl,
@@ -462,7 +463,7 @@ function createMenuDrawLayer() {
462463
<MeasurementControl position="top-right" />
463464
<DrawControl position="top-right" />
464465
<InspectControl position="top-right" />
465-
<LayerControl position="top-left" show>
466+
<LayerControl position="top-left">
466467
<template #endList="{ mapId }">
467468
<BaseMapCard :mapId="mapId" />
468469
</template>
@@ -483,6 +484,7 @@ function createMenuDrawLayer() {
483484
<BaseMapControl position="bottom-left" />
484485
<IdentifyShowFirstControl />
485486
<LayerHighlight />
487+
<DatasetControl position="top-left" show />
486488
</Map>
487489
</template>
488490

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<script lang="ts">
2+
export default {
3+
name: 'layer-control',
4+
};
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { DraggableItemSideBar } from '@hungpvq/vue-draggable';
9+
import {
10+
BaseButton,
11+
makeShowProps,
12+
MapControlButton,
13+
ModuleContainer,
14+
useLang,
15+
useMap,
16+
useShow,
17+
withMapProps,
18+
} from '@hungpvq/vue-map-core';
19+
import SvgIcon from '@jamescoyle/vue-icon';
20+
import { mdiDatabaseOutline, mdiInformation } from '@mdi/js';
21+
import { computed, onMounted, shallowRef, watch } from 'vue';
22+
import type { IDataset } from '../../interfaces/dataset.base';
23+
import { handleMenuActionClick } from '../../model/menu';
24+
import { useMapDataset } from '../../store';
25+
import DatasetDetail from './DatasetDetail.vue';
26+
const props = defineProps({
27+
...withMapProps,
28+
...makeShowProps({ show: false }),
29+
});
30+
const { mapId, moduleContainerProps } = useMap(props);
31+
const { trans, setLocale } = useLang(mapId.value);
32+
setLocale({
33+
map: {
34+
'dataset-control': {
35+
title: 'Dataset Control',
36+
},
37+
},
38+
});
39+
const path = {
40+
icon: mdiDatabaseOutline,
41+
detail: mdiInformation,
42+
};
43+
const [show, toggleShow] = useShow(props.show);
44+
const { getDatasets, getDatasetIds } = useMapDataset(mapId.value);
45+
const datasetIds = computed(() => {
46+
return getDatasetIds().value;
47+
});
48+
watch(
49+
datasetIds,
50+
() => {
51+
updateList();
52+
},
53+
{ deep: true },
54+
);
55+
function updateList() {
56+
getViewFromStore();
57+
}
58+
const views = shallowRef<Array<IDataset>>([]);
59+
function getViewFromStore() {
60+
views.value = getDatasets();
61+
}
62+
function onShowDetail(view: IDataset) {
63+
handleMenuActionClick(
64+
[
65+
[
66+
'addComponent',
67+
[
68+
view,
69+
mapId.value,
70+
{
71+
component: () => DatasetDetail,
72+
attr: {
73+
dataset: view,
74+
},
75+
check: 'detail-dataset',
76+
},
77+
],
78+
],
79+
],
80+
view,
81+
mapId.value,
82+
view,
83+
);
84+
}
85+
onMounted(() => {
86+
updateList();
87+
});
88+
defineSlots<{
89+
item(props: { item: IDataset }): any;
90+
default(): any;
91+
}>();
92+
</script>
93+
<template>
94+
<ModuleContainer v-bind="moduleContainerProps">
95+
<template #btn>
96+
<MapControlButton
97+
v-if="!show"
98+
@click.stop="toggleShow()"
99+
:active="show"
100+
:tooltip="trans('map.dataset-control.title')"
101+
>
102+
<SvgIcon size="14" type="mdi" :path="path.icon" />
103+
</MapControlButton>
104+
</template>
105+
106+
<template #draggable="props">
107+
<DraggableItemSideBar
108+
:containerId="props.containerId"
109+
v-model:show="show"
110+
>
111+
<template #title> {{ trans('map.dataset-control.title') }} </template>
112+
<div class="dataset-control">
113+
<div v-for="view in views" :key="view.id">
114+
<slot name="item" :item="view">
115+
<div class="dataset-item">
116+
<span class="dataset-item__title">{{ view.getName() }}</span>
117+
<div class="dataset-item__title-action">
118+
<BaseButton @click.stop="onShowDetail(view)">
119+
<SvgIcon size="16" type="mdi" :path="path.detail" />
120+
</BaseButton>
121+
</div>
122+
</div>
123+
</slot>
124+
</div>
125+
</div>
126+
</DraggableItemSideBar>
127+
</template>
128+
<slot />
129+
</ModuleContainer>
130+
</template>
131+
132+
<style scoped lang="scss">
133+
.dataset-control {
134+
display: flex;
135+
flex-direction: column;
136+
height: 100%;
137+
.dataset-item {
138+
.dataset-item__title {
139+
display: inline-block;
140+
text-align: left;
141+
flex-grow: 1;
142+
white-space: nowrap;
143+
overflow: hidden;
144+
}
145+
.dataset-item__title-action {
146+
display: flex;
147+
flex-grow: 0;
148+
align-items: center;
149+
}
150+
display: flex;
151+
min-height: 30px;
152+
padding: 4px 8px;
153+
}
154+
}
155+
</style>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<script lang="ts">
2+
export default {
3+
name: 'detail-dataset-info',
4+
};
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { DraggableItemPopup } from '@hungpvq/vue-draggable';
9+
import { ModuleContainer } from '@hungpvq/vue-map-core';
10+
import { shallowRef, watch } from 'vue';
11+
import type { IDataset } from '../../interfaces';
12+
import { traverseTree } from '../../model';
13+
const props = defineProps<{ dataset: IDataset }>();
14+
const emit = defineEmits(['close']);
15+
function onUpdateShow(val: boolean) {
16+
if (!val) {
17+
emit('close');
18+
}
19+
}
20+
const items = shallowRef<{ level: number; path: number[]; node: IDataset }[]>(
21+
[],
22+
);
23+
watch(
24+
() => props.dataset,
25+
(newVal) => {
26+
traverseTree(props.dataset, (node, level, path) => {
27+
items.value.push({
28+
node,
29+
level,
30+
path,
31+
});
32+
});
33+
},
34+
{ immediate: true },
35+
);
36+
</script>
37+
<template>
38+
<ModuleContainer v-bind="$attrs">
39+
<template #draggable="props">
40+
<DraggableItemPopup
41+
v-bind="props"
42+
show
43+
@update:show="onUpdateShow"
44+
:width="400"
45+
:height="400"
46+
>
47+
<template #title>
48+
{{ dataset.getName() }}
49+
</template>
50+
<ul class="dataset-list">
51+
<li
52+
v-for="(item, index) in items"
53+
:key="index"
54+
class="dataset-list-item"
55+
:style="{ paddingLeft: `${item.level * 0.5}rem` }"
56+
>
57+
<span>{{ item.path.join('.') }}</span>
58+
<span>({{ item.node.type }})</span>
59+
<span>{{ item.node.getName() }}</span>
60+
</li>
61+
</ul>
62+
</DraggableItemPopup>
63+
</template>
64+
</ModuleContainer>
65+
</template>
66+
<style scoped>
67+
.dataset-list-item {
68+
display: flex;
69+
align-items: center;
70+
padding: 4px 8px;
71+
gap: 8px;
72+
}
73+
.dataset-list {
74+
padding: 8px;
75+
}
76+
</style>

libs/map/dataset/src/modules/IdentifyControl/IdentifyControl.vue

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,13 @@ const {
9191
9292
const origin = reactive({ latitude: 0, longitude: 0 });
9393
function onMapClick(e: MapMouseEvent) {
94-
console.log('map:identify', 'isEventClickBox', isEventClickBox.value);
95-
console.log('map:identify', 'isEventClickActive', isEventClickActive.value);
9694
if (isEventClickBox.value) return;
9795
logHelper(loggerIdentify, mapId.value, 'multi').debug('onMapClick', e);
9896
origin.latitude = e.lngLat.lat;
9997
origin.longitude = e.lngLat.lng;
10098
onGetFeatures(e.point);
10199
}
102100
function onBboxSelect(bbox: any) {
103-
console.log('map:identify', 'isEventClickBox', isEventClickBox.value);
104-
console.log('map:identify', 'isEventClickActive', isEventClickActive.value);
105101
if (isEventClickActive.value) return;
106102
logHelper(loggerIdentify, mapId.value, 'multi').debug('onBboxSelect', bbox);
107103
onRemoveBox();

libs/map/dataset/src/modules/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { default as ComponentManagementControl } from './ComponentManagementControl/ComponentManagementControl.vue';
22
export { default as CreateControl } from './CreateControl/CreateControl.vue';
3+
export { default as DatasetControl } from './DatasetControl/DatasetControl.vue';
34
export { default as IdentifyControl } from './IdentifyControl/IdentifyControl.vue';
45
export { default as IdentifyShowFirstControl } from './IdentifyControl/IdentifyShowFirstControl.vue';
56
export { default as LayerControl } from './LayerControl/LayerControl.vue';

libs/map/dataset/src/store/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@ export const useMapDataset = (mapId: string) => {
118118
function getDatasetIds() {
119119
return store.datasetIds;
120120
}
121+
function getDatasets() {
122+
return store.datasetIds.value.map((id) => store.datasets[id]);
123+
}
121124
return {
125+
getDatasets,
122126
addDataset,
123127
getDatasetIds,
124128
removeComponent,

0 commit comments

Comments
 (0)