feat: upload and download bitstream from the component of project view
This commit is contained in:
@@ -4,51 +4,50 @@
|
||||
<div v-else>
|
||||
<div class="mb-4 pb-4 border-b border-base-300">
|
||||
<h4 class="font-semibold text-lg mb-1">{{ componentData?.type }}</h4>
|
||||
<p class="text-xs text-base-content opacity-70">ID: {{ componentData?.id }}</p>
|
||||
<p class="text-xs text-base-content opacity-70">类型: {{ componentData?.type }}</p>
|
||||
<p class="text-xs text-base-content opacity-70">
|
||||
ID: {{ componentData?.id }}
|
||||
</p>
|
||||
<p class="text-xs text-base-content opacity-70">
|
||||
类型: {{ componentData?.type }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 通用属性部分 -->
|
||||
<CollapsibleSection
|
||||
title="通用属性"
|
||||
v-model:isExpanded="generalPropsExpanded"
|
||||
status="default"
|
||||
>
|
||||
<CollapsibleSection title="通用属性" v-model:isExpanded="generalPropsExpanded" status="default">
|
||||
<div class="space-y-4">
|
||||
<div v-for="prop in getGeneralProps()" :key="prop.name" class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">{{ prop.label || prop.name }}</span>
|
||||
</label>
|
||||
<!-- 根据 prop 类型选择输入控件 -->
|
||||
<input
|
||||
v-if="prop.type === 'number'"
|
||||
type="number"
|
||||
:placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full"
|
||||
:value="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly"
|
||||
:min="prop.min"
|
||||
:max="prop.max"
|
||||
:step="prop.step"
|
||||
@input="updateDirectProp(componentData.id, prop.name, parseFloat(($event.target as HTMLInputElement).value) || prop.default)"
|
||||
/>
|
||||
<input
|
||||
v-else-if="prop.type === 'string'"
|
||||
type="text"
|
||||
:placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full"
|
||||
:value="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly"
|
||||
@input="updateDirectProp(componentData.id, prop.name, ($event.target as HTMLInputElement).value)"
|
||||
/>
|
||||
<input v-if="prop.type === 'number'" type="number" :placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full" :value="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly" :min="prop.min" :max="prop.max" :step="prop.step" @input="
|
||||
updateDirectProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
parseFloat(($event.target as HTMLInputElement).value) ||
|
||||
prop.default,
|
||||
)
|
||||
" />
|
||||
<input v-else-if="prop.type === 'string'" type="text" :placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full" :value="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly" @input="
|
||||
updateDirectProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
($event.target as HTMLInputElement).value,
|
||||
)
|
||||
" />
|
||||
<div v-else-if="prop.type === 'boolean'" class="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-sm mr-2"
|
||||
:checked="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly"
|
||||
@change="updateDirectProp(componentData.id, prop.name, ($event.target as HTMLInputElement).checked)"
|
||||
/>
|
||||
<input type="checkbox" class="checkbox checkbox-sm mr-2" :checked="getPropValue(componentData, prop.name)"
|
||||
:disabled="prop.isReadOnly" @change="
|
||||
updateDirectProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
($event.target as HTMLInputElement).checked,
|
||||
)
|
||||
" />
|
||||
<span>{{ prop.label || prop.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -56,74 +55,69 @@
|
||||
</CollapsibleSection>
|
||||
|
||||
<!-- 组件特有属性部分 -->
|
||||
<CollapsibleSection
|
||||
title="组件特有属性"
|
||||
v-model:isExpanded="componentPropsExpanded"
|
||||
status="default"
|
||||
class="mt-4"
|
||||
>
|
||||
<CollapsibleSection title="组件特有属性" v-model:isExpanded="componentPropsExpanded" status="default" class="mt-4">
|
||||
<div v-if="componentConfig && componentConfig.props" class="space-y-4">
|
||||
<div v-for="prop in getComponentProps()" :key="prop.name" class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">{{ prop.label || prop.name }}</span>
|
||||
</label>
|
||||
<!-- 根据 prop 类型选择输入控件 -->
|
||||
<input
|
||||
v-if="prop.type === 'string'"
|
||||
type="text"
|
||||
:placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full"
|
||||
:value="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly"
|
||||
@input="updateProp(componentData.id, prop.name, ($event.target as HTMLInputElement).value)"
|
||||
/>
|
||||
<input
|
||||
v-else-if="prop.type === 'number'"
|
||||
type="number"
|
||||
:placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full"
|
||||
:value="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly"
|
||||
:min="prop.min"
|
||||
:max="prop.max"
|
||||
:step="prop.step"
|
||||
@input="updateProp(componentData.id, prop.name, parseFloat(($event.target as HTMLInputElement).value) || prop.default)"
|
||||
/>
|
||||
<input v-if="prop.type === 'string'" type="text" :placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full" :value="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly" @input="
|
||||
updateProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
($event.target as HTMLInputElement).value,
|
||||
)
|
||||
" />
|
||||
<input v-else-if="prop.type === 'number'" type="number" :placeholder="prop.label || prop.name"
|
||||
class="input input-bordered input-sm w-full" :value="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly" :min="prop.min" :max="prop.max" :step="prop.step" @input="
|
||||
updateProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
parseFloat(($event.target as HTMLInputElement).value) ||
|
||||
prop.default,
|
||||
)
|
||||
" />
|
||||
<div v-else-if="prop.type === 'boolean'" class="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-sm mr-2"
|
||||
:checked="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly"
|
||||
@change="updateProp(componentData.id, prop.name, ($event.target as HTMLInputElement).checked)"
|
||||
/>
|
||||
<input type="checkbox" class="checkbox checkbox-sm mr-2" :checked="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly" @change="
|
||||
updateProp(
|
||||
componentData.id,
|
||||
prop.name,
|
||||
($event.target as HTMLInputElement).checked,
|
||||
)
|
||||
" />
|
||||
<span>{{ prop.label || prop.name }}</span>
|
||||
</div>
|
||||
<select
|
||||
v-else-if="prop.type === 'select' && prop.options"
|
||||
class="select select-bordered select-sm w-full"
|
||||
:value="componentData?.attrs?.[prop.name]"
|
||||
:disabled="prop.isReadOnly"
|
||||
@change="(event) => {
|
||||
const selectElement = event.target as HTMLSelectElement;
|
||||
const value = selectElement.value;
|
||||
if (componentData) {
|
||||
updateProp(componentData.id, prop.name, value);
|
||||
</div>
|
||||
<select v-else-if="prop.type === 'select' && prop.options" class="select select-bordered select-sm w-full"
|
||||
:value="componentData?.attrs?.[prop.name]" :disabled="prop.isReadOnly" @change="
|
||||
(event) => {
|
||||
const selectElement = event.target as HTMLSelectElement;
|
||||
const value = selectElement.value;
|
||||
if (componentData) {
|
||||
updateProp(componentData.id, prop.name, value);
|
||||
}
|
||||
}
|
||||
}"
|
||||
>
|
||||
">
|
||||
<option v-for="option in prop.options" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<p v-else class="text-xs text-warning">不支持的属性类型: {{ prop.type }}</p>
|
||||
<p v-else class="text-xs text-warning">
|
||||
不支持的属性类型: {{ prop.type }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="componentData && !componentConfig" class="text-base-content opacity-70 text-sm">
|
||||
正在加载组件配置...
|
||||
</div>
|
||||
<div v-else-if="componentData && componentConfig && getComponentProps().length === 0" class="text-base-content opacity-70 text-sm">
|
||||
<div v-else-if="
|
||||
componentData && componentConfig && getComponentProps().length === 0
|
||||
" class="text-base-content opacity-70 text-sm">
|
||||
此组件没有特有属性可配置。
|
||||
</div>
|
||||
</CollapsibleSection>
|
||||
@@ -132,13 +126,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import CollapsibleSection from './CollapsibleSection.vue';
|
||||
import { type DiagramPart } from '@/components/diagramManager';
|
||||
import {
|
||||
type PropertyConfig,
|
||||
getPropValue
|
||||
} from '@/components/equipments/componentConfig';
|
||||
import { ref } from "vue";
|
||||
import CollapsibleSection from "./CollapsibleSection.vue";
|
||||
import { type DiagramPart } from "@/components/diagramManager";
|
||||
import {
|
||||
type PropertyConfig,
|
||||
getPropValue,
|
||||
} from "@/components/equipments/componentConfig";
|
||||
|
||||
// 定义属性
|
||||
const props = defineProps<{
|
||||
@@ -148,8 +142,13 @@ const props = defineProps<{
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits<{
|
||||
(e: 'updateProp', componentId: string, propName: string, value: any): void;
|
||||
(e: 'updateDirectProp', componentId: string, propName: string, value: any): void;
|
||||
(e: "updateProp", componentId: string, propName: string, value: any): void;
|
||||
(
|
||||
e: "updateDirectProp",
|
||||
componentId: string,
|
||||
propName: string,
|
||||
value: any,
|
||||
): void;
|
||||
}>();
|
||||
|
||||
// 控制折叠面板状态
|
||||
@@ -158,23 +157,32 @@ const componentPropsExpanded = ref(true);
|
||||
|
||||
// 更新组件属性方法
|
||||
function updateProp(componentId: string, propName: string, value: any) {
|
||||
emit('updateProp', componentId, propName, value);
|
||||
emit("updateProp", componentId, propName, value);
|
||||
}
|
||||
|
||||
// 更新组件的直接属性
|
||||
function updateDirectProp(componentId: string, propName: string, value: any) {
|
||||
emit('updateDirectProp', componentId, propName, value);
|
||||
emit("updateDirectProp", componentId, propName, value);
|
||||
}
|
||||
|
||||
// 获取通用属性(直接属性)
|
||||
function getGeneralProps(): PropertyConfig[] {
|
||||
return props.componentConfig?.props.filter(p => p.isDirectProp && p.name !== 'pins') || [];
|
||||
return (
|
||||
props.componentConfig?.props.filter(
|
||||
(p) => p.isDirectProp && p.name !== "pins",
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
// 获取组件特有属性(非直接属性)
|
||||
function getComponentProps(): PropertyConfig[] {
|
||||
return props.componentConfig?.props.filter(p => !p.isDirectProp && p.name !== 'pins') || [];
|
||||
return (
|
||||
props.componentConfig?.props.filter(
|
||||
(p) => !p.isDirectProp && p.name !== "pins",
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user