mirror of
https://github.com/dfpc-coe/CloudTAK.git
synced 2025-12-22 13:47:22 +00:00
Update Attachment Property
This commit is contained in:
@@ -430,16 +430,15 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if='!cot.properties.contact && cot.properties.attachments !== undefined'
|
||||
class='col-12 py-2'
|
||||
<template
|
||||
v-if='!cot.properties.contact'
|
||||
>
|
||||
<PropertyAttachments
|
||||
:key='cot.properties.id'
|
||||
:model-value='cot.properties.attachments'
|
||||
:model-value='cot.properties.attachments || []'
|
||||
@update:model-value='updatePropertyAttachment($event)'
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-if='cot.properties.remarks !== undefined'
|
||||
|
||||
@@ -1,107 +1,127 @@
|
||||
<template>
|
||||
<div class='col-12 d-flex align-items-center py2'>
|
||||
<IconPaperclip
|
||||
:size='18'
|
||||
stroke='1'
|
||||
color='#6b7990'
|
||||
class='ms-2 me-1'
|
||||
/>
|
||||
<label class='subheader user-select-none'>Attachments</label>
|
||||
|
||||
<div class='ms-auto me-2'>
|
||||
<IconFileUpload
|
||||
v-if='!upload'
|
||||
v-tooltip='"Add Attachment"'
|
||||
:size='24'
|
||||
<div class='col-12 pt-2'>
|
||||
<div
|
||||
class='d-flex align-items-center cursor-pointer user-select-none py-2 px-2 rounded transition-all mx-2'
|
||||
:class='{ "bg-accent": expanded, "hover": !expanded }'
|
||||
@click='expanded = !expanded'
|
||||
>
|
||||
<IconPaperclip
|
||||
:size='18'
|
||||
stroke='1'
|
||||
class='cursor-pointer'
|
||||
@click='upload = true'
|
||||
color='#6b7990'
|
||||
class='ms-2 me-1'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-12'>
|
||||
<div class='mx-2'>
|
||||
<TablerLoading
|
||||
v-if='loading'
|
||||
:inline='true'
|
||||
class='my-2'
|
||||
/>
|
||||
<div
|
||||
v-else-if='upload'
|
||||
class='py-2 px-4'
|
||||
>
|
||||
<Upload
|
||||
:url='uploadURL()'
|
||||
:headers='uploadHeaders()'
|
||||
method='PUT'
|
||||
@cancel='upload = false'
|
||||
@done='uploadComplete($event)'
|
||||
<label class='subheader cursor-pointer m-0'>Attachments</label>
|
||||
|
||||
<div class='ms-auto d-flex align-items-center'>
|
||||
<IconFileUpload
|
||||
v-if='!upload'
|
||||
v-tooltip='"Add Attachment"'
|
||||
:size='20'
|
||||
stroke='1'
|
||||
class='cursor-pointer me-2'
|
||||
@click.stop='upload = true; expanded = true'
|
||||
/>
|
||||
<span class='badge bg-blue-lt me-2'>{{ files.length }}</span>
|
||||
<IconChevronDown
|
||||
class='transition-transform'
|
||||
:class='{ "rotate-180": !expanded }'
|
||||
:size='18'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TablerNone
|
||||
v-else-if='!files.length'
|
||||
:compact='true'
|
||||
:create='false'
|
||||
/>
|
||||
<template v-else>
|
||||
<div class='w-100 d-flex flex-wrap align-items-center justify-content-center'>
|
||||
<template v-for='file of files'>
|
||||
<div
|
||||
class='grid-transition'
|
||||
:class='{ expanded: expanded }'
|
||||
>
|
||||
<div class='overflow-hidden'>
|
||||
<div class='col-12'>
|
||||
<div class='mx-2'>
|
||||
<TablerLoading
|
||||
v-if='loading'
|
||||
:inline='true'
|
||||
class='my-2'
|
||||
/>
|
||||
<div
|
||||
class='px-2 py-2 hover rounded'
|
||||
v-else-if='upload'
|
||||
class='py-2 px-4'
|
||||
>
|
||||
<div
|
||||
class='d-flex align-items-center justify-content-center'
|
||||
style='
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
'
|
||||
>
|
||||
<img
|
||||
v-if='[".png", ".jpg", ".jpeg", ".webp"].includes(file.ext.toLowerCase())'
|
||||
class='cursor-pointer'
|
||||
:style='{
|
||||
"max-height": "180px",
|
||||
"object-fit": "contain"
|
||||
}'
|
||||
:src='downloadAssetUrl(file)'
|
||||
@click='attachmentPane(file)'
|
||||
>
|
||||
<IconFile
|
||||
v-else
|
||||
:size='60'
|
||||
stroke='1'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class='d-flex align-items-center pt-2'
|
||||
style='
|
||||
height: 30px;
|
||||
'
|
||||
>
|
||||
<span
|
||||
class='mx-2 text-truncate'
|
||||
style='max-width: 160px;'
|
||||
v-text='file.name'
|
||||
/>
|
||||
|
||||
<div class='ms-auto'>
|
||||
<TablerIconButton
|
||||
title='Download Asset'
|
||||
@click='downloadAsset(file)'
|
||||
>
|
||||
<IconDownload
|
||||
:size='24'
|
||||
stroke='1'
|
||||
/>
|
||||
</TablerIconButton>
|
||||
</div>
|
||||
</div>
|
||||
<Upload
|
||||
:url='uploadURL()'
|
||||
:headers='uploadHeaders()'
|
||||
method='PUT'
|
||||
@cancel='upload = false'
|
||||
@done='uploadComplete($event)'
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<TablerNone
|
||||
v-else-if='!files.length'
|
||||
:compact='true'
|
||||
:create='false'
|
||||
/>
|
||||
<template v-else>
|
||||
<div class='w-100 d-flex flex-wrap align-items-center justify-content-center'>
|
||||
<template v-for='file of files'>
|
||||
<div
|
||||
class='px-2 py-2 hover rounded'
|
||||
>
|
||||
<div
|
||||
class='d-flex align-items-center justify-content-center'
|
||||
style='
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
'
|
||||
>
|
||||
<img
|
||||
v-if='[".png", ".jpg", ".jpeg", ".webp"].includes(file.ext.toLowerCase())'
|
||||
class='cursor-pointer'
|
||||
:style='{
|
||||
"max-height": "180px",
|
||||
"object-fit": "contain"
|
||||
}'
|
||||
:src='downloadAssetUrl(file)'
|
||||
@click='attachmentPane(file)'
|
||||
>
|
||||
<IconFile
|
||||
v-else
|
||||
:size='60'
|
||||
stroke='1'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class='d-flex align-items-center pt-2'
|
||||
style='
|
||||
height: 30px;
|
||||
'
|
||||
>
|
||||
<span
|
||||
class='mx-2 text-truncate'
|
||||
style='max-width: 160px;'
|
||||
v-text='file.name'
|
||||
/>
|
||||
|
||||
<div class='ms-auto'>
|
||||
<TablerIconButton
|
||||
title='Download Asset'
|
||||
@click='downloadAsset(file)'
|
||||
>
|
||||
<IconDownload
|
||||
:size='24'
|
||||
stroke='1'
|
||||
/>
|
||||
</TablerIconButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -116,6 +136,7 @@ import {
|
||||
IconDownload,
|
||||
IconPaperclip,
|
||||
IconFileUpload,
|
||||
IconChevronDown,
|
||||
} from '@tabler/icons-vue';
|
||||
|
||||
import {
|
||||
@@ -137,6 +158,7 @@ const emit = defineEmits([
|
||||
|
||||
const floatStore = useFloatStore();
|
||||
|
||||
const expanded = ref(false);
|
||||
const upload = ref(false);
|
||||
const loading = ref(true);
|
||||
const files = ref([]);
|
||||
@@ -210,3 +232,23 @@ async function fetchMetadata() {
|
||||
files.value = (await std(url)).items;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.grid-transition {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
transition: grid-template-rows 0.3s ease-out;
|
||||
}
|
||||
|
||||
.grid-transition.expanded {
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.rotate-180 {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.transition-transform {
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class='col-12 pb-2'>
|
||||
<div
|
||||
class='col-12 pb-2'
|
||||
:style='{ zIndex: expanded ? 10 : "auto", position: "relative" }'
|
||||
>
|
||||
<div
|
||||
class='d-flex align-items-center cursor-pointer user-select-none py-2 px-2 rounded transition-all mx-2'
|
||||
:class='{ "bg-accent": expanded, "hover": !expanded }'
|
||||
@@ -25,19 +28,23 @@
|
||||
class='grid-transition'
|
||||
:class='{ expanded: expanded }'
|
||||
>
|
||||
<div class='overflow-hidden'>
|
||||
<div class='px-2 py-3'>
|
||||
<div class='row g-2 rounded px-2 bg-accent pb-2'>
|
||||
<template v-if='cot.geometry.type === "Point"'>
|
||||
<div class='col-12'>
|
||||
<IconSelect
|
||||
:model-value='cot.properties.icon'
|
||||
label='Point Icon'
|
||||
:size='32'
|
||||
stroke='1'
|
||||
@update:model-value='updatePropertyIcon($event)'
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
:style='{ overflow: overflow }'
|
||||
style='min-height: 0;'
|
||||
>
|
||||
<div class='mx-2 py-2'>
|
||||
<div class='rounded bg-accent px-2 py-2'>
|
||||
<div class='row g-2'>
|
||||
<template v-if='cot.geometry.type === "Point"'>
|
||||
<div class='col-12'>
|
||||
<IconSelect
|
||||
:model-value='cot.properties.icon'
|
||||
label='Point Icon'
|
||||
:size='32'
|
||||
stroke='1'
|
||||
@update:model-value='updatePropertyIcon($event)'
|
||||
/>
|
||||
</div>
|
||||
<div class='col-12'>
|
||||
<label class='subheader user-select-none'>Point Color</label>
|
||||
<TablerInput
|
||||
@@ -108,7 +115,7 @@
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if='cot.geometry.type === "Polygon"'>
|
||||
<template v-if='cot.geometry.type === "Polygon" || cot.geometry.type === "MultiPolygon"'>
|
||||
<div class='col-12'>
|
||||
<label class='subheader user-select-none'>Fill Colour</label>
|
||||
<TablerInput
|
||||
@@ -131,6 +138,7 @@
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,7 +147,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang='ts'>
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { IconPaint, IconChevronDown } from '@tabler/icons-vue';
|
||||
import {
|
||||
TablerInput,
|
||||
@@ -154,6 +162,20 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const expanded = ref(false);
|
||||
const overflow = ref('hidden');
|
||||
let timeout: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
watch(expanded, (val) => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
|
||||
if (val) {
|
||||
timeout = setTimeout(() => {
|
||||
overflow.value = 'visible';
|
||||
}, 300);
|
||||
} else {
|
||||
overflow.value = 'hidden';
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function updateProperty(key: string, event: any) {
|
||||
|
||||
Reference in New Issue
Block a user