Skip to content

Commit

Permalink
chore(web): show tooltip when pressing copy button (#1233)
Browse files Browse the repository at this point in the history
chore: show tooltip when pressing copy button
  • Loading branch information
caichi-t authored Sep 19, 2024
1 parent ea80f28 commit b19a234
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 78 deletions.
15 changes: 14 additions & 1 deletion web/src/components/molecules/Accessibility/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Input from "@reearth-cms/components/atoms/Input";
import Select from "@reearth-cms/components/atoms/Select";
import Switch from "@reearth-cms/components/atoms/Switch";
import Table, { TableColumnsType } from "@reearth-cms/components/atoms/Table";
import Tooltip from "@reearth-cms/components/atoms/Tooltip";
import { PublicScope } from "@reearth-cms/components/molecules/Accessibility/types";
import { Model } from "@reearth-cms/components/molecules/Model/types";
import { useT } from "@reearth-cms/i18n";
Expand Down Expand Up @@ -154,7 +155,11 @@ const Accessibility: React.FC<Props> = ({
<Form.Item label={t("Project Alias")}>
<Input
value={aliasState}
suffix={<Icon icon="copy" onClick={handleCopy} />}
suffix={
<Tooltip title={t("Alias copied!!")} trigger={"click"}>
<StyledIcon icon="copy" onClick={handleCopy} />
</Tooltip>
}
contentEditable={false}
/>
</Form.Item>
Expand Down Expand Up @@ -185,3 +190,11 @@ const StyledAnchor = styled.a`
text-decoration: underline;
color: #000000d9;
`;

const StyledIcon = styled(Icon)`
transition: all 0.3s;
color: rgb(0, 0, 0, 0.45);
:hover {
color: rgba(0, 0, 0, 0.88);
}
`;
26 changes: 15 additions & 11 deletions web/src/components/molecules/Asset/Asset/AssetBody/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from "@reearth-cms/components/atoms/Button";
import DownloadButton from "@reearth-cms/components/atoms/DownloadButton";
import Icon from "@reearth-cms/components/atoms/Icon";
import Space from "@reearth-cms/components/atoms/Space";
import Tooltip from "@reearth-cms/components/atoms/Tooltip";
import UserAvatar from "@reearth-cms/components/atoms/UserAvatar";
import Card from "@reearth-cms/components/molecules/Asset/Asset/AssetBody/card";
import PreviewToolbar from "@reearth-cms/components/molecules/Asset/Asset/AssetBody/previewToolbar";
Expand Down Expand Up @@ -122,19 +123,20 @@ const AssetMolecule: React.FC<Props> = ({
}
}, [assetFileExt, assetUrl, svgRender, viewerType, workspaceSettings]);

const handleCopy = useCallback(() => {
navigator.clipboard.writeText(asset.url);
}, [asset.url]);

return (
<BodyContainer>
<BodyWrapper>
<Card
title={
<>
{asset.fileName}{" "}
<CopyIcon
icon="copy"
onClick={() => {
navigator.clipboard.writeText(asset.url);
}}
/>
{asset.fileName}
<Tooltip title={t("URL copied!!")} trigger={"click"}>
<CopyIcon icon="copy" onClick={handleCopy} />
</Tooltip>
</>
}
toolbar={
Expand Down Expand Up @@ -203,10 +205,12 @@ const AssetMolecule: React.FC<Props> = ({
);
};

const CopyIcon = styled(Icon)<{ selected?: boolean }>`
margin-left: 16px;
&:active {
color: #096dd9;
const CopyIcon = styled(Icon)`
margin-left: 10px;
transition: all 0.3s;
color: rgb(0, 0, 0, 0.45);
:hover {
color: rgba(0, 0, 0, 0.88);
}
`;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Key } from "rc-table/lib/interface";
import { expect, test } from "vitest";

import { AssetFile } from "@reearth-cms/components/molecules/Asset/types";

import { generateAssetTreeData } from "./generateAssetTreeData";

test("returns empty array if filePaths property is not provided", () => {
const result = generateAssetTreeData({ name: "", path: "/" }, [], "http://example.com");
const result = generateAssetTreeData({ name: "", path: "/" });
expect(result).toEqual([]);
});

Expand All @@ -21,9 +20,7 @@ test("returns correct file tree data", () => {
"/folder3/file4.txt",
],
};
const selectedKeys: Key[] = [];
const assetBaseUrl = "http://example.com";
const result = generateAssetTreeData(file, selectedKeys, assetBaseUrl);
const result = generateAssetTreeData(file);

// /folder1/
expect(result[0].key).toEqual("0-0");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import styled from "@emotion/styled";
import { Key } from "rc-table/lib/interface";

import Icon from "@reearth-cms/components/atoms/Icon";
import { AssetFile } from "@reearth-cms/components/molecules/Asset/types";

import { FileNode } from "./types";

export const generateAssetTreeData = (
file: AssetFile,
selectedKeys: Key[],
assetBaseUrl: string,
): FileNode[] => {
export const generateAssetTreeData = (file: AssetFile): FileNode[] => {
if (!file.filePaths) return [];

const root: FileNode = {
Expand All @@ -30,21 +22,10 @@ export const generateAssetTreeData = (
const key = `${i}-${j}`;
const path = `${currentNode.path}${part}${/\.[^.]+$/.test(part) ? "" : "/"}`;
const newNode: FileNode = {
key: key,
title: (
<>
{part}
<CopyIcon
selected={selectedKeys[0] === key}
icon="copy"
onClick={() => {
navigator.clipboard.writeText(assetBaseUrl + path);
}}
/>
</>
),
key,
title: part,
name: part,
path: path,
path,
children: [],
};

Expand All @@ -58,11 +39,3 @@ export const generateAssetTreeData = (

return root.children;
};

const CopyIcon = styled(Icon)<{ selected?: boolean }>`
margin-left: 16px;
visibility: ${({ selected }) => (selected ? "visible" : "hidden")};
&:active {
color: #096dd9;
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useCallback, useEffect, useState } from "react";

import Icon from "@reearth-cms/components/atoms/Icon";
import Spin from "@reearth-cms/components/atoms/Spin";
import Tooltip from "@reearth-cms/components/atoms/Tooltip";
import Tree, { TreeProps } from "@reearth-cms/components/atoms/Tree";
import { ArchiveExtractionStatus, AssetFile } from "@reearth-cms/components/molecules/Asset/types";
import { useT } from "@reearth-cms/i18n";
Expand All @@ -26,14 +27,13 @@ const UnzipFileList: React.FC<Props> = ({
}) => {
const t = useT();

const [expandedKeys, setExpandedKeys] = useState<FileNode["key"][]>(["0-0"]);
const [selectedKeys, setSelectedKeys] = useState<FileNode["key"][]>([]);
const [treeData, setTreeData] = useState<FileNode[]>([]);
const [treeData, setTreeData] = useState<FileNode[]>();

useEffect(() => {
const data = generateAssetTreeData(file, selectedKeys, assetBaseUrl);
const data = generateAssetTreeData(file);
setTreeData(data);
}, [assetBaseUrl, file, selectedKeys]);
}, [file]);

const previewFile = useCallback(
(path: string) => {
Expand All @@ -51,9 +51,12 @@ const UnzipFileList: React.FC<Props> = ({
[previewFile, selectedKeys],
);

const handleExpand: TreeProps["onExpand"] = (keys: Key[]) => {
setExpandedKeys([...keys]);
};
const handleCopy = useCallback(
(path: string) => {
navigator.clipboard.writeText(assetBaseUrl + path);
},
[assetBaseUrl],
);

return (
<UnzipFileListWrapper>
Expand All @@ -69,16 +72,29 @@ const UnzipFileList: React.FC<Props> = ({
</ExtractionFailedText>
</ExtractionFailedWrapper>
) : (
<Tree
switcherIcon={<Icon icon="caretDown" />}
expandedKeys={[...expandedKeys]}
selectedKeys={[...selectedKeys]}
onSelect={handleSelect}
onExpand={handleExpand}
treeData={treeData}
multiple={false}
showLine
/>
treeData && (
<Tree
switcherIcon={<Icon icon="caretDown" />}
defaultExpandedKeys={["0-0"]}
selectedKeys={selectedKeys}
onSelect={handleSelect}
treeData={treeData}
multiple={false}
showLine
titleRender={({ title, key, path }) => {
return (
<>
{title}
{selectedKeys[0] === key && (
<Tooltip title={t("URL copied!!")} trigger={"click"}>
<CopyIcon icon="copy" onClick={() => handleCopy(path)} />
</Tooltip>
)}
</>
);
}}
/>
)
)}
</UnzipFileListWrapper>
);
Expand Down Expand Up @@ -119,4 +135,13 @@ const ExtractionFailedText = styled.p`
color: rgba(0, 0, 0, 0.85);
`;

const CopyIcon = styled(Icon)`
margin-left: 6px;
transition: all 0.3s;
color: rgb(0, 0, 0, 0.45);
:hover {
color: rgba(0, 0, 0, 0.88);
}
`;

export default UnzipFileList;
17 changes: 11 additions & 6 deletions web/src/components/molecules/Common/Form/GeometryItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Icon from "@reearth-cms/components/atoms/Icon";
import mapPinFilled from "@reearth-cms/components/atoms/Icon/Icons/mapPinFilled.svg";
import Input from "@reearth-cms/components/atoms/Input";
import Modal from "@reearth-cms/components/atoms/Modal";
import Tooltip from "@reearth-cms/components/atoms/Tooltip";
import Typography from "@reearth-cms/components/atoms/Typography";
import {
ObjectSupportedType,
Expand Down Expand Up @@ -267,7 +268,7 @@ const GeometryItem: React.FC<Props> = ({
}, [currentValue, typeCheck, value]);

const placeholderContent = useMemo(() => {
const key = Array.isArray(supportedTypes) ? supportedTypes[0] : supportedTypes ?? "POINT";
const key = Array.isArray(supportedTypes) ? supportedTypes[0] : (supportedTypes ?? "POINT");
const obj: {
type: string;
coordinates?: unknown;
Expand Down Expand Up @@ -505,16 +506,20 @@ const GeometryItem: React.FC<Props> = ({
handle={<span className="react-resizable-handle" />}>
<EditorWrapper hasError={hasError} width={width}>
<EditorButtons>
<EditorButton
icon={<Icon icon="editorCopy" size={12} />}
size="small"
onClick={copyButtonClick}
/>
<Tooltip title={t("Value copied!!")} trigger={"click"}>
<EditorButton
icon={<Icon icon="editorCopy" size={12} />}
size="small"
onClick={copyButtonClick}
disabled={!currentValue}
/>
</Tooltip>
{!disabled && (
<EditorButton
icon={<Icon icon="trash" size={12} />}
size="small"
onClick={deleteButtonClick}
disabled={!currentValue}
/>
)}
</EditorButtons>
Expand Down
17 changes: 10 additions & 7 deletions web/src/components/molecules/MyIntegrations/Settings/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
import { useCallback, useMemo, useState } from "react";
import { useCallback, useState } from "react";

import Button from "@reearth-cms/components/atoms/Button";
import Col from "@reearth-cms/components/atoms/Col";
Expand All @@ -10,6 +10,7 @@ import Input from "@reearth-cms/components/atoms/Input";
import Modal from "@reearth-cms/components/atoms/Modal";
import Row from "@reearth-cms/components/atoms/Row";
import TextArea from "@reearth-cms/components/atoms/TextArea";
import Tooltip from "@reearth-cms/components/atoms/Tooltip";
import { Integration } from "@reearth-cms/components/molecules/MyIntegrations/types";
import { useT } from "@reearth-cms/i18n";

Expand Down Expand Up @@ -84,11 +85,8 @@ const MyIntegrationForm: React.FC<Props> = ({
});
}, [t, onRegenerateToken]);

const copyIcon = useMemo(() => {
const onClick = () => {
if (integration.config.token) navigator.clipboard.writeText(integration.config.token);
};
return <Icon icon="copy" onClick={onClick} />;
const handleCopy = useCallback(() => {
if (integration.config.token) navigator.clipboard.writeText(integration.config.token);
}, [integration.config.token]);

return (
Expand Down Expand Up @@ -117,7 +115,11 @@ const MyIntegrationForm: React.FC<Props> = ({
<StyledTokenInput
value={integration.config.token}
contentEditable={false}
prefix={copyIcon}
prefix={
<Tooltip title={t("Token copied!!")} trigger={"click"}>
<Icon icon="copy" onClick={handleCopy} />
</Tooltip>
}
/>
<StyledRegenerateTokenButton
type="primary"
Expand Down Expand Up @@ -185,6 +187,7 @@ const StyledTokenInput = styled(Input.Password)`
order: 1;
margin-left: 4px;
color: rgb(0, 0, 0, 0.45);
transition: all 0.3s;
:hover {
color: rgba(0, 0, 0, 0.88);
}
Expand Down
4 changes: 4 additions & 0 deletions web/src/i18n/translations/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Accessibility: ''
Public Scope: ''
Choose the scope of your project. This affects all the models shown below that are switched on.: ''
Project Alias: ''
Alias copied!!: ''
Save changes: ''
Are you sure you want to delete your account?: ''
Cancel: ''
Expand All @@ -34,6 +35,7 @@ Auto: ''
Service Language: ''
This will change the UI language: ''
Language: ''
URL copied!!: ''
Unzip: ''
Asset Type: ''
Created Time: ''
Expand Down Expand Up @@ -88,6 +90,7 @@ You are entering a new value: ''
This action will replace the previously entered value. Do you want to continue?: ''
Do not show this again: ''
Continue: ''
Value copied!!: ''
Search Location: ''
GeoJSON type mismatch, please check your input: ''
Personal Account: ''
Expand Down Expand Up @@ -229,6 +232,7 @@ Regenerate The Integration Token?: ''
If you regenerate the integration token, the previous token will become invalid, and this action cannot be undone. Are you sure you want to proceed?: ''
Reset: ''
Integration Token: ''
Token copied!!: ''
Regenerate: ''
Code Example: ''
your model id here: ''
Expand Down
Loading

0 comments on commit b19a234

Please sign in to comment.