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

126 lines
2.9 KiB
Vue

<template>
<PlannerSidebar title="Properties">
<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';
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: 'Name', type: 'string' },
{ key: 'visible', title: 'Visible', type: 'boolean', groupable: true },
];
const lineProps: ObjectProperty[] = [
...commonProps,
{ key: 'width', title: 'Line Width', type: 'number', groupable: true },
{ key: 'color', title: 'Color', type: 'color', groupable: true },
{
key: 'lineCap',
title: 'Line Cap',
type: 'select',
groupable: true,
options: [
{ value: undefined, title: '' },
{ value: 'butt', title: 'Butt' },
{ value: 'round', title: 'Round' },
{ value: 'square', title: 'Square' },
],
},
{
key: 'lineJoin',
title: 'Line Join',
type: 'select',
groupable: true,
options: [
{ value: undefined, title: '' },
{ value: 'miter', title: 'Miter' },
{ value: 'bevel', title: 'Bevel' },
{ value: 'round', title: 'Round' },
],
},
{ key: 'closed', title: '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>