handle copy and paste

This commit is contained in:
shams mosowi
2019-10-04 13:57:18 +10:00
parent aad524226e
commit fe134cf196
7 changed files with 113 additions and 8 deletions

View File

@@ -21,6 +21,7 @@
"csv-parse": "^4.4.6",
"date-fns": "^2.0.0-beta.5",
"firebase": "^6.6.0",
"hotkeys-js": "^3.7.2",
"lodash": "^4.17.15",
"ramda": "^0.26.1",
"react": "^16.9.0",

View File

@@ -41,7 +41,7 @@ const Date = (props: Props) => {
{fieldType === FieldType.date ? (
<DatePicker
className={classes.field}
value={value ? value.toDate() : null}
value={value && value.toDate ? value.toDate() : null}
onChange={handleDateChange}
format="dd/MM/yy"
emptyLabel="select a date"

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import ExpandIcon from "@material-ui/icons/AspectRatio";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
@@ -33,7 +33,9 @@ interface Props {
const LongText = (props: Props) => {
const { value, onSubmit } = props;
const [text, setText] = useState(value ? value : "");
useEffect(() => {
if (text !== value) setText(value);
}, [value]);
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const classes = useStyles();

View File

@@ -51,8 +51,9 @@ export const DateFormatter = (key: string, fieldType: FieldType) => (
);
};
export const onGridRowsUpdated = (props: any) => {
const { fromRowData, updated } = props;
export const onGridRowsUpdated = (event: any) => {
const { fromRowData, updated } = event;
onSubmit(Object.keys(updated)[0], fromRowData)(Object.values(updated)[0]);
};
export const onCellSelected = (args: any) => {};

View File

@@ -23,7 +23,7 @@ import { CLOUD_FUNCTIONS } from "firebase/callables";
import Typography from "@material-ui/core/Typography";
import AddIcon from "@material-ui/icons/AddCircle";
import SettingsIcon from "@material-ui/icons/Settings";
import useHotkeys from "../../hooks/useHotkeys";
import useWindowSize from "../../hooks/useWindowSize";
import { DraggableHeader } from "react-data-grid-addons";
import Confirmation from "components/Confirmation";
@@ -88,6 +88,10 @@ interface Props {
function Table(props: Props) {
const { collection, filters } = props;
const { tableState, tableActions } = useFiretable(collection);
const [selectedCell, setSelectedCell] = useState<{ row: any; column: any }>({
row: {},
column: {},
});
const [search, setSearch] = useState({
config: undefined,
collection: "",
@@ -96,6 +100,73 @@ function Table(props: Props) {
const size = useWindowSize();
useHotkeys(
"cmd+c",
() => {
handleCopy();
},
[selectedCell]
);
useHotkeys(
"ctrl+c",
() => {
handleCopy();
},
[selectedCell]
);
useHotkeys(
"cmd+v",
() => {
handlePaste();
},
[selectedCell]
);
useHotkeys(
"ctrl+v",
() => {
handlePaste();
},
[selectedCell]
);
useHotkeys(
"ctrl+x",
() => {
handleCut();
},
[selectedCell]
);
useHotkeys(
"cmd+x",
() => {
handleCut();
},
[selectedCell]
);
const handlePaste = async () => {
const { row, column } = selectedCell;
const newValue = await navigator.clipboard.readText();
onSubmit(column.key, row)(newValue);
};
const handleCopy = () => {
const { row, column } = selectedCell;
switch (column.type) {
case FieldType.number:
case FieldType.rating:
case FieldType.email:
case FieldType.simpleText:
case FieldType.PhoneNumber:
navigator.clipboard.writeText(row[column.key]);
break;
default:
break;
}
};
const handleCut = () => {
const { row, column } = selectedCell;
navigator.clipboard.writeText(row[column.key]);
onSubmit(column.key, row)(null);
};
useEffect(() => {
tableActions.table.set(collection, filters);
}, [collection, filters]);
@@ -174,7 +245,7 @@ function Table(props: Props) {
const onHeaderDrop = (dragged: any, target: any) => {
tableActions.column.reorder(dragged, target);
};
let columns = [];
let columns: any[] = [];
if (!tableState.loadingColumns) {
columns = tableState.columns.map((column: any) => ({
width: 220,
@@ -254,7 +325,14 @@ function Table(props: Props) {
onGridRowsUpdated={onGridRowsUpdated}
enableCellSelect={true}
minHeight={tableHeight}
onCellSelected={onCellSelected}
onCellSelected={(coordinates: {
rowIdx: number;
idx: number;
}) => {
const row = rows[coordinates.rowIdx];
const column = columns[coordinates.idx];
setSelectedCell({ row, column });
}}
onColumnResize={(idx, width) =>
tableActions.column.resize(idx, width)
}

18
src/hooks/useHotkeys.ts Normal file
View File

@@ -0,0 +1,18 @@
import hotkeys, { HotkeysEvent } from "hotkeys-js";
import { useCallback, useEffect } from "react";
type CallbackFn = (event: KeyboardEvent, handler: HotkeysEvent) => void;
export default function useHotkeys(
keys: string,
callback: CallbackFn,
deps: any[] = []
) {
const memoisedCallback = useCallback(callback, deps);
useEffect(() => {
hotkeys(keys, memoisedCallback);
return () => hotkeys.unbind(keys, memoisedCallback);
}, [memoisedCallback]);
}

View File

@@ -5721,6 +5721,11 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546"
integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==
hotkeys-js@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.7.2.tgz#30378b6db40bcd24fe6e51cd19c29ed1898c125f"
integrity sha512-LJIPBgejlklphThig2edlYUiPq3iFDHdsXftvZ0VWrpi330dRwD2YxPlzOYv0UQEatvZdgwG3ZLCfJ020ix8vQ==
hpack.js@^2.1.6:
version "2.1.6"
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"