homemanager-fe/src/components/house-planner/PlannerPropertyPanel.vue

149 lines
3.4 KiB
Vue

<template>
<PlannerSidebar :title="$t('planner.panel.properties.title')">
<div
class="bg-white-50 flex h-full flex-col overflow-auto"
v-if="selectedObject && applicableProperties"
>
<PropertyFormItem
v-for="prop of applicableProperties.properties"
:id="selectedObject.id"
:prop="prop"
:value="selectedObject[prop.key as keyof typeof selectedObject]"
@update="(newValue) => updateProp(prop, newValue)"
/>
</div>
</PlannerSidebar>
</template>
<script setup lang="ts">
import PlannerSidebar from './PlannerSidebar.vue';
import { Layer } from '../../modules/house-planner/interfaces';
import {
ObjectProperties,
ObjectProperty,
} from './interfaces/properties.interfaces';
import { computed } from 'vue';
import PropertyFormItem from './PropertyFormItem.vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const props = defineProps<{
layers: Layer[];
}>();
const emit = defineEmits<{
(
e: 'update',
layerId: number,
objectId: number,
key: string,
value: unknown,
): void;
}>();
const commonProps: ObjectProperty[] = [
{ key: 'name', title: t('planner.properties.name'), type: 'string' },
{
key: 'visible',
title: t('planner.properties.visible'),
type: 'boolean',
groupable: true,
},
];
const lineProps: ObjectProperty[] = [
...commonProps,
{
key: 'width',
title: t('planner.properties.width'),
type: 'number',
groupable: true,
},
{
key: 'color',
title: t('planner.properties.color'),
type: 'color',
groupable: true,
},
{
key: 'lineCap',
title: t('planner.properties.lineCap'),
type: 'select',
groupable: true,
options: [
{ value: undefined, title: '' },
{ value: 'butt', title: t('planner.properties.butt') },
{ value: 'round', title: t('planner.properties.round') },
{ value: 'square', title: t('planner.properties.square') },
],
},
{
key: 'lineJoin',
title: t('planner.properties.lineJoin'),
type: 'select',
groupable: true,
options: [
{ value: undefined, title: '' },
{ value: 'miter', title: t('planner.properties.miter') },
{ value: 'bevel', title: t('planner.properties.bevel') },
{ value: 'round', title: t('planner.properties.round') },
],
},
{
key: 'closed',
title: t('planner.properties.closed'),
type: 'boolean',
groupable: true,
},
];
const objectTypeProperties: ObjectProperties[] = [
{
type: 'line',
properties: lineProps,
},
{
type: 'curve',
properties: lineProps,
},
{
type: 'room',
properties: lineProps,
},
{
type: 'object',
properties: commonProps,
},
];
const currentLayer = computed(() =>
props.layers.find((layer) => layer.active && layer.visible),
);
// TODO multi edit
const selectedObject = computed(
() => currentLayer.value?.contents?.filter((obj) => obj.selected)[0],
);
const applicableProperties = computed(
() =>
selectedObject.value &&
objectTypeProperties.find(
(prop) => prop.type === selectedObject.value?.type,
),
);
const updateProp = (prop: ObjectProperty, value: unknown) => {
if (!currentLayer.value || !selectedObject.value) return;
if (prop.type === 'number') value = parseFloat(value as string);
emit(
'update',
currentLayer.value!.id,
selectedObject.value!.id,
prop.key,
value,
);
};
</script>