mirror of https://github.com/jetkvm/kvm.git
backport: versioning cloud app (0.3.8)
This commit is contained in:
parent
43bf322c75
commit
55ff16c4a2
|
|
@ -32,7 +32,7 @@
|
|||
"react-simple-keyboard": "^3.7.112",
|
||||
"react-xtermjs": "^1.0.9",
|
||||
"recharts": "^2.15.1",
|
||||
"semver": "^7.7.1",
|
||||
"semver": "^7.7.3",
|
||||
"tailwind-merge": "^2.5.5",
|
||||
"usehooks-ts": "^3.1.1",
|
||||
"validator": "^13.12.0",
|
||||
|
|
@ -5336,9 +5336,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
"react-simple-keyboard": "^3.7.112",
|
||||
"react-xtermjs": "^1.0.9",
|
||||
"recharts": "^2.15.1",
|
||||
"semver": "^7.7.1",
|
||||
"semver": "^7.7.3",
|
||||
"tailwind-merge": "^2.5.5",
|
||||
"usehooks-ts": "^3.1.1",
|
||||
"validator": "^13.12.0",
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonPropsType>(
|
|||
|
||||
Button.displayName = "Button";
|
||||
|
||||
type LinkPropsType = Pick<LinkProps, "to"> &
|
||||
type LinkPropsType = Pick<LinkProps, "to" | "target" | "reloadDocument"> &
|
||||
React.ComponentProps<typeof ButtonContent> & { disabled?: boolean };
|
||||
export const LinkButton = ({ to, ...props }: LinkPropsType) => {
|
||||
const classes = cx(
|
||||
|
|
@ -223,13 +223,13 @@ export const LinkButton = ({ to, ...props }: LinkPropsType) => {
|
|||
|
||||
if (to.toString().startsWith("http")) {
|
||||
return (
|
||||
<ExtLink href={to.toString()} className={classes}>
|
||||
<ExtLink href={to.toString()} className={classes} target={props.target}>
|
||||
<ButtonContent {...props} />
|
||||
</ExtLink>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Link to={to} className={classes}>
|
||||
<Link to={to} className={classes} target={props.target} reloadDocument={props.reloadDocument}>
|
||||
<ButtonContent {...props} />
|
||||
</Link>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { MdConnectWithoutContact } from "react-icons/md";
|
|||
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { LuEllipsisVertical } from "react-icons/lu";
|
||||
import semver from "semver";
|
||||
import { useMemo } from "react";
|
||||
|
||||
function getRelativeTimeString(date: Date | number, lang = navigator.language): string {
|
||||
// Allow dates or times to be passed
|
||||
|
|
@ -43,12 +45,33 @@ export default function KvmCard({
|
|||
id,
|
||||
online,
|
||||
lastSeen,
|
||||
appVersion,
|
||||
}: {
|
||||
title: string;
|
||||
id: string;
|
||||
online: boolean;
|
||||
lastSeen: Date | null;
|
||||
appVersion: string;
|
||||
}) {
|
||||
/**
|
||||
* Constructs the URL for connecting to this KVM device's interface.
|
||||
*
|
||||
* Version 0.4.91 is the last backwards-compatible UI that works with older devices.
|
||||
* Devices on v0.4.91 or below are served that version, while newer devices get
|
||||
* their actual version. Unparseable versions fall back to 0.4.91 for safety.
|
||||
*/
|
||||
const kvmUrl = useMemo(() => {
|
||||
const BACKWARDS_COMPATIBLE_VERSION = "0.4.91";
|
||||
|
||||
// Use device version if valid and >= 0.4.91, otherwise fall back to backwards-compatible version
|
||||
const shouldUseDeviceVersion =
|
||||
semver.valid(appVersion) && semver.gte(appVersion, BACKWARDS_COMPATIBLE_VERSION);
|
||||
const version = shouldUseDeviceVersion ? appVersion : BACKWARDS_COMPATIBLE_VERSION;
|
||||
|
||||
return new URL(`/v/${version}/devices/${id}`, window.location.origin).toString();
|
||||
}, [appVersion, id]);
|
||||
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-5 py-5 space-y-3">
|
||||
|
|
@ -87,7 +110,9 @@ export default function KvmCard({
|
|||
text="Connect to KVM"
|
||||
LeadingIcon={MdConnectWithoutContact}
|
||||
textAlign="center"
|
||||
to={`/devices/${id}`}
|
||||
reloadDocument
|
||||
target="_self"
|
||||
to={kvmUrl}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -302,7 +302,8 @@ if (isOnDevice) {
|
|||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
// We only need to do this for the cloud deployment, because the device doesn't need to be versioned
|
||||
], { basename: import.meta.env.BASE_URL });
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,13 @@ import { ArrowRightIcon } from "@heroicons/react/16/solid";
|
|||
import { CLOUD_API } from "@/ui.config";
|
||||
|
||||
interface LoaderData {
|
||||
devices: { id: string; name: string; online: boolean; lastSeen: string }[];
|
||||
devices: {
|
||||
id: string;
|
||||
name: string;
|
||||
online: boolean;
|
||||
lastSeen: string;
|
||||
version: string;
|
||||
}[];
|
||||
user: User;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue