Feature: iFrame widget (#2261)
--------- Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
parent
5512d05f00
commit
ebd384c62d
7 changed files with 111 additions and 0 deletions
35
docs/widgets/services/iframe.md
Normal file
35
docs/widgets/services/iframe.md
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
title: iFrame
|
||||||
|
Description: Add a custom iFrame Widget
|
||||||
|
---
|
||||||
|
|
||||||
|
A basic iFrame widget to show external content, see the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) for more details about some of the options.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
Requests made via the iFrame widget are inherently **not proxied** as they are made from the browser itself.
|
||||||
|
|
||||||
|
## Basic Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
widget:
|
||||||
|
type: iframe
|
||||||
|
name: myIframe
|
||||||
|
src: http://example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Full Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
widget:
|
||||||
|
type: iframe
|
||||||
|
name: myIframe
|
||||||
|
src: http://example.com
|
||||||
|
classes: h-60 sm:h-60 md:h-60 lg:h-60 xl:h-60 2xl:h-72 # optional, use tailwind height classes, see https://tailwindcss.com/docs/height
|
||||||
|
referrerPolicy: same-origin # optional, no default
|
||||||
|
allowPolicy: autoplay fullscreen gamepad # optional, no default
|
||||||
|
allowFullscreen: false # optional, default: true
|
||||||
|
loadingStrategy: eager # optional, default: eager
|
||||||
|
allowScrolling: no # optional, default: yes
|
||||||
|
refreshInterval: 2000 # optional, no default
|
||||||
|
```
|
|
@ -63,6 +63,7 @@ nav:
|
||||||
- widgets/services/healthchecks.md
|
- widgets/services/healthchecks.md
|
||||||
- widgets/services/homeassistant.md
|
- widgets/services/homeassistant.md
|
||||||
- widgets/services/homebridge.md
|
- widgets/services/homebridge.md
|
||||||
|
- widgets/services/iframe.md
|
||||||
- widgets/services/immich.md
|
- widgets/services/immich.md
|
||||||
- widgets/services/jackett.md
|
- widgets/services/jackett.md
|
||||||
- widgets/services/jdownloader.md
|
- widgets/services/jdownloader.md
|
||||||
|
|
|
@ -366,6 +366,13 @@ export function cleanServiceGroups(groups) {
|
||||||
firstDayInWeek,
|
firstDayInWeek,
|
||||||
view,
|
view,
|
||||||
maxEvents,
|
maxEvents,
|
||||||
|
src, // iframe widget
|
||||||
|
classes,
|
||||||
|
referrerPolicy,
|
||||||
|
allowPolicy,
|
||||||
|
allowFullscreen,
|
||||||
|
loadingStrategy,
|
||||||
|
allowScrolling,
|
||||||
} = cleanedService.widget;
|
} = cleanedService.widget;
|
||||||
|
|
||||||
let fieldsList = fields;
|
let fieldsList = fields;
|
||||||
|
@ -413,6 +420,16 @@ export function cleanServiceGroups(groups) {
|
||||||
if (app) cleanedService.widget.app = app;
|
if (app) cleanedService.widget.app = app;
|
||||||
if (podSelector) cleanedService.widget.podSelector = podSelector;
|
if (podSelector) cleanedService.widget.podSelector = podSelector;
|
||||||
}
|
}
|
||||||
|
if (type === "iframe") {
|
||||||
|
if (src) cleanedService.widget.src = src;
|
||||||
|
if (classes) cleanedService.widget.classes = classes;
|
||||||
|
if (referrerPolicy) cleanedService.widget.referrerPolicy = referrerPolicy;
|
||||||
|
if (allowPolicy) cleanedService.widget.allowPolicy = allowPolicy;
|
||||||
|
if (allowFullscreen) cleanedService.widget.allowFullscreen = allowFullscreen;
|
||||||
|
if (loadingStrategy) cleanedService.widget.loadingStrategy = loadingStrategy;
|
||||||
|
if (allowScrolling) cleanedService.widget.allowScrolling = allowScrolling;
|
||||||
|
if (refreshInterval) cleanedService.widget.refreshInterval = refreshInterval;
|
||||||
|
}
|
||||||
if (["opnsense", "pfsense"].includes(type)) {
|
if (["opnsense", "pfsense"].includes(type)) {
|
||||||
if (wan) cleanedService.widget.wan = wan;
|
if (wan) cleanedService.widget.wan = wan;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ const components = {
|
||||||
channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")),
|
channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")),
|
||||||
cloudflared: dynamic(() => import("./cloudflared/component")),
|
cloudflared: dynamic(() => import("./cloudflared/component")),
|
||||||
coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
|
coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
|
||||||
|
iframe: dynamic(() => import("./iframe/component")),
|
||||||
customapi: dynamic(() => import("./customapi/component")),
|
customapi: dynamic(() => import("./customapi/component")),
|
||||||
deluge: dynamic(() => import("./deluge/component")),
|
deluge: dynamic(() => import("./deluge/component")),
|
||||||
diskstation: dynamic(() => import("./diskstation/component")),
|
diskstation: dynamic(() => import("./diskstation/component")),
|
||||||
|
|
50
src/widgets/iframe/component.jsx
Normal file
50
src/widgets/iframe/component.jsx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const [refreshTimer, setRefreshTimer] = useState(0);
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (widget?.refreshInterval) {
|
||||||
|
setInterval(
|
||||||
|
() => setRefreshTimer(refreshTimer + 1),
|
||||||
|
widget?.refreshInterval < 1000 ? 1000 : widget?.refreshInterval,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [refreshTimer, widget?.refreshInterval]);
|
||||||
|
|
||||||
|
const scrollingDisableStyle = widget?.allowScrolling === "no" ? { pointerEvents: "none", overflow: "hidden" } : {};
|
||||||
|
|
||||||
|
const classes = widget?.classes || "h-60 sm:h-60 md:h-60 lg:h-60 xl:h-60 2xl:h-72";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
"bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center text-center",
|
||||||
|
"service-block",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
src={widget?.src}
|
||||||
|
key={`${widget?.name}-${refreshTimer}`}
|
||||||
|
name={widget?.name}
|
||||||
|
title={widget?.name}
|
||||||
|
allow={widget?.allowPolicy}
|
||||||
|
allowFullScreen={widget?.allowfullscreen}
|
||||||
|
referrerPolicy={widget?.referrerPolicy}
|
||||||
|
loading={widget?.loadingStrategy}
|
||||||
|
scrolling={widget?.allowScrolling}
|
||||||
|
style={{
|
||||||
|
scrollingDisableStyle,
|
||||||
|
}}
|
||||||
|
className={`rounded w-full ${classes}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
3
src/widgets/iframe/widget.js
Normal file
3
src/widgets/iframe/widget.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const widget = {};
|
||||||
|
|
||||||
|
export default widget;
|
|
@ -76,5 +76,9 @@ module.exports = {
|
||||||
"dark:bg-white",
|
"dark:bg-white",
|
||||||
"bg-orange-400",
|
"bg-orange-400",
|
||||||
"dark:bg-orange-400",
|
"dark:bg-orange-400",
|
||||||
|
{
|
||||||
|
pattern: /h-([0-96])/,
|
||||||
|
variants: ["sm", "md", "lg", "xl", "2xl"],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue