diff --git a/web/packages/design/src/DataTable/Table.tsx b/web/packages/design/src/DataTable/Table.tsx index 8f3b9bc8bcaa5..d028e1b18a844 100644 --- a/web/packages/design/src/DataTable/Table.tsx +++ b/web/packages/design/src/DataTable/Table.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import React, { ReactNode } from 'react'; +import React, { ReactNode, PropsWithChildren } from 'react'; import { Box, Flex, Indicator, P1, Text } from 'design'; import * as Icons from 'design/Icon'; @@ -108,6 +108,22 @@ export default function Table(props: TableProps) { return ; } data.map((item, rowIdx) => { + const TableRow: React.FC = ({ children }) => ( + row?.onClick?.(item)} + style={row?.getStyle?.(item)} + > + {children} + + ); + + const customRow = row?.customRow?.(item); + if (customRow) { + rows.push({customRow}); + return; + } + const cells = columns.flatMap((column, columnIdx) => { if (column.isNonRender) { return []; // does not include this column. @@ -125,15 +141,7 @@ export default function Table(props: TableProps) { ); }); - rows.push( - row?.onClick?.(item)} - style={row?.getStyle?.(item)} - > - {cells} - - ); + rows.push({cells}); }); if (rows.length) { diff --git a/web/packages/design/src/DataTable/types.ts b/web/packages/design/src/DataTable/types.ts index afe803116613a..9f5ec0490653c 100644 --- a/web/packages/design/src/DataTable/types.ts +++ b/web/packages/design/src/DataTable/types.ts @@ -79,6 +79,14 @@ export type TableProps = { * conditionally style a row (eg: cursor: pointer, disabled) */ getStyle?(row: T): React.CSSProperties; + /** + * conditionally render a custom row + * use case: by default all columns are represented by cells + * but certain rows you need all the columns to be merged + * into one cell to render other related elements like a + * dropdown selector. + */ + customRow?(row: T): JSX.Element; }; }; diff --git a/web/packages/design/src/Link/Link.jsx b/web/packages/design/src/Link/Link.jsx index 957be80a5f7be..260c31f85094b 100644 --- a/web/packages/design/src/Link/Link.jsx +++ b/web/packages/design/src/Link/Link.jsx @@ -31,7 +31,6 @@ const StyledButtonLink = styled.a.attrs({ rel: 'noreferrer', })` color: ${({ theme }) => theme.colors.buttons.link.default}; - font-weight: normal; background: none; text-decoration: underline; text-transform: none; diff --git a/web/packages/shared/components/AccessRequests/NewRequest/CheckableOption.tsx b/web/packages/shared/components/AccessRequests/NewRequest/CheckableOption.tsx new file mode 100644 index 0000000000000..f10b940050628 --- /dev/null +++ b/web/packages/shared/components/AccessRequests/NewRequest/CheckableOption.tsx @@ -0,0 +1,48 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React from 'react'; +import { Flex, Text } from 'design'; +import { components, OptionProps } from 'react-select'; + +import { Option as BaseOption } from 'shared/components/Select'; + +export type Option = BaseOption & { + isAdded?: boolean; + kind: 'app' | 'user_group' | 'namespace'; +}; + +export const CheckableOptionComponent = ( + props: OptionProps