Merge pull request #279 from bugout-dev/token-screen

Token screen
pull/295/head
Neeraj Kashyap 2021-09-25 09:00:00 -07:00 zatwierdzone przez GitHub
commit 98ab736ef4
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
2 zmienionych plików z 172 dodań i 19 usunięć

Wyświetl plik

@ -4,6 +4,8 @@ import TokenRequest from "../../src/components/TokenRequest";
import { useTokens } from "../../src/core/hooks";
import {
VStack,
Stack,
Input,
Box,
Center,
Spinner,
@ -17,12 +19,14 @@ import {
ModalHeader,
ModalBody,
ModalCloseButton,
InputGroup,
} from "@chakra-ui/react";
import { getLayout } from "../../src/layouts/AccountLayout";
const Tokens = () => {
const { onOpen, onClose, isOpen } = useDisclosure();
const [newToken, setNewToken] = useState(null);
const [filter, setFilter] = useState("");
const [tokens, setTokens] = useState();
const { list, updateMutation, revoke, isLoading, data } = useTokens();
@ -50,6 +54,7 @@ const Tokens = () => {
document.title = `Tokens`;
}, []);
const handleChange = (event) => setFilter(event.target.value);
return (
<Box>
{isLoading && !tokens ? (
@ -77,17 +82,36 @@ const Tokens = () => {
</Modal>
<Heading variant="tokensScreen"> My API tokens </Heading>
<VStack overflow="initial" maxH="unset" height="100%" maxW="100%">
<Button
alignSelf="flex-end"
onClick={onOpen}
colorScheme="orange"
variant="solid"
size="sm"
>
Add new token
</Button>
<Stack direction={["column", "row", null]} w="100%">
<InputGroup size="sm" variant="outline">
<Input
type="search"
maxW="300px"
flexBasis="50px"
flexGrow={1}
display="flex"
minW="150px"
w="unset"
borderRadius="md"
placeholder="Type here to filter by label name"
value={filter}
onChange={handleChange}
/>
</InputGroup>
<Button
alignSelf="flex-end"
onClick={onOpen}
colorScheme="orange"
variant="solid"
px="2rem"
size="sm"
>
Add new token
</Button>
</Stack>
<TokensList
data={tokens}
filter={filter}
revoke={revoke}
isLoading={isLoading}
update={updateMutation}

Wyświetl plik

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect, useState, useMemo } from "react";
import { Skeleton, IconButton } from "@chakra-ui/react";
import {
Table,
@ -9,19 +9,77 @@ import {
Tbody,
Editable,
EditableInput,
Button,
EditablePreview,
useBreakpointValue,
} from "@chakra-ui/react";
import { DeleteIcon } from "@chakra-ui/icons";
import { DeleteIcon, TriangleDownIcon } from "@chakra-ui/icons";
import moment from "moment";
import CopyButton from "./CopyButton";
const List = ({ data, revoke, isLoading, update }) => {
const SORT_BY_TYPES = {
DATE: 0,
LABEL: 1,
};
const SORT_DIRECTION_TYPES = {
ASC: true,
DESC: false,
};
const List = ({ data, revoke, isLoading, update, filter }) => {
const [stateData, setStateData] = useState(data);
const userToken = localStorage.getItem("MOONSTREAM_ACCESS_TOKEN");
const [sortBy, setSortBy] = useState({
column: SORT_BY_TYPES.LABEL,
direction: SORT_DIRECTION_TYPES.ASC,
});
const buttonSize = useBreakpointValue({
base: "xs",
sm: "sm",
md: "sm",
lg: "sm",
xl: "sm",
"2xl": "sm",
});
const sortedTokens = useMemo(() => {
return data?.token?.sort(function (a, b) {
var aName = a?.note?.toUpperCase();
var bName = b?.note?.toUpperCase();
if ((a.note || b.note) && sortBy.column === SORT_BY_TYPES.LABEL) {
if (!b.note) return -1;
if (sortBy.direction === SORT_DIRECTION_TYPES.ASC) {
return aName < bName ? -1 : aName > bName ? 1 : 0;
} else {
return aName > bName ? -1 : aName < bName ? 1 : 0;
}
} else {
if (sortBy.direction === SORT_DIRECTION_TYPES.ASC) {
return new Date(b.created_at) - new Date(a.created_at);
} else {
return new Date(a.created_at) - new Date(b.created_at);
}
}
});
}, [sortBy, data]);
useEffect(() => {
if (data?.token?.length > 0) {
const filteredTokens = sortedTokens.filter((item) => {
if (filter === null || filter === undefined || filter === "") {
return true;
} else return item.note.includes(filter);
});
setStateData({ ...data, token: [...filteredTokens] });
}
}, [data, sortBy, filter, sortedTokens]);
const cellProps = {
px: ["2px", "6px", "inherit"],
};
if (data) {
if (stateData) {
return (
<Table
variant="simple"
@ -33,14 +91,86 @@ const List = ({ data, revoke, isLoading, update }) => {
>
<Thead>
<Tr>
<Th>Label</Th>
<Th {...cellProps}>Token</Th>
<Th {...cellProps}>Date Created</Th>
<Th {...cellProps}>Actions</Th>
<Th>
<Button
variant="link"
my={0}
mx={0}
size={buttonSize}
colorScheme={
sortBy.column !== SORT_BY_TYPES.LABEL ? "blue" : "orange"
}
onClick={() =>
setSortBy({
column: SORT_BY_TYPES.LABEL,
direction:
sortBy.column !== SORT_BY_TYPES.LABEL
? SORT_DIRECTION_TYPES.ASC
: !sortBy.direction,
})
}
rightIcon={
<TriangleDownIcon
color={
sortBy.column !== SORT_BY_TYPES.LABEL && "transparent"
}
boxSize="12px"
transform={
sortBy.direction === SORT_DIRECTION_TYPES.ASC
? "rotate(0deg)"
: "rotate(180deg)"
}
/>
}
>
Label
</Button>
</Th>
<Th {...cellProps} fontSize={["xx-small", "xs", null]}>
Token
</Th>
<Th {...cellProps} fontSize={["xx-small", "xs", null]}>
<Button
mx={0}
variant="link"
my={0}
size={buttonSize}
colorScheme={
sortBy.column !== SORT_BY_TYPES.DATE ? "blue" : "orange"
}
onClick={() =>
setSortBy({
column: SORT_BY_TYPES.DATE,
direction:
sortBy.column !== SORT_BY_TYPES.DATE
? SORT_DIRECTION_TYPES.ASC
: !sortBy.direction,
})
}
rightIcon={
<TriangleDownIcon
color={
sortBy.column !== SORT_BY_TYPES.DATE && "transparent"
}
boxSize="12px"
transform={
sortBy.direction === SORT_DIRECTION_TYPES.ASC
? "rotate(0deg)"
: "rotate(180deg)"
}
/>
}
>
{`Date Created`}
</Button>
</Th>
<Th {...cellProps} fontSize={["xx-small", "xs", null]}>
Actions
</Th>
</Tr>
</Thead>
<Tbody>
{data.token.map((token) => {
{stateData.token?.map((token) => {
if (token.active) {
if (userToken !== token.id) {
return (
@ -50,7 +180,6 @@ const List = ({ data, revoke, isLoading, update }) => {
colorScheme="blue"
placeholder="Click to set up label"
defaultValue={token.note}
isDisabled={update.isLoading}
onSubmit={(nextValue) =>
update.mutate({ token: token.id, note: nextValue })
}