Skip to content

Commit

Permalink
Trim the oversized text in the variables table and Implement variable…
Browse files Browse the repository at this point in the history
…s view (#45401)

* trim text component

* fix

* reviews
  • Loading branch information
shubhamraj-git authored Jan 5, 2025
1 parent 55c7741 commit c692b08
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const DeleteVariableButton = ({ deleteKey: variableKey }: Props) => {
<Dialog.Content backdrop>
<Dialog.Header>
<VStack align="start" gap={4}>
<Heading size="xl">Delete Variable - {variableKey} </Heading>
<Heading size="xl">Delete Variable</Heading>
</VStack>
</Dialog.Header>

Expand Down
4 changes: 4 additions & 0 deletions airflow/ui/src/pages/Variables/Variables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { Button, Tooltip } from "src/components/ui";
import { ActionBar } from "src/components/ui/ActionBar";
import { Checkbox } from "src/components/ui/Checkbox";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { TrimText } from "src/utils/TrimText";

import ImportVariablesButton from "./ImportVariablesButton";
import AddVariableButton from "./ManageVariable/AddVariableButton";
Expand Down Expand Up @@ -63,14 +64,17 @@ const getColumns = ({
},
{
accessorKey: "key",
cell: ({ row }) => <TrimText isClickable onClickContent={row.original} text={row.original.key} />,
header: "Key",
},
{
accessorKey: "value",
cell: ({ row }) => <TrimText showTooltip text={row.original.value} />,
header: "Value",
},
{
accessorKey: "description",
cell: ({ row }) => <TrimText showTooltip text={row.original.description} />,
header: "Description",
},
{
Expand Down
118 changes: 118 additions & 0 deletions airflow/ui/src/utils/TrimText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*!
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Text, Box, useDisclosure, Heading, Stack } from "@chakra-ui/react";

import { Dialog, Tooltip } from "src/components/ui";

import { capitalize } from "./capitalize";

const formatKey = (key: string): string => {
const formatted = capitalize(key).replaceAll("_", " ");

return formatted;
};

type TrimTextProps = {
readonly charLimit?: number;
readonly isClickable?: boolean;
readonly onClickContent?: Record<string, boolean | number | string | null>;
readonly showTooltip?: boolean;
readonly text: string | null;
};

export const TrimText = ({
charLimit = 50,
isClickable = false,
onClickContent,
showTooltip = false,
text,
}: TrimTextProps) => {
const safeText = text ?? "";
const isTrimmed = safeText.length > charLimit;
const trimmedText = isTrimmed ? `${safeText.slice(0, charLimit)}...` : safeText;

const { onClose, onOpen, open } = useDisclosure();

return (
<>
<Tooltip
content={showTooltip && isTrimmed ? safeText : undefined}
disabled={!isTrimmed || !showTooltip}
>
<Box
_hover={isClickable ? { textDecoration: "underline" } : undefined}
as={isClickable ? "button" : "span"}
color={isClickable ? "fg.info" : undefined}
cursor={isClickable ? "pointer" : "default"}
fontWeight={isClickable ? "bold" : undefined}
onClick={onOpen}
>
<Text>{trimmedText}</Text>
</Box>
</Tooltip>

<Dialog.Root onOpenChange={onClose} open={isClickable ? open : undefined} size="xl">
<Dialog.Content backdrop>
<Dialog.Header>
<Heading size="xl">Details</Heading>
</Dialog.Header>

<Dialog.CloseTrigger />

<Dialog.Body>
<Stack gap={4}>
{onClickContent ? (
Object.entries(onClickContent).map(([key, value]) => {
const formattedKey = formatKey(key);
const isEmpty = value === "" || value === null;

return (
<Box key={key}>
<Text fontWeight="bold" mb={2}>
{formattedKey}
</Text>
<Box
bg="gray.subtle"
borderRadius="md"
maxHeight={200}
overflow="auto"
overflowWrap="break-word"
p={4}
whiteSpace="pre-wrap"
>
<Text
color={isEmpty ? "gray.emphasized" : undefined}
fontWeight={isEmpty ? "bold" : "normal"}
>
{isEmpty ? "Empty" : String(value)}
</Text>
</Box>
</Box>
);
})
) : (
<Text>No content available.</Text>
)}
</Stack>
</Dialog.Body>
</Dialog.Content>
</Dialog.Root>
</>
);
};

0 comments on commit c692b08

Please sign in to comment.