feat: add iframe widget for dashboard (#7516)

#### What type of PR is this?

/area ui
/kind feature
/milestone 2.21.x

#### What this PR does / why we need it:

Add iframe widget for dashboard

<img width="1212" alt="image" src="https://github.com/user-attachments/assets/e31bb9f2-5120-4565-ad2d-cf878b4c9d53" />

#### Does this PR introduce a user-facing change?

```release-note
为仪表盘添加网页嵌入小部件
```
pull/7530/head
Ryan Wang 2025-06-10 00:46:34 +08:00 committed by GitHub
parent c50099e491
commit 2332e09ead
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 101 additions and 0 deletions

View File

@ -3,6 +3,7 @@ import type { DashboardWidgetDefinition } from "@halo-dev/console-shared";
import { markRaw } from "vue";
import CommentStatsWidget from "./presets/comments/CommentStatsWidget.vue";
import PendingCommentsWidget from "./presets/comments/PendingCommentsWidget.vue";
import IframeWidget from "./presets/core/iframe/IframeWidget.vue";
import QuickActionWidget from "./presets/core/quick-action/QuickActionWidget.vue";
import StackWidget from "./presets/core/stack/StackWidget.vue";
import ViewsStatsWidget from "./presets/core/view-stats/ViewsStatsWidget.vue";
@ -204,4 +205,31 @@ export const internalWidgetDefinitions: DashboardWidgetDefinition[] = [
minW: 1,
},
},
{
id: "core:iframe",
component: markRaw(IframeWidget),
group: "core.dashboard.widgets.groups.other",
configFormKitSchema: () => [
{
$formkit: "text",
label: i18n.global.t(
"core.dashboard.widgets.presets.iframe.config.fields.title.label"
),
name: "title",
},
{
$formkit: "url",
label: "URL",
name: "url",
validation: "required|url",
},
],
defaultConfig: {},
defaultSize: {
w: 6,
h: 12,
minH: 2,
minW: 2,
},
},
];

View File

@ -0,0 +1,41 @@
<script setup lang="ts">
import WidgetCard from "@console/modules/dashboard/components/WidgetCard.vue";
defineProps<{
previewMode?: boolean;
editMode?: boolean;
config: {
title?: string;
url?: string;
};
}>();
</script>
<template>
<WidgetCard
:title="
previewMode
? $t('core.dashboard.widgets.presets.iframe.title')
: config.title
"
>
<div
v-if="!config.url"
class="flex items-center justify-center w-full h-full"
>
<span class="text-sm text-gray-600">
{{ $t("core.dashboard.widgets.presets.iframe.empty.title") }}
</span>
</div>
<iframe
v-else
:src="config.url"
sandbox="allow-scripts allow-same-origin"
credentialless
referrerpolicy="no-referrer"
class="w-full h-full border-none"
:class="{
'pointer-events-none': editMode,
}"
></iframe>
</WidgetCard>
</template>

View File

@ -46,6 +46,14 @@ core:
title: Pending Comments
empty:
title: No pending comments
iframe:
title: Iframe
empty:
title: Please enter the URL in the configuration
config:
fields:
title:
label: Title
stack:
title: Widget Stack
operations:

View File

@ -116,6 +116,14 @@ core:
title: No pending comments
views_stats:
title: Visits
iframe:
title: Iframe
empty:
title: Please enter the URL in the configuration
config:
fields:
title:
label: Title
stack:
title: Widget Stack
operations:

View File

@ -108,6 +108,14 @@ core:
title: 新评论
empty:
title: 暂无待审核评论
iframe:
title: 网页嵌入
empty:
title: 请在配置中输入 URL
config:
fields:
title:
label: 标题
stack:
title: 堆叠部件
operations:

View File

@ -108,6 +108,14 @@ core:
title: 新評論
empty:
title: 沒有待審核評論
iframe:
title: 網頁嵌入
empty:
title: 請在配置中輸入 URL
config:
fields:
title:
label: 標題
stack:
title: 堆疊部件
operations: