mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-31 11:49:10 +01:00
Icon and banner to show workflow
This commit is contained in:
2
gradle/changelog/icon_for_status.yaml
Normal file
2
gradle/changelog/icon_for_status.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: added
|
||||
description: Icon for displaying a status like success
|
||||
@@ -29,6 +29,7 @@ export const ButtonVariants = {
|
||||
SECONDARY: "secondary",
|
||||
TERTIARY: "tertiary",
|
||||
SIGNAL: "signal",
|
||||
DANGER: "danger",
|
||||
INFO: "info",
|
||||
} as const;
|
||||
|
||||
@@ -43,6 +44,7 @@ const createButtonClasses = (variant?: ButtonVariant, isLoading?: boolean) =>
|
||||
"is-primary is-inverted": variant === "tertiary",
|
||||
"is-warning": variant === "signal",
|
||||
"is-info is-outlined": variant === "info",
|
||||
"is-danger": variant === "danger",
|
||||
"is-loading": isLoading,
|
||||
});
|
||||
|
||||
|
||||
63
scm-ui/ui-core/src/base/status/StatusIcon.stories.tsx
Normal file
63
scm-ui/ui-core/src/base/status/StatusIcon.stories.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
import React, { ComponentProps } from "react";
|
||||
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { StoryFn } from "@storybook/react";
|
||||
import { StatusIcon } from "./index";
|
||||
import { StatusIconSizeVariantList, StatusVariantList, StatusVariants } from "./StatusIcon";
|
||||
|
||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||
export default {
|
||||
title: "Status",
|
||||
component: null,
|
||||
subcomponents: {
|
||||
Button: StatusIcon,
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
options: StatusVariantList,
|
||||
control: { type: "select" },
|
||||
},
|
||||
iconSize: {
|
||||
options: StatusIconSizeVariantList,
|
||||
control: { type: "select" },
|
||||
},
|
||||
},
|
||||
decorators: [StoryRouter()],
|
||||
parameters: {
|
||||
storyshots: { disable: true },
|
||||
},
|
||||
};
|
||||
|
||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
||||
const StatusIconTemplate: StoryFn<ComponentProps<typeof StatusIcon>> = (args) => <StatusIcon {...args} />;
|
||||
|
||||
export const Icon = StatusIconTemplate.bind({});
|
||||
Icon.args = {
|
||||
variant: StatusVariants.SUCCESS,
|
||||
invert: false,
|
||||
iconSize: "lg",
|
||||
};
|
||||
|
||||
export const IconWithTitle = StatusIconTemplate.bind({});
|
||||
IconWithTitle.args = {
|
||||
variant: StatusVariants.SUCCESS,
|
||||
invert: false,
|
||||
iconSize: "lg",
|
||||
children: "Lorem Ipsum",
|
||||
};
|
||||
133
scm-ui/ui-core/src/base/status/StatusIcon.tsx
Normal file
133
scm-ui/ui-core/src/base/status/StatusIcon.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
import { Icon } from "../buttons";
|
||||
|
||||
export const StatusVariants = {
|
||||
IN_PROGRESS: "in progress",
|
||||
SUCCESS: "success",
|
||||
WARNING: "warning",
|
||||
DANGER: "danger",
|
||||
UNDEFINED: "undefined",
|
||||
};
|
||||
|
||||
export const StatusVariantList = Object.values(StatusVariants);
|
||||
|
||||
export type StatusVariant = typeof StatusVariants[keyof typeof StatusVariants];
|
||||
|
||||
export const StatusIconSizeVariants = {
|
||||
SMALL: "xs",
|
||||
MEDIUM: "lg",
|
||||
LARGE: "2x",
|
||||
};
|
||||
|
||||
export const StatusIconSizeVariantList = Object.values(StatusIconSizeVariants);
|
||||
|
||||
export type StatusIconSizeVariant = typeof StatusIconSizeVariants[keyof typeof StatusIconSizeVariants];
|
||||
|
||||
type IconProps = React.HTMLProps<HTMLElement> & {
|
||||
variant: StatusVariant;
|
||||
color?: string;
|
||||
iconSize?: StatusIconSizeVariant;
|
||||
invert?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @beta
|
||||
* @since 3.9.0
|
||||
*/
|
||||
const StatusIcon = React.forwardRef<HTMLElement, IconProps>(
|
||||
({ color, className, iconSize = StatusIconSizeVariants.MEDIUM, variant, invert = false, children }, ref) => {
|
||||
const icon = classNames({
|
||||
"exclamation-triangle": variant === StatusVariants.DANGER,
|
||||
"check-circle": variant === StatusVariants.SUCCESS,
|
||||
"hourglass-start": variant === StatusVariants.IN_PROGRESS,
|
||||
"circle-notch": variant === StatusVariants.UNDEFINED,
|
||||
});
|
||||
if (!color) {
|
||||
if (invert) {
|
||||
color = classNames({
|
||||
"icon-color-inverted": variant === StatusVariants.DANGER || StatusVariants.SUCCESS,
|
||||
"icon-warning-inverted": variant === StatusVariants.WARNING,
|
||||
"icon-color-inverted-secondary":
|
||||
variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
|
||||
});
|
||||
} else {
|
||||
color = classNames({
|
||||
"has-text-danger": variant === StatusVariants.DANGER,
|
||||
"has-text-success": variant === StatusVariants.SUCCESS,
|
||||
"has-text-warning": variant === StatusVariants.WARNING,
|
||||
"icon-color-secondary": variant === StatusVariants.IN_PROGRESS || variant === StatusVariants.UNDEFINED,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="is-flex is-align-items-center">
|
||||
{variant === "warning" ? (
|
||||
<WarningIcon color={color} iconSize={iconSize} className={className}>{`${icon}`}</WarningIcon>
|
||||
) : (
|
||||
<Icon className={className}>{`${icon} ${color} fa-${iconSize}`}</Icon>
|
||||
)}
|
||||
{children && <span className="ml-2">{children}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
type WarningIconProps = React.HTMLProps<HTMLElement> & {
|
||||
color?: string;
|
||||
iconSize?: string;
|
||||
};
|
||||
|
||||
const WarningIcon = React.forwardRef<HTMLElement, WarningIconProps>(({ color, className, iconSize }, ref) => {
|
||||
return (
|
||||
<span className={classNames(className, "icon", color)} aria-hidden="true" ref={ref}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="Ebene_1"
|
||||
data-name="Ebene 1"
|
||||
height="1em"
|
||||
width="1em"
|
||||
viewBox="0 0 140 140"
|
||||
fill="currentColor"
|
||||
className={classNames("fas fa-fw fa-custom-icon", `fa-${iconSize}`)}
|
||||
>
|
||||
<defs>
|
||||
<mask id="cutoutMask">
|
||||
<rect x="0" y="0" width="140" height="140" fill="white" />
|
||||
<path
|
||||
className="cls-2"
|
||||
d="M79.93,109.67c-2.75,2.75-6.06,4.13-9.93,4.13s-7.18-1.38-9.93-4.13-4.13-6.06-4.13-9.93,1.38-7.18,4.13-9.93,6.06-4.13,9.93-4.13,7.18,1.38,9.93,4.13,4.13,6.06,4.13,9.93-1.38,7.18-4.13,9.93ZM59.98,76.01c0,1.17.41,2.14,1.23,2.9s1.82,1.14,2.99,1.14h11.6c1.17,0,2.17-.38,2.99-1.14s1.23-1.73,1.23-2.9l2.46-47.81c0-1.17-.41-2.2-1.23-3.08s-1.82-1.32-2.99-1.32h-16.52c-1.17,0-2.17.44-2.99,1.32s-1.23,1.9-1.23,3.08l2.46,47.81Z"
|
||||
fill="black"
|
||||
/>
|
||||
</mask>
|
||||
</defs>
|
||||
<path
|
||||
className="cls-1"
|
||||
d="M125,0c4.17,0,7.71,1.46,10.62,4.38s4.38,6.46,4.38,10.62v110c0,4.17-1.46,7.71-4.38,10.63-2.92,2.92-6.46,4.38-10.62,4.38H15c-4.17,0-7.71-1.46-10.62-4.38-2.92-2.92-4.38-6.46-4.38-10.63V15c0-4.17,1.46-7.71,4.38-10.62S10.83,0,15,0h110Z"
|
||||
mask="url(#cutoutMask)"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
});
|
||||
|
||||
export default StatusIcon;
|
||||
17
scm-ui/ui-core/src/base/status/index.ts
Normal file
17
scm-ui/ui-core/src/base/status/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2020 - present Cloudogu GmbH
|
||||
*
|
||||
* 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, version 3.
|
||||
*
|
||||
* 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 https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
export { default as StatusIcon, StatusVariant, StatusIconSizeVariant } from "./StatusIcon";
|
||||
@@ -314,3 +314,21 @@ input[type="date"].input::-webkit-calendar-picker-indicator {
|
||||
.popover-close:focus {
|
||||
background: $grey-darker !important;
|
||||
}
|
||||
|
||||
.icon-color-inverted {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.icon-color-inverted-secondary {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.icon-warning-inverted {
|
||||
color: #583708;
|
||||
}
|
||||
|
||||
.icon-color-secondary {
|
||||
color: $grey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -337,3 +337,19 @@ input[type="date"].input::-webkit-calendar-picker-indicator {
|
||||
.popover-close:focus {
|
||||
background: $grey-light !important;
|
||||
}
|
||||
|
||||
.icon-color-inverted {
|
||||
color: $scheme-main;
|
||||
}
|
||||
|
||||
.icon-color-inverted-secondary {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.icon-warning-inverted {
|
||||
color: $scheme-main;
|
||||
}
|
||||
|
||||
.icon-color-secondary {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
@@ -90,3 +90,19 @@ footer.footer {
|
||||
.has-hover-visible:hover {
|
||||
color: $grey-darker !important;
|
||||
}
|
||||
|
||||
.icon-color-inverted {
|
||||
color: $scheme-main;
|
||||
}
|
||||
|
||||
.icon-color-inverted-secondary {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.icon-warning-inverted {
|
||||
color: $scheme-main;
|
||||
}
|
||||
|
||||
.icon-color-secondary {
|
||||
color: $dark;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user