多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

268 lines
7.4 KiB

<script lang="ts" setup>
import { marked } from 'marked'
interface Prop {
modelValue: boolean
extensionId: string
from: 'market' | 'extension'
}
const props = defineProps<Prop>()
const emit = defineEmits(['update:modelValue'])
const vModel = useVModel(props, 'modelValue', emit)
const { availableExtensions, descriptionContent, addExtension, getExtensionAssetsUrl, isMarketVisible } = useExtensions()
const onBack = () => {
vModel.value = false
isMarketVisible.value = true
}
const onAddExtension = (ext: any) => {
addExtension(ext)
vModel.value = false
}
const activeExtension = computed(() => {
return availableExtensions.value.find((ext) => ext.id === props.extensionId)
})
// Create a custom renderer
const renderer = new marked.Renderer()
// Override the image function to modify the URL
renderer.image = function (href: string, title: string | null, text: string) {
// Modify the URL here
const newUrl = getExtensionAssetsUrl(href)
return `<img src="${newUrl}" alt="${text}" title="${title || ''}">`
}
// Apply the custom renderer to marked
marked.use({ renderer })
const getModifiedContent = (content = '') => {
// Modify raw <img> tags, supporting both single and double quotes
return content.replace(/<img\s+src=(["'])(.*?)\1(.*?)>/g, (match, quote, src, rest) => {
const newSrc = getExtensionAssetsUrl(src)
return `<img src=${quote}${newSrc}${quote}${rest}>`
})
}
const detailsBody = computed(() => {
if (descriptionContent.value[props.extensionId]) {
return marked.parse(getModifiedContent(descriptionContent.value[props.extensionId]))
} else if (activeExtension.value?.description) {
return marked.parse(getModifiedContent(activeExtension.value.description))
}
return '<p></p>'
})
</script>
<template>
<NcModal
v-model:visible="vModel"
:class="{ active: vModel }"
:footer="null"
:width="1154"
size="medium"
wrap-class-name="nc-modal-extension-details"
>
<div v-if="activeExtension" class="flex flex-col w-full h-full">
<div class="flex items-center gap-3 p-4 border-b-1 border-gray-200">
<NcButton v-if="from === 'market'" size="small" type="text" @click="onBack">
<GeneralIcon icon="arrowLeft" />
</NcButton>
<img :src="getExtensionAssetsUrl(activeExtension.iconUrl)" alt="icon" class="h-[50px] w-[50px] object-contain" />
<div class="flex-1 flex flex-col">
<div class="font-semibold text-xl truncate">{{ activeExtension.title }}</div>
<div class="text-small leading-[18px] text-gray-500 truncate">{{ activeExtension.subTitle }}</div>
</div>
<div class="self-start flex items-center gap-2.5">
<NcButton size="small" class="w-full" @click="onAddExtension(activeExtension)">
<div class="flex items-center justify-center gap-1 -ml-3px">
<GeneralIcon icon="plus" /> {{ $t('general.install') }}
</div>
</NcButton>
<NcButton size="small" type="text" @click="vModel = false">
<GeneralIcon icon="close" class="text-gray-600" />
</NcButton>
</div>
</div>
<div class="extension-details">
<div class="extension-details-left">
<div class="nc-extension-details-body" v-html="detailsBody"></div>
</div>
<div class="extension-details-right">
<div class="extension-details-right-section">
<div class="extension-details-right-title">Version</div>
<div class="extension-details-right-subtitle">{{ activeExtension.version }}</div>
</div>
<NcDivider />
<div class="extension-details-right-section">
<div v-if="activeExtension.publisherName" class="extension-details-right-title">Publisher</div>
<div class="extension-details-right-subtitle">{{ activeExtension.publisherName }}</div>
</div>
<template v-if="activeExtension.publisherEmail">
<NcDivider />
<div class="extension-details-right-section">
<div class="extension-details-right-title">Publisher Email</div>
<div class="extension-details-right-subtitle">
<a :href="`mailto:${activeExtension.publisherEmail}`" target="_blank" rel="noopener noreferrer">
{{ activeExtension.publisherEmail }}
</a>
</div>
</div>
</template>
<template v-if="activeExtension.publisherUrl">
<NcDivider />
<div class="extension-details-right-section">
<div class="extension-details-right-title">Publisher Website</div>
<div class="extension-details-right-subtitle">
<a :href="activeExtension.publisherUrl" target="_blank" rel="noopener noreferrer">
{{ activeExtension.publisherUrl }}
</a>
</div>
</div>
</template>
</div>
</div>
</div>
</NcModal>
</template>
<style lang="scss" scoped>
.extension-details {
@apply flex w-full h-[calc(100%_-_65px)];
.extension-details-left {
@apply p-6 flex-1 flex flex-col gap-6 nc-scrollbar-thin;
}
.extension-details-right {
@apply p-5 w-[320px] flex flex-col space-y-4 border-l-1 border-gray-200 bg-gray-50 nc-scrollbar-thin;
.extension-details-right-section {
@apply flex flex-col gap-2;
}
.extension-details-right-title {
@apply text-sm font-semibold text-gray-800;
}
.extension-details-right-subtitle {
@apply text-sm font-weight-500 text-gray-600;
}
}
}
</style>
<style lang="scss">
.nc-modal-extension-details {
.ant-modal-content {
@apply overflow-hidden;
}
.nc-modal {
@apply !p-0;
height: min(calc(100vh - 100px), 1024px);
max-height: min(calc(100vh - 100px), 1024px) !important;
.nc-edit-or-add-integration-left-panel {
@apply w-full p-6 flex-1 flex justify-center;
}
.nc-edit-or-add-integration-right-panel {
@apply p-5 w-[320px] border-l-1 border-gray-200 flex flex-col gap-4 bg-gray-50 rounded-br-2xl;
}
}
.nc-extension-details-body {
p {
@apply !m-0 !leading-5;
}
ul {
li {
@apply ml-4;
list-style-type: disc;
}
}
ol {
@apply !pl-4;
li {
list-style-type: decimal;
}
}
ul,
ol {
@apply !my-0;
}
// Pre tag is the parent wrapper for Code block
pre {
@apply overflow-auto mt-3 bg-gray-100;
border-color: #d0d5dd;
border: 1px;
color: black;
font-family: 'JetBrainsMono', monospace;
padding: 1rem;
border-radius: 0.5rem;
height: fit-content;
code {
@apply !px-0;
}
}
code {
@apply rounded-md px-2 py-1 bg-gray-100;
color: inherit;
font-size: 0.8rem;
}
blockquote {
border-left: 3px solid #d0d5dd;
padding: 0 1em;
color: #666;
margin: 1em 0;
font-style: italic;
}
hr {
@apply !border-gray-300;
border: 0;
border-top: 1px solid #ccc;
margin: 1.5em 0;
}
h1 {
font-weight: 700;
font-size: 1.85rem;
margin-bottom: 0.1rem;
line-height: 36px;
}
h2 {
font-weight: 600;
font-size: 1.55rem;
margin-bottom: 0.1em;
line-height: 30px;
}
h3 {
font-weight: 600;
font-size: 1.15rem;
margin-bottom: 0.1em;
line-height: 24px;
}
}
}
</style>