Remove card-table action area (#2016)

In .card-tables there was an action area that had a darker background. Now this area only contains the delete action. Also, users mistakenly assumed that the hovered area could be clicked. It has therefore been removed and the icons themselves have received a hover effect.
This commit is contained in:
Florian Scholdei
2022-05-06 10:01:01 +02:00
committed by GitHub
parent 6cf8afac01
commit 4c94235414
11 changed files with 68 additions and 53 deletions

View File

@@ -0,0 +1,2 @@
- type: fixed
description: Remove card-table action area ([#2016](https://github.com/scm-manager/scm-manager/pull/2016))

View File

@@ -4205,7 +4205,7 @@ exports[`Storyshots GroupEntry Default 1`] = `
type="button" type="button"
> >
<i <i
className="fas fa-fw fa-download has-text-inherit is-medium pr-5" className="fas fa-fw fa-download has-text-inherit is-medium"
onKeyPress={[Function]} onKeyPress={[Function]}
/> />
@@ -4279,7 +4279,7 @@ exports[`Storyshots GroupEntry With long texts 1`] = `
type="button" type="button"
> >
<i <i
className="fas fa-fw fa-download has-text-inherit is-medium pr-5" className="fas fa-fw fa-download has-text-inherit is-medium"
onKeyPress={[Function]} onKeyPress={[Function]}
/> />

View File

@@ -70,7 +70,13 @@ const Button: FC<InnerProps> = ({
innerRef innerRef
}) => { }) => {
const renderIcon = () => { const renderIcon = () => {
return <>{icon ? <Icon name={icon} color="inherit" className="is-medium pr-5" /> : null}</>; return (
<>
{icon ? (
<Icon name={icon} color="inherit" className={classNames("is-medium", { "pr-5": label || children })} />
) : null}
</>
);
}; };
const classes = classNames( const classes = classNames(

View File

@@ -633,6 +633,7 @@ ul.is-separated {
&:first-child { &:first-child {
border-left: 3px solid; border-left: 3px solid;
} }
// Deprecated
&.is-darker { &.is-darker {
background-color: $white-ter; background-color: $white-ter;
} }
@@ -902,6 +903,10 @@ form .field:not(.is-grouped) {
border-bottom-right-radius: unset; border-bottom-right-radius: unset;
} }
.is-vertical-align-middle {
vertical-align: middle !important
}
// radio // radio
//overwrite bulma's default margin //overwrite bulma's default margin
.radio + .radio { .radio + .radio {

View File

@@ -31,7 +31,7 @@ import {
useClearNotifications, useClearNotifications,
useDismissNotification, useDismissNotification,
useNotifications, useNotifications,
useNotificationSubscription useNotificationSubscription,
} from "@scm-manager/ui-api"; } from "@scm-manager/ui-api";
import { Notification, NotificationCollection } from "@scm-manager/ui-types"; import { Notification, NotificationCollection } from "@scm-manager/ui-types";
import { import {
@@ -42,7 +42,7 @@ import {
Notification as InfoNotification, Notification as InfoNotification,
ToastArea, ToastArea,
ToastNotification, ToastNotification,
ToastType ToastType,
} from "@scm-manager/ui-components"; } from "@scm-manager/ui-components";
import HeaderDropDown, { Column, OnlyMobileWrappingColumn, Table } from "../components/HeaderDropDown"; import HeaderDropDown, { Column, OnlyMobileWrappingColumn, Table } from "../components/HeaderDropDown";
@@ -77,11 +77,11 @@ const NotificationEntry: FC<EntryProps> = ({ notification, removeToast }) => {
<OnlyMobileWrappingColumn className="has-text-right"> <OnlyMobileWrappingColumn className="has-text-right">
<DateFromNow date={notification.createdAt} /> <DateFromNow date={notification.createdAt} />
</OnlyMobileWrappingColumn> </OnlyMobileWrappingColumn>
<DismissColumn className="is-darker is-clickable" onClick={remove}> <DismissColumn>
{isLoading ? ( {isLoading ? (
<div className="small-loading-spinner" aria-label={t("notifications.loading")} /> <div className="small-loading-spinner" aria-label={t("notifications.loading")} />
) : ( ) : (
<Icon name="trash" color="secondary-most" title={t("notifications.dismiss")} /> <Button color="text" icon="trash" action={remove} title={t("notifications.dismiss")} className="px-1" />
)} )}
</DismissColumn> </DismissColumn>
</tr> </tr>

View File

@@ -27,7 +27,7 @@ import { useTranslation } from "react-i18next";
import classNames from "classnames"; import classNames from "classnames";
import styled from "styled-components"; import styled from "styled-components";
import { Branch, BranchDetails, Link, Repository } from "@scm-manager/ui-types"; import { Branch, BranchDetails, Link, Repository } from "@scm-manager/ui-types";
import { devices, Icon, SmallLoadingSpinner } from "@scm-manager/ui-components"; import { Button, devices, SmallLoadingSpinner } from "@scm-manager/ui-components";
import { binder } from "@scm-manager/ui-extensions"; import { binder } from "@scm-manager/ui-extensions";
import DefaultBranchTag from "./DefaultBranchTag"; import DefaultBranchTag from "./DefaultBranchTag";
import AheadBehindTag from "./AheadBehindTag"; import AheadBehindTag from "./AheadBehindTag";
@@ -68,14 +68,13 @@ const BranchRow: FC<Props> = ({ repository, baseUrl, branch, onDelete, details }
let deleteButton; let deleteButton;
if ((branch?._links?.delete as Link)?.href) { if ((branch?._links?.delete as Link)?.href) {
deleteButton = ( deleteButton = (
<span <Button
className="icon is-small is-hovered is-clickable" color="text"
onClick={() => onDelete(branch)} icon="trash"
onKeyDown={e => e.key === "Enter" && onDelete(branch)} action={() => onDelete(branch)}
tabIndex={0} title={t("branch.delete.button")}
> className="px-2"
<Icon name="trash" title={t("branch.delete.button")} /> />
</span>
); );
} }
@@ -92,7 +91,7 @@ const BranchRow: FC<Props> = ({ repository, baseUrl, branch, onDelete, details }
const extensionProps = { repository, branch, details }; const extensionProps = { repository, branch, details };
return ( return (
<AdaptTableFlow> <AdaptTableFlow>
<td> <td className="is-vertical-align-middle">
<ReactLink to={to} title={branch.name}> <ReactLink to={to} title={branch.name}>
{branch.name} {branch.name}
</ReactLink> </ReactLink>
@@ -102,11 +101,13 @@ const BranchRow: FC<Props> = ({ repository, baseUrl, branch, onDelete, details }
</MobileFlowSpan> </MobileFlowSpan>
)} )}
</td> </td>
<td className="has-text-centered">{renderBranchTag()}</td> <td className="is-vertical-align-middle has-text-centered">{renderBranchTag()}</td>
{binder.hasExtension("repos.branches.row.details") {binder.hasExtension("repos.branches.row.details")
? binder.getExtensions("repos.branches.row.details").map(e => <td>{React.createElement(e, extensionProps)}</td>) ? binder
.getExtensions("repos.branches.row.details")
.map((e) => <td>{React.createElement(e, extensionProps)}</td>)
: null} : null}
<td className="is-darker has-text-centered">{deleteButton}</td> <td className="is-vertical-align-middle has-text-centered">{deleteButton}</td>
</AdaptTableFlow> </AdaptTableFlow>
); );
}; };

View File

@@ -24,7 +24,7 @@
import React, { FC, useEffect, useState } from "react"; import React, { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Namespace, Permission, Repository } from "@scm-manager/ui-types"; import { Namespace, Permission, Repository } from "@scm-manager/ui-types";
import { ConfirmAlert, ErrorNotification, Icon } from "@scm-manager/ui-components"; import { Button, ConfirmAlert, ErrorNotification } from "@scm-manager/ui-components";
import { useDeletePermission } from "@scm-manager/ui-api"; import { useDeletePermission } from "@scm-manager/ui-api";
type Props = { type Props = {
@@ -63,13 +63,13 @@ const DeletePermissionButton: FC<Props> = ({ namespaceOrRepository, permission,
className: "is-outlined", className: "is-outlined",
label: t("permission.delete-permission-button.confirm-alert.submit"), label: t("permission.delete-permission-button.confirm-alert.submit"),
isLoading, isLoading,
onClick: () => deletePermission() onClick: () => deletePermission(),
}, },
{ {
label: t("permission.delete-permission-button.confirm-alert.cancel"), label: t("permission.delete-permission-button.confirm-alert.cancel"),
onClick: () => null, onClick: () => null,
autofocus: true autofocus: true,
} },
]} ]}
close={() => setShowConfirmAlert(false)} close={() => setShowConfirmAlert(false)}
/> />
@@ -79,12 +79,12 @@ const DeletePermissionButton: FC<Props> = ({ namespaceOrRepository, permission,
return ( return (
<> <>
<ErrorNotification error={error} /> <ErrorNotification error={error} />
<Icon <Button
name="trash" color="text"
onClick={action} icon="trash"
onEnter={action} action={action}
tabIndex={0}
title={t("permission.delete-permission-button.label")} title={t("permission.delete-permission-button.label")}
className="px-2"
/> />
</> </>
); );

View File

@@ -118,7 +118,7 @@ const SinglePermission: FC<Props> = ({
<VCenteredTd> <VCenteredTd>
<Button label={t("permission.advanced-button.label")} action={() => setShowAdvancedDialog(true)} /> <Button label={t("permission.advanced-button.label")} action={() => setShowAdvancedDialog(true)} />
</VCenteredTd> </VCenteredTd>
<VCenteredTd className="is-darker has-text-centered"> <VCenteredTd className="has-text-centered">
{permission._links.delete ? ( {permission._links.delete ? (
<DeletePermissionButton permission={permission} namespaceOrRepository={namespaceOrRepository} /> <DeletePermissionButton permission={permission} namespaceOrRepository={namespaceOrRepository} />
) : null} ) : null}

View File

@@ -26,7 +26,7 @@ import { Link as RouterLink } from "react-router-dom";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import classNames from "classnames"; import classNames from "classnames";
import { Tag, Link } from "@scm-manager/ui-types"; import { Tag, Link } from "@scm-manager/ui-types";
import { DateFromNow, Icon } from "@scm-manager/ui-components"; import { Button, DateFromNow } from "@scm-manager/ui-components";
type Props = { type Props = {
tag: Tag; tag: Tag;
@@ -41,21 +41,14 @@ const TagRow: FC<Props> = ({ tag, baseUrl, onDelete }) => {
let deleteButton; let deleteButton;
if ((tag?._links?.delete as Link)?.href) { if ((tag?._links?.delete as Link)?.href) {
deleteButton = ( deleteButton = (
<span <Button color="text" icon="trash" action={() => onDelete(tag)} title={t("tag.delete.button")} className="px-2" />
className="icon is-small is-clickable"
onClick={() => onDelete(tag)}
onKeyDown={e => e.key === "Enter" && onDelete(tag)}
tabIndex={0}
>
<Icon name="trash" className="fas" title={t("tag.delete.button")} />
</span>
); );
} }
const to = `${baseUrl}/${encodeURIComponent(tag.name)}/info`; const to = `${baseUrl}/${encodeURIComponent(tag.name)}/info`;
return ( return (
<tr> <tr>
<td> <td className="is-vertical-align-middle">
<RouterLink to={to} title={tag.name}> <RouterLink to={to} title={tag.name}>
{tag.name} {tag.name}
<span className={classNames("has-text-secondary", "is-ellipsis-overflow", "ml-2", "is-size-7")}> <span className={classNames("has-text-secondary", "is-ellipsis-overflow", "ml-2", "is-size-7")}>
@@ -63,7 +56,7 @@ const TagRow: FC<Props> = ({ tag, baseUrl, onDelete }) => {
</span> </span>
</RouterLink> </RouterLink>
</td> </td>
<td className="is-darker has-text-centered">{deleteButton}</td> <td className="is-vertical-align-middle has-text-centered">{deleteButton}</td>
</tr> </tr>
); );
}; };

View File

@@ -23,7 +23,7 @@
*/ */
import React, { FC } from "react"; import React, { FC } from "react";
import { DateFromNow, Icon } from "@scm-manager/ui-components"; import { Button, DateFromNow } from "@scm-manager/ui-components";
import { ApiKey } from "@scm-manager/ui-types"; import { ApiKey } from "@scm-manager/ui-types";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { DeleteFunction } from "@scm-manager/ui-api"; import { DeleteFunction } from "@scm-manager/ui-api";
@@ -37,18 +37,20 @@ export const ApiKeyEntry: FC<Props> = ({ apiKey, onDelete }) => {
const [t] = useTranslation("users"); const [t] = useTranslation("users");
let deleteButton; let deleteButton;
if (apiKey?._links?.delete) { if (apiKey?._links?.delete) {
deleteButton = <Icon name="trash" title={t("apiKey.delete")} color="inherit" onClick={() => onDelete(apiKey)} />; deleteButton = (
<Button color="text" icon="trash" action={() => onDelete(apiKey)} title={t("apiKey.delete")} className="px-2" />
);
} }
return ( return (
<> <>
<tr> <tr>
<td>{apiKey.displayName}</td> <td className="is-vertical-align-middle">{apiKey.displayName}</td>
<td>{apiKey.permissionRole}</td> <td className="is-vertical-align-middle">{apiKey.permissionRole}</td>
<td className="is-hidden-mobile"> <td className="is-vertical-align-middle is-hidden-mobile">
<DateFromNow date={apiKey.created} /> <DateFromNow date={apiKey.created} />
</td> </td>
<td className="is-darker has-text-centered">{deleteButton}</td> <td className="is-vertical-align-middle has-text-centered">{deleteButton}</td>
</tr> </tr>
</> </>
); );

View File

@@ -23,7 +23,7 @@
*/ */
import React, { FC } from "react"; import React, { FC } from "react";
import { DateFromNow, Icon } from "@scm-manager/ui-components"; import { Button, DateFromNow } from "@scm-manager/ui-components";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Link, PublicKey } from "@scm-manager/ui-types"; import { Link, PublicKey } from "@scm-manager/ui-types";
import { DeleteFunction } from "@scm-manager/ui-api"; import { DeleteFunction } from "@scm-manager/ui-api";
@@ -39,18 +39,24 @@ export const PublicKeyEntry: FC<Props> = ({ publicKey, onDelete }) => {
let deleteButton; let deleteButton;
if (publicKey?._links?.delete) { if (publicKey?._links?.delete) {
deleteButton = ( deleteButton = (
<Icon name="trash" title={t("publicKey.delete")} color="inherit" onClick={() => onDelete(publicKey)} /> <Button
color="text"
icon="trash"
action={() => onDelete(publicKey)}
title={t("publicKey.delete")}
className="px-2"
/>
); );
} }
return ( return (
<> <>
<tr> <tr>
<td>{publicKey.displayName}</td> <td className="is-vertical-align-middle">{publicKey.displayName}</td>
<td className="is-hidden-mobile"> <td className="is-vertical-align-middle is-hidden-mobile">
<DateFromNow date={publicKey.created} /> <DateFromNow date={publicKey.created} />
</td> </td>
<td className="is-hidden-mobile"> <td className="is-vertical-align-middle is-hidden-mobile">
{publicKey._links?.raw ? ( {publicKey._links?.raw ? (
<a title={t("publicKey.download")} href={(publicKey._links.raw as Link).href}> <a title={t("publicKey.download")} href={(publicKey._links.raw as Link).href}>
{publicKey.id} {publicKey.id}
@@ -59,7 +65,7 @@ export const PublicKeyEntry: FC<Props> = ({ publicKey, onDelete }) => {
publicKey.id publicKey.id
)} )}
</td> </td>
<td className="is-darker has-text-centered">{deleteButton}</td> <td className="is-vertical-align-middle has-text-centered">{deleteButton}</td>
</tr> </tr>
</> </>
); );