mirror of https://github.com/portainer/portainer
fix(helm): helm charts view bad icon aspect ratio EE-4451 (#7875)
parent
1100a2bd28
commit
368e6b2a44
|
@ -102,6 +102,9 @@ pr-icon {
|
|||
}
|
||||
|
||||
.icon-nested-blue {
|
||||
@apply bg-blue-3 text-blue-8;
|
||||
@apply th-dark:bg-gray-9 th-dark:text-blue-3;
|
||||
@apply th-highcontrast:bg-gray-9 th-highcontrast:text-blue-3;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -110,7 +113,6 @@ pr-icon {
|
|||
padding: 5px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background-color: var(--ui-blue-3);
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,22 +2,9 @@
|
|||
<div ng-class="{ 'blocklist-item--selected': $ctrl.model.Selected }" class="blocklist-item template-item mx-[10px]" ng-click="$ctrl.onSelect($ctrl.model)">
|
||||
<div class="blocklist-item-box">
|
||||
<!-- helmchart-image -->
|
||||
<span ng-if="$ctrl.model.icon">
|
||||
<fallback-image
|
||||
src="$ctrl.model.icon"
|
||||
fallback-icon="'svg-helm'"
|
||||
class-name="'blocklist-item-logo h-16 w-auto'"
|
||||
fallback-class-name="'icon-nested-blue !h-12 !w-12 [&>*]:!h-8 [&>*]:!w-auto'"
|
||||
fallback-mode="'primary'"
|
||||
size="'xl'"
|
||||
></fallback-image>
|
||||
<span class="shrink-0">
|
||||
<fallback-image src="$ctrl.model.icon" fallback-icon="'svg-helm'" class-name="'blocklist-item-logo h-16 w-auto'" size="'3xl'"></fallback-image>
|
||||
</span>
|
||||
|
||||
<div class="widget-icon space-right" ng-if="!$ctrl.model.icon">
|
||||
<pr-icon icon="'svg-helm'"></pr-icon>
|
||||
</div>
|
||||
|
||||
<!-- !helmchart-image -->
|
||||
<!-- helmchart-details -->
|
||||
<div class="col-sm-12 helm-template-item-details">
|
||||
<!-- blocklist-item-line1 -->
|
||||
|
|
|
@ -24,13 +24,7 @@
|
|||
<div class="col-sm-12" ng-if="$ctrl.state.chart">
|
||||
<rd-widget>
|
||||
<div class="toolBarTitle vertical-center pt-5 px-5 text-muted">
|
||||
<fallback-image
|
||||
src="$ctrl.state.chart.icon"
|
||||
fallback-icon="'svg-helm'"
|
||||
class-name="'h-8 w-8'"
|
||||
fallback-class-name="'icon-nested-blue'"
|
||||
fallback-mode="'primary'"
|
||||
></fallback-image>
|
||||
<fallback-image src="$ctrl.state.chart.icon" fallback-icon="'svg-helm'" class-name="'h-8 w-8'" size="'lg'"></fallback-image>
|
||||
{{ $ctrl.state.chart.name }}
|
||||
</div>
|
||||
<rd-widget-body classes="padding">
|
||||
|
|
|
@ -3,13 +3,7 @@
|
|||
<div class="blocklist-item-box">
|
||||
<!-- template-image -->
|
||||
<div class="vertical-center justify-center min-w-[56px]">
|
||||
<fallback-image
|
||||
src="$ctrl.model.Logo"
|
||||
fallback-icon="'svg-rocket'"
|
||||
class-name="'blocklist-item-logo'"
|
||||
fallback-class-name="'!h-14 !w-14 [&>*]:!h-8 [&>*]:!w-auto icon-nested-blue'"
|
||||
fallback-mode="'primary'"
|
||||
></fallback-image>
|
||||
<fallback-image src="$ctrl.model.Logo" fallback-icon="'svg-rocket'" class-name="'blocklist-item-logo'" size="'3xl'"></fallback-image>
|
||||
</div>
|
||||
<!-- !template-image -->
|
||||
<!-- template-details -->
|
||||
|
|
|
@ -5,7 +5,7 @@ import Microsoft from '@/assets/ico/vendor/microsoft.svg?c';
|
|||
import Google from '@/assets/ico/vendor/google.svg?c';
|
||||
import Github from '@/assets/ico/vendor/github.svg?c';
|
||||
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
export const options = [
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ import { TableColumnHeaderAngular } from '@@/datatables/TableHeaderCell';
|
|||
import { DashboardItem } from '@@/DashboardItem';
|
||||
import { SearchBar } from '@@/datatables/SearchBar';
|
||||
import { FallbackImage } from '@@/FallbackImage';
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
import { TeamsSelector } from '@@/TeamsSelector';
|
||||
import { PortainerSelect } from '@@/form-components/PortainerSelect';
|
||||
|
||||
|
@ -88,8 +88,6 @@ export const componentsModule = angular
|
|||
'alt',
|
||||
'size',
|
||||
'className',
|
||||
'fallbackMode',
|
||||
'fallbackClassName',
|
||||
'feather',
|
||||
])
|
||||
)
|
||||
|
@ -106,7 +104,7 @@ export const componentsModule = angular
|
|||
'datatableSearchbar',
|
||||
r2a(SearchBar, ['data-cy', 'onChange', 'value', 'placeholder'])
|
||||
)
|
||||
.component('boxSelectorBadgeIcon', r2a(BadgeIcon, ['featherIcon', 'icon']))
|
||||
.component('badgeIcon', r2a(BadgeIcon, ['featherIcon', 'icon', 'size']))
|
||||
.component(
|
||||
'accessControlPanel',
|
||||
r2a(withUIRouter(withReactQuery(withCurrentUser(AccessControlPanel))), [
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Edit } from 'react-feather';
|
|||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
import Openldap from '@/assets/ico/vendor/openldap.svg?c';
|
||||
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
const SERVER_TYPES = {
|
||||
CUSTOM: 0,
|
||||
|
|
|
@ -7,7 +7,7 @@ import Proget from '@/assets/ico/vendor/proget.svg?c';
|
|||
import Azure from '@/assets/ico/vendor/azure.svg?c';
|
||||
import Gitlab from '@/assets/ico/vendor/gitlab.svg?c';
|
||||
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
export const options = [
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ import Microsoft from '@/assets/ico/vendor/microsoft.svg?c';
|
|||
import Ldap from '@/assets/ico/ldap.svg?c';
|
||||
import OAuth from '@/assets/ico/oauth.svg?c';
|
||||
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
export const options = [
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@ import { DownloadCloud, UploadCloud } from 'react-feather';
|
|||
|
||||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
export const options = [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { Meta } from '@storybook/react';
|
||||
|
||||
import { BadgeIcon, BadgeSize, Props } from './BadgeIcon';
|
||||
|
||||
export default {
|
||||
component: BadgeIcon,
|
||||
title: 'Components/BadgeIcon',
|
||||
argTypes: {
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['md', 'lg', 'xl', '2xl', '3xl'],
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['edit', 'info', 'smile', 'users'],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Meta<Props>;
|
||||
|
||||
// : JSX.IntrinsicAttributes & PropsWithChildren<Props>
|
||||
function Template({
|
||||
size = '3xl',
|
||||
icon = 'edit',
|
||||
}: {
|
||||
size?: BadgeSize;
|
||||
icon: string;
|
||||
}) {
|
||||
return <BadgeIcon icon={icon} size={size} featherIcon />;
|
||||
}
|
||||
|
||||
export const Example = Template.bind({});
|
|
@ -0,0 +1,45 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { Icon, IconProps } from '@@/Icon';
|
||||
|
||||
export type BadgeSize = 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
||||
|
||||
export interface Props extends IconProps {
|
||||
size?: BadgeSize;
|
||||
}
|
||||
|
||||
export function BadgeIcon({ icon, featherIcon, size = '3xl' }: Props) {
|
||||
const sizeClasses = iconSizeToClasses(size);
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
sizeClasses,
|
||||
`badge-icon
|
||||
bg-blue-3 text-blue-8
|
||||
th-dark:bg-gray-9 th-dark:text-blue-3
|
||||
rounded-full
|
||||
inline-flex items-center justify-center
|
||||
`
|
||||
)}
|
||||
>
|
||||
<Icon icon={icon} feather={featherIcon} className="feather !flex" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function iconSizeToClasses(size: BadgeSize) {
|
||||
switch (size) {
|
||||
case 'md':
|
||||
return 'h-6 w-6 text-md';
|
||||
case 'lg':
|
||||
return 'h-8 w-8 text-lg';
|
||||
case 'xl':
|
||||
return 'h-10 w-10 text-xl';
|
||||
case '2xl':
|
||||
return 'h-12 w-12 text-2xl';
|
||||
case '3xl':
|
||||
return 'h-14 w-14 text-3xl';
|
||||
default:
|
||||
return 'h-14 w-14 text-3xl';
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export { BadgeIcon } from './BadgeIcon';
|
|
@ -1,19 +0,0 @@
|
|||
import { Icon, IconProps } from '@@/Icon';
|
||||
|
||||
type Props = IconProps;
|
||||
|
||||
export function BadgeIcon({ icon, featherIcon }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={`badge-icon
|
||||
text-3xl h-14 w-14
|
||||
bg-blue-3 text-blue-8
|
||||
th-dark:bg-gray-9 th-dark:text-blue-3
|
||||
rounded-full
|
||||
inline-flex items-center justify-center
|
||||
`}
|
||||
>
|
||||
<Icon icon={icon} feather={featherIcon} className="feather !flex" />
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -2,7 +2,8 @@ import { Edit, FileText, Globe, Upload } from 'react-feather';
|
|||
|
||||
import GitIcon from '@/assets/ico/git.svg?c';
|
||||
|
||||
import { BadgeIcon } from '../BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
import { BoxSelectorOption } from '../types';
|
||||
|
||||
export const editor: BoxSelectorOption<'editor'> = {
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import clsx from 'clsx';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Icon, IconMode, IconSize } from './Icon';
|
||||
import { BadgeIcon, BadgeSize } from './BadgeIcon/BadgeIcon';
|
||||
|
||||
interface Props {
|
||||
// props for the image to load
|
||||
src: string; // a link to an external image
|
||||
fallbackIcon: string;
|
||||
alt?: string;
|
||||
size?: IconSize;
|
||||
size?: BadgeSize;
|
||||
className?: string;
|
||||
// additional fallback icon props
|
||||
fallbackMode?: IconMode;
|
||||
fallbackClassName?: string;
|
||||
// additional fallback badge props
|
||||
feather?: boolean;
|
||||
}
|
||||
|
||||
|
@ -22,22 +19,18 @@ export function FallbackImage({
|
|||
alt,
|
||||
size,
|
||||
className,
|
||||
fallbackMode,
|
||||
fallbackClassName,
|
||||
feather,
|
||||
}: Props) {
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const classes = clsx(className, { [`icon-${size}`]: size });
|
||||
|
||||
useEffect(() => {
|
||||
setError(false);
|
||||
}, [src]);
|
||||
|
||||
if (!error) {
|
||||
if (!error && src) {
|
||||
return (
|
||||
<img
|
||||
className={classes}
|
||||
className={className}
|
||||
src={src}
|
||||
alt={alt}
|
||||
onError={() => setError(true)}
|
||||
|
@ -46,13 +39,5 @@ export function FallbackImage({
|
|||
}
|
||||
|
||||
// fallback icon if there is an error loading the image
|
||||
return (
|
||||
<Icon
|
||||
icon={fallbackIcon}
|
||||
feather={feather}
|
||||
className={fallbackClassName}
|
||||
size={size}
|
||||
mode={fallbackMode}
|
||||
/>
|
||||
);
|
||||
return <BadgeIcon icon={fallbackIcon} featherIcon={feather} size={size} />;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { ownershipIcon } from '@/portainer/filters/filters';
|
|||
import { Team } from '@/react/portainer/users/teams/types';
|
||||
|
||||
import { BoxSelectorOption } from '@@/BoxSelector/types';
|
||||
import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
import { ResourceControlOwnership } from '../types';
|
||||
|
||||
|
|
Loading…
Reference in New Issue