mirror of
https://github.com/sergi0g/cup.git
synced 2025-11-16 09:03:46 -05:00
Bug fixes for the previous UI improvements (I tested properly this time)
This commit is contained in:
43
web/src/components/CodeBlock.tsx
Normal file
43
web/src/components/CodeBlock.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { ReactNode, useState } from "react";
|
||||||
|
import { theme } from "../theme";
|
||||||
|
import { IconCheck, IconClipboard } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
export function CodeBlock({
|
||||||
|
children,
|
||||||
|
enableCopy,
|
||||||
|
}: {
|
||||||
|
children: ReactNode;
|
||||||
|
enableCopy?: boolean;
|
||||||
|
}) {
|
||||||
|
const [copySuccess, setCopySuccess] = useState(false);
|
||||||
|
const handleCopy = (text: string) => {
|
||||||
|
return () => {
|
||||||
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
|
setCopySuccess(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCopySuccess(false);
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`group relative flex w-full items-center rounded-lg bg-${theme}-100 px-3 py-2 font-mono text-${theme}-700 dark:bg-${theme}-950 dark:text-${theme}-300`}
|
||||||
|
>
|
||||||
|
<p className="overflow-scroll">{children}</p>
|
||||||
|
{enableCopy &&
|
||||||
|
navigator.clipboard &&
|
||||||
|
(copySuccess ? (
|
||||||
|
<IconCheck className={`absolute right-3 size-7 bg-${theme}-100 pl-2 py-1 dark:bg-${theme}-950`} />
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className={`duration-50 absolute right-3 bg-${theme}-100 pl-2 py-1 opacity-0 transition-opacity group-hover:opacity-100 dark:bg-${theme}-950`}
|
||||||
|
onClick={handleCopy(`docker pull ${children}`)}
|
||||||
|
>
|
||||||
|
<IconClipboard className="size-5" />
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
import { WithTooltip } from "./Tooltip";
|
import { WithTooltip } from "./Tooltip";
|
||||||
import type { Image } from "../types";
|
import type { Image } from "../types";
|
||||||
import { theme } from "../theme";
|
import { theme } from "../theme";
|
||||||
import { PullCommand } from "./PullCommand";
|
import { CodeBlock } from "./CodeBlock";
|
||||||
|
|
||||||
const clickable_registries = [
|
const clickable_registries = [
|
||||||
"registry-1.docker.io",
|
"registry-1.docker.io",
|
||||||
@@ -125,7 +125,10 @@ export default function Image({ data }: { data: Image }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{data.result.has_update && (
|
{data.result.has_update && (
|
||||||
<PullCommand reference={new_reference} />
|
<div className="flex flex-col gap-1">
|
||||||
|
Pull command
|
||||||
|
<CodeBlock enableCopy>{new_reference}</CodeBlock>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
{data.result.info?.type == "digest" && (
|
{data.result.info?.type == "digest" && (
|
||||||
@@ -133,23 +136,15 @@ export default function Image({ data }: { data: Image }) {
|
|||||||
{data.result.info.local_digests.length > 1
|
{data.result.info.local_digests.length > 1
|
||||||
? "Local digests"
|
? "Local digests"
|
||||||
: "Local digest"}
|
: "Local digest"}
|
||||||
<div
|
<CodeBlock enableCopy>
|
||||||
className={`bg-${theme}-100 dark:bg-${theme}-950 scrollable rounded-md px-3 py-2 font-mono text-${theme}-500`}
|
{data.result.info.local_digests.join("\n")}
|
||||||
>
|
</CodeBlock>
|
||||||
<p className="overflow-x-scroll">
|
|
||||||
{data.result.info.local_digests.join("\n")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{data.result.info.remote_digest && (
|
{data.result.info.remote_digest && (
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
Remote digest
|
Remote digest
|
||||||
<div
|
<CodeBlock enableCopy>
|
||||||
className={`bg-${theme}-100 dark:bg-${theme}-950 rounded-md px-3 py-2 font-mono text-${theme}-500`}
|
{data.result.info.remote_digest}
|
||||||
>
|
</CodeBlock>
|
||||||
<p className="overflow-x-scroll">
|
|
||||||
{data.result.info.remote_digest}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { theme } from "../theme";
|
|
||||||
import { IconCheck, IconClipboard } from "@tabler/icons-react";
|
|
||||||
|
|
||||||
export function PullCommand({ reference }: { reference: string }) {
|
|
||||||
const [copySuccess, setCopySuccess] = useState(false);
|
|
||||||
const handleCopy = (text: string) => {
|
|
||||||
return () => {
|
|
||||||
navigator.clipboard.writeText(text).then(() => {
|
|
||||||
setCopySuccess(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setCopySuccess(false);
|
|
||||||
}, 3000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
Pull command
|
|
||||||
<div
|
|
||||||
className={`w-full group relative flex items-center rounded-lg bg-${theme}-100 px-3 py-2 font-mono text-${theme}-700 dark:bg-${theme}-950 dark:text-${theme}-300`}
|
|
||||||
>
|
|
||||||
<p className="overflow-scroll">docker pull {reference}</p>
|
|
||||||
{navigator.clipboard &&
|
|
||||||
(copySuccess ? (
|
|
||||||
<IconCheck className="absolute right-3 size-7 bg-neutral-100 pl-2 dark:bg-neutral-950" />
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
className="duration-50 absolute right-3 opacity-0 transition-opacity group-hover:opacity-100"
|
|
||||||
onClick={handleCopy(`docker pull ${reference}`)}
|
|
||||||
>
|
|
||||||
<IconClipboard className="size-5"/>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user