salix-front/src/components/common/VnJsonValue.vue

112 lines
2.7 KiB
Vue

<script setup>
import { watch, computed } from 'vue';
import { toDateString } from 'src/filters';
import { useDescriptorStore } from 'src/stores/useDescriptorStore';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
const props = defineProps({
prop: { type: Object, default: undefined },
});
const maxStrLen = 512;
let t = '';
let cssClass = '';
let type;
const descriptorStore = useDescriptorStore();
const propsValue = computed(() => props.prop.val.val);
const updateValue = () => {
type = typeof propsValue.value;
if (propsValue.value == null) {
t = '∅';
cssClass = 'json-null';
} else {
cssClass = `json-${type}`;
switch (type) {
case 'number':
if (Number.isInteger(propsValue)) {
t = propsValue.value.toString();
} else {
t = (
Math.round((propsValue.value + Number.EPSILON) * 1000) / 1000
).toString();
}
break;
case 'boolean':
t = propsValue.value ? '✓' : '✗';
cssClass = `json-${propsValue.value ? 'true' : 'false'}`;
break;
case 'string':
t =
propsValue.value.length <= maxStrLen
? propsValue
: propsValue.value.substring(0, maxStrLen) + '...';
break;
case 'object':
if (propsValue.value instanceof Date) {
t = toDateString(propsValue.value);
} else {
t = propsValue.value.toString();
}
break;
default:
t = propsValue.value.toString();
}
}
};
watch(() => propsValue.value, updateValue);
updateValue();
</script>
<template>
<span :title="props.prop.name">{{ props.prop.nameI18n }}: </span>
<span
:title="
type === 'string' && propsValue.value?.length > maxStrLen
? propsValue.value
: ''
"
:class="{
[cssClass]: t !== '',
'json-link': descriptorStore.has(props.prop.name),
}"
>
{{ t }}
<component
v-if="props.prop.val.id"
:is="descriptorStore.has(props.prop.name)"
:id="props.prop.val.id"
/>
</span>
</template>
<style scoped>
.json-string {
color: #d172cc;
}
.json-object {
color: #d1a572;
}
.json-number {
color: #85d0ff;
}
.json-true {
color: #7dc489;
}
.json-false {
color: #c74949;
}
.json-null {
color: #cd7c7c;
font-style: italic;
}
.json-link {
text-decoration: underline;
cursor: pointer;
}
</style>