Skip to content

Commit

Permalink
wip: create a style manager (#1072)
Browse files Browse the repository at this point in the history
  • Loading branch information
Floran05 committed Feb 20, 2025
1 parent 58e6233 commit 6ae067b
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 40 deletions.
18 changes: 12 additions & 6 deletions map/client/components/styles/KStyleEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
<KStyleProperty v-model="style.point.color" :name="$t('KStyleEditor.COLOR')" type="color" />
<KStyleProperty v-model="style.point.size" :name="$t('KStyleEditor.SIZE')" type="size" />
<KStyleProperty v-model="style.point.shape" :name="$t('KStyleEditor.SHAPE')" type="shape" />
<KStyleProperty v-model="style.point.icon.classes" :name="$t('KStyleEditor.ICON')" type="icon" />
<KStyleProperty v-model="style.point.icon.size" :name="$t('KStyleEditor.ICON_SIZE')" type="size" :min="12" :max="24" />
<KStyleProperty v-if="!is3D" v-model="style.point.icon.classes" :name="$t('KStyleEditor.ICON')" type="icon" />
<KStyleProperty v-if="!is3D" v-model="style.point.icon.size" :name="$t('KStyleEditor.ICON_SIZE')" type="size" :min="12" :max="24" />
</q-list>
</q-expansion-item>

Expand Down Expand Up @@ -82,14 +82,15 @@
</template>

<script setup>
import { ref, computed } from 'vue'
import _ from 'lodash'
import KStyleProperty from './KStyleProperty.vue'
import KStylePreview from './KStylePreview.vue'
import { DefaultStyle } from '../../utils/index.js'
import _ from 'lodash'
import KPanel from '../../../../core/client/components/KPanel.vue'
import { DefaultStyle } from '../../utils/index.js'
import { useCurrentActivity } from '../../composables/activity.js'
// Props
const props = defineProps({
title: {
type: String,
Expand All @@ -109,13 +110,17 @@ const props = defineProps({
}
})
// Emits
const emit = defineEmits([
'cancel',
'apply'
])
// Data
const style = ref(_.assign({}, _.pick(DefaultStyle, ['point', 'line', 'polygon']), { name: '' }, props.style))
const { CurrentActivity } = useCurrentActivity()
// Computed
const buttons = computed(() => {
if (props.buttons !== null) return props.buttons
return [
Expand All @@ -139,9 +144,10 @@ const buttons = computed(() => {
]
})
const is3D = computed(() => {
return this.kActivity.is3D()
return CurrentActivity.value.is3D()
})
// Functions
function getStyle () {
return style.value
}
Expand Down
149 changes: 115 additions & 34 deletions map/client/components/styles/KStyleManager.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,61 @@
<template>
<div class="column">
<div class="row justify-center">

<q-tab-panels v-model="viewMode" animated style="width: 100%">
<div>
<div id="style-manager-header" class="q-px-md q-mt-md" v-if="title || (toolbar && toolbar.length)">
<div v-if="title" class="ellipsis text-h6">
{{ $tie(title) }}
</div>
<KPanel
id="style-manager-toolbar"
:content="toolbar"
v-bind:class="{ 'q-gutter-x-sm' : $q.screen.gt.xs, 'q-gutter-x-xs': $q.screen.lt.sm }"
/>
<QSeparator inset />
</div>
<div id="style-manager-content">
<q-tab-panels v-model="viewMode" animated>
<q-tab-panel name="list">
<KGrid
service="styles"
:append-items="true"
:base-query="baseQuery"
:filter-query="filterQuery"
class="fit"
:renderer="{
component: 'collection/KItem',
actions: [
{
id: 'edit-style',
icon: 'las la-edit',
tooltip: 'KStyleManager.EDIT',
scope: 'header',
handler: editStyle
},
{
id: 'delete-style',
icon: 'las la-trash',
tooltip: 'KStyleManager.DELETE',
scope: 'footer',
handler: { name: 'removeItem', params: ['confirm'] }
},
],
class: 'col-12'
}"
service="styles"
:append-items="true"
:base-query="baseQuery"
:filter-query="filterQuery"
class="fit"
:renderer="{
component: 'styles/KStylePreviewItem',
options: {
avatar: false
},
actions: [
{
id: 'apply-to-selection',
icon: 'las la-object-ungroup',
tooltip: 'KStyleManager.APPLY_TO_SELECTION',
scope: 'header',
handler: applyToSelection
},
{
id: 'edit-style',
icon: 'las la-edit',
tooltip: 'KStyleManager.EDIT',
scope: 'header',
handler: editStyle
},
{
id: 'delete-style',
icon: 'las la-trash',
tooltip: 'KStyleManager.DELETE',
scope: 'footer',
handler: { name: 'removeItem', params: ['confirm'] }
},
],
class: 'col-12'
}"
/>
</q-tab-panel>
<q-tab-panel name="edit">
<k-style-editor/>
<KStyleEditor ref="styleEditor" :style="style" @cancel="onCancel" @apply="onApply" />
</q-tab-panel>
</q-tab-panels>

</div>
</div>
</template>
Expand All @@ -45,12 +64,26 @@
import { computed, ref } from 'vue'
import _ from 'lodash'
import { KGrid } from '../../../../core/client/components'
import { Store } from '@kalisio/kdk/core.client'
import { Store, api } from '@kalisio/kdk/core.client'
import KStyleEditor from './KStyleEditor.vue'
import { useCurrentActivity } from '../../composables/activity.js'
import { isLayerStyleEditable } from '../../utils/utils.layers.js'
import { editFeaturesStyle } from '../../utils/utils.features.js'
// Props
defineProps({
title: {
type: String,
default: ''
}
})
// Data
const filter = Store.get('filter')
const styleEditor = ref(null)
const style = ref(null)
const viewMode = ref('list')
const { getSelectedFeaturesByLayer } = useCurrentActivity()
// Computed
const baseQuery = computed(() => {
Expand All @@ -63,10 +96,58 @@ const filterQuery = computed(() => {
// Filter the objects against the group
return query
})
const toolbar = computed(() => {
if (viewMode.value === 'edit') return []
return [
{
component: 'collection/KSorter',
id: 'style-manager-sorter-options',
tooltip: 'KStyleManager.SORT',
options: [
{ icon: 'las la-sort-alpha-down', value: { field: 'name', order: 1 }, default: true },
{ icon: 'las la-sort-alpha-up', value: { field: 'name', order: -1 } },
{ icon: 'kdk:clockwise.png', value: { field: 'updatedAt', order: 1 } },
{ icon: 'kdk:anticlockwise.png', value: { field: 'updatedAt', order: -1 } }
]
},
{ component: 'collection/KFilter', style: 'max-width: 200px;' },
{ component: 'QSpace' },
{
id: 'add-layer-category',
icon: 'las la-plus-circle',
tooltip: 'KStyleManager.CREATE_STYLE',
size: '1rem',
handler: () => { editStyle() }
}
]
})
function editStyle (style) {
console.log(style)
// Functions
function applyToSelection (styleToApply) {
const type = { Point: 'point', LineString: 'line', Polygon: 'polygon' }
_.forEach(getSelectedFeaturesByLayer(), layer => {
if (isLayerStyleEditable(layer.layer)) {
_.forEach(layer.features, f => { f.style = _.get(styleToApply, ['item', _.get(type, f.geometry.type, 'point')], null) })
editFeaturesStyle({ type: 'FeatureCollection', features: layer.features }, layer.layer)
}
})
}
function editStyle (styleToEdit) {
viewMode.value = 'edit'
style.value = _.get(styleToEdit, 'item', null)
}
function onApply (style) {
const service = api.getService('styles')
if (style._id) {
service.patch(style._id, style)
} else {
service.create(style)
}
viewMode.value = 'list'
}
function onCancel () {
viewMode.value = 'list'
}
</script>
2 changes: 2 additions & 0 deletions map/client/i18n/map_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"DISPLAY_POSITION": "Display the coordinates",
"DISPLAY_LEGEND": "Display legend",
"DISPLAY_SELECTION": "Display selection",
"DISPLAY_STYLE_MANAGER": "Display style manager",
"HIDE_LEGEND": "Hide legend",
"SEARCH_LOCATION": "Search a location",
"ADD_VIEW": "Add view",
Expand Down Expand Up @@ -748,6 +749,7 @@
},
"KStyleManager": {
"TITLE": "Style manager",
"APPLY_TO_SELECTION": "Apply style to selection",
"EDIT": "Edit style",
"DELETE": "Delete style",
"SORT": "Sort styles",
Expand Down
2 changes: 2 additions & 0 deletions map/client/i18n/map_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"DISPLAY_POSITION": "Afficher les coordonnées",
"DISPLAY_LEGEND": "Afficher la légende",
"DISPLAY_SELECTION": "Afficher la sélection",
"DISPLAY_STYLE_MANAGER": "Afficher le gestionnaire de style",
"HIDE_LEGEND": "Masquer la légende",
"SEARCH_LOCATION": "Rechercher un lieu",
"ADD_VIEW": "Ajouter une vue",
Expand Down Expand Up @@ -752,6 +753,7 @@
},
"KStyleManager": {
"TITLE": "Gestionnaire de styles",
"APPLY_TO_SELECTION": "Appliquer le style à la sélection",
"EDIT": "Modifier le style",
"DELETE": "Supprimer le style",
"SORT": "Trier les styles",
Expand Down
13 changes: 13 additions & 0 deletions map/client/utils/utils.features.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,19 @@ export async function editFeaturesProperties(geoJson, layer) {
return (geoJson.type === 'FeatureCollection' ? Object.assign(geoJson, { features: updatedFeatures }) : updatedFeatures)
}

export async function editFeaturesStyle(geoJson, layer) {
const features = (geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson])
const updatedFeatures = []
for (let i = 0; i < features.length; i++) {
const feature = features[i]
if (feature._id) {
const updatedFeature = await api.getService(layer.service).patch(feature._id, _.pick(feature, ['style']))
updatedFeatures.push(updatedFeature)
}
}
return (geoJson.type === 'FeatureCollection' ? Object.assign(geoJson, { features: updatedFeatures }) : updatedFeatures)
}

export async function removeFeatures(geoJson, layer) {
// Remove all features of a given layer
if (!geoJson) {
Expand Down

0 comments on commit 6ae067b

Please sign in to comment.