mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
refactor: New Icon system with Enhanced Antd Custom Icon (#12229)
* Enhance custom icon * Minor fix * Move DashboardList icon trash icon to enhanced * Enhance trash icon on lists * Enhance actions icons card view * Add storybook entry for custom icons * Test delete button * Remove commented line * Fix linting issue * Enhance Antd icons * Enhance existing icons up to BoltSmallRunIcon * Remove unused import * Import/Exports all icons from index * Export all existing icons * Implement more enhanced icons * Add data-id on edit buttons * Fix lint issue * Inherit color * Apply original color to actions * Fix linting issue * Fix typo * Change ModeHoriz to MoreHoriz
This commit is contained in:
@@ -20,6 +20,7 @@ import React, { ReactNode } from 'react';
|
||||
import shortid from 'shortid';
|
||||
import { t, styled } from '@superset-ui/core';
|
||||
import Button from 'src/components/Button';
|
||||
import Icons from 'src/components/Icons';
|
||||
import Fieldset from './Fieldset';
|
||||
import { recurseReactClone } from './utils';
|
||||
import './crud.less';
|
||||
@@ -251,13 +252,18 @@ export default class CRUDCollection extends React.PureComponent<
|
||||
}
|
||||
if (allowDeletes) {
|
||||
tds.push(
|
||||
<td key="__actions" data-test="crud-delete-option">
|
||||
<i
|
||||
{...{ 'data-test': 'crud-delete-icon' }}
|
||||
role="button"
|
||||
<td
|
||||
key="__actions"
|
||||
data-test="crud-delete-option"
|
||||
className="text-primary"
|
||||
>
|
||||
<Icons.Trash
|
||||
aria-label="Delete item"
|
||||
className="pointer"
|
||||
data-test="crud-delete-icon"
|
||||
iconSize="m"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="fa fa-trash text-primary pointer"
|
||||
onClick={this.deleteItem.bind(this, record.id)}
|
||||
/>
|
||||
</td>,
|
||||
|
||||
31
superset-frontend/src/components/Icons/AntdEnhanced.tsx
Normal file
31
superset-frontend/src/components/Icons/AntdEnhanced.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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 React from 'react';
|
||||
import * as AntdIcons from '@ant-design/icons/lib/icons';
|
||||
import Icon from './Icon';
|
||||
import IconType from './IconType';
|
||||
|
||||
const AntdEnhancedIcons = Object.keys(AntdIcons)
|
||||
.map(k => ({
|
||||
[k]: (props: IconType) => <Icon component={AntdIcons[k]} {...props} />,
|
||||
}))
|
||||
.reduce((l, r) => ({ ...l, ...r }));
|
||||
|
||||
export default AntdEnhancedIcons;
|
||||
50
superset-frontend/src/components/Icons/Icon.tsx
Normal file
50
superset-frontend/src/components/Icons/Icon.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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 React from 'react';
|
||||
import AntdIcon from '@ant-design/icons';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';
|
||||
import IconType from './IconType';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const EnhancedIcon = ({ iconColor, iconSize, ...rest }: IconType) => (
|
||||
<AntdIcon viewBox={rest.viewBox || '0 0 24 24'} {...rest} />
|
||||
);
|
||||
|
||||
const Icon = styled(EnhancedIcon)<IconType>`
|
||||
${({ iconColor }) => iconColor && `color: ${iconColor};`};
|
||||
font-size: ${({ iconSize, theme }) =>
|
||||
iconSize ? `${theme.typography.sizes[iconSize]}px` : '24px'};
|
||||
`;
|
||||
|
||||
export const renderIcon = (
|
||||
SVGComponent:
|
||||
| React.ComponentClass<
|
||||
CustomIconComponentProps | React.SVGProps<SVGSVGElement>,
|
||||
any
|
||||
>
|
||||
| React.FunctionComponent<
|
||||
CustomIconComponentProps | React.SVGProps<SVGSVGElement>
|
||||
>
|
||||
| undefined,
|
||||
props: IconType,
|
||||
) => <Icon component={SVGComponent} {...props} />;
|
||||
|
||||
export default Icon;
|
||||
28
superset-frontend/src/components/Icons/IconType.ts
Normal file
28
superset-frontend/src/components/Icons/IconType.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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 AntdIcon from '@ant-design/icons';
|
||||
|
||||
type AntdIconType = typeof AntdIcon.defaultProps;
|
||||
type IconType = AntdIconType & {
|
||||
iconColor?: string;
|
||||
iconSize?: 's' | 'm' | 'l' | 'xl' | 'xxl';
|
||||
};
|
||||
|
||||
export default IconType;
|
||||
83
superset-frontend/src/components/Icons/icons.stories.jsx
Normal file
83
superset-frontend/src/components/Icons/icons.stories.jsx
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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 React from 'react';
|
||||
import { withKnobs, select } from '@storybook/addon-knobs';
|
||||
import { styled, supersetTheme } from '@superset-ui/core';
|
||||
import Icons from '.';
|
||||
import Icon from './Icon';
|
||||
|
||||
export default {
|
||||
title: 'Icons',
|
||||
component: Icon,
|
||||
decorators: [withKnobs],
|
||||
};
|
||||
|
||||
const palette = {};
|
||||
Object.entries(supersetTheme.colors).forEach(([familyName, family]) => {
|
||||
Object.entries(family).forEach(([colorName, colorValue]) => {
|
||||
palette[`${familyName} / ${colorName}`] = colorValue;
|
||||
});
|
||||
});
|
||||
|
||||
const colorKnob = {
|
||||
label: 'Color',
|
||||
options: {
|
||||
Default: null,
|
||||
...palette,
|
||||
},
|
||||
defaultValue: null,
|
||||
};
|
||||
|
||||
const IconSet = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
`;
|
||||
|
||||
const IconBlock = styled.div`
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 10%;
|
||||
text-align: center;
|
||||
padding: ${({ theme }) => theme.gridUnit * 2}px;
|
||||
div {
|
||||
white-space: nowrap;
|
||||
font-size: ${({ theme }) => theme.typography.sizes.s}px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const SupersetIcon = () => (
|
||||
<IconSet>
|
||||
{Object.keys(Icons).map(k => {
|
||||
const IconComponent = Icons[k];
|
||||
return (
|
||||
<IconBlock key={k}>
|
||||
<IconComponent
|
||||
iconColor={select(
|
||||
colorKnob.label,
|
||||
colorKnob.options,
|
||||
colorKnob.defaultValue,
|
||||
colorKnob.groupId,
|
||||
)}
|
||||
/>
|
||||
</IconBlock>
|
||||
);
|
||||
})}
|
||||
</IconSet>
|
||||
);
|
||||
284
superset-frontend/src/components/Icons/index.ts
Normal file
284
superset-frontend/src/components/Icons/index.ts
Normal file
@@ -0,0 +1,284 @@
|
||||
/**
|
||||
* 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 { ReactComponent as AlertIcon } from 'images/icons/alert.svg';
|
||||
import { ReactComponent as AlertSolidIcon } from 'images/icons/alert_solid.svg';
|
||||
import { ReactComponent as AlertSolidSmallIcon } from 'images/icons/alert_solid_small.svg';
|
||||
import { ReactComponent as BinocularsIcon } from 'images/icons/binoculars.svg';
|
||||
import { ReactComponent as BoltIcon } from 'images/icons/bolt.svg';
|
||||
import { ReactComponent as BoltSmallIcon } from 'images/icons/bolt_small.svg';
|
||||
import { ReactComponent as BoltSmallRunIcon } from 'images/icons/bolt_small_run.svg';
|
||||
import { ReactComponent as CalendarIcon } from 'images/icons/calendar.svg';
|
||||
import { ReactComponent as CancelIcon } from 'images/icons/cancel.svg';
|
||||
import { ReactComponent as CancelSolidIcon } from 'images/icons/cancel_solid.svg';
|
||||
import { ReactComponent as CancelXIcon } from 'images/icons/cancel-x.svg';
|
||||
import { ReactComponent as CardViewIcon } from 'images/icons/card_view.svg';
|
||||
import { ReactComponent as CardsIcon } from 'images/icons/cards.svg';
|
||||
import { ReactComponent as CardsLockedIcon } from 'images/icons/cards_locked.svg';
|
||||
import { ReactComponent as CaretDownIcon } from 'images/icons/caret_down.svg';
|
||||
import { ReactComponent as CaretLeftIcon } from 'images/icons/caret_left.svg';
|
||||
import { ReactComponent as CaretRightIcon } from 'images/icons/caret_right.svg';
|
||||
import { ReactComponent as CaretUpIcon } from 'images/icons/caret_up.svg';
|
||||
import { ReactComponent as CertifiedIcon } from 'images/icons/certified.svg';
|
||||
import { ReactComponent as CheckIcon } from 'images/icons/check.svg';
|
||||
import { ReactComponent as CheckboxHalfIcon } from 'images/icons/checkbox-half.svg';
|
||||
import { ReactComponent as CheckboxOffIcon } from 'images/icons/checkbox-off.svg';
|
||||
import { ReactComponent as CheckboxOnIcon } from 'images/icons/checkbox-on.svg';
|
||||
import { ReactComponent as CircleCheckIcon } from 'images/icons/circle_check.svg';
|
||||
import { ReactComponent as CircleCheckSolidIcon } from 'images/icons/circle_check_solid.svg';
|
||||
import { ReactComponent as CircleIcon } from 'images/icons/circle.svg';
|
||||
import { ReactComponent as ClockIcon } from 'images/icons/clock.svg';
|
||||
import { ReactComponent as CloseIcon } from 'images/icons/close.svg';
|
||||
import { ReactComponent as CodeIcon } from 'images/icons/code.svg';
|
||||
import { ReactComponent as CogIcon } from 'images/icons/cog.svg';
|
||||
import { ReactComponent as CollapseIcon } from 'images/icons/collapse.svg';
|
||||
import { ReactComponent as ColorPaletteIcon } from 'images/icons/color_palette.svg';
|
||||
import { ReactComponent as ComponentsIcon } from 'images/icons/components.svg';
|
||||
import { ReactComponent as CopyIcon } from 'images/icons/copy.svg';
|
||||
import { ReactComponent as CursorTargeIcon } from 'images/icons/cursor_target.svg';
|
||||
import { ReactComponent as DatabaseIcon } from 'images/icons/database.svg';
|
||||
import { ReactComponent as DatasetPhysicalIcon } from 'images/icons/dataset_physical.svg';
|
||||
import { ReactComponent as DatasetVirtualGreyscaleIcon } from 'images/icons/dataset_virtual_greyscale.svg';
|
||||
import { ReactComponent as DatasetVirtualIcon } from 'images/icons/dataset_virtual.svg';
|
||||
import { ReactComponent as DownloadIcon } from 'images/icons/download.svg';
|
||||
import { ReactComponent as EditAltIcon } from 'images/icons/edit_alt.svg';
|
||||
import { ReactComponent as EditIcon } from 'images/icons/edit.svg';
|
||||
import { ReactComponent as EmailIcon } from 'images/icons/email.svg';
|
||||
import { ReactComponent as ErrorIcon } from 'images/icons/error.svg';
|
||||
import { ReactComponent as ErrorSolidIcon } from 'images/icons/error_solid.svg';
|
||||
import { ReactComponent as ErrorSolidSmallIcon } from 'images/icons/error_solid_small.svg';
|
||||
import { ReactComponent as ExclamationIcon } from 'images/icons/exclamation.svg';
|
||||
import { ReactComponent as ExpandIcon } from 'images/icons/expand.svg';
|
||||
import { ReactComponent as EyeIcon } from 'images/icons/eye.svg';
|
||||
import { ReactComponent as EyeSlashIcon } from 'images/icons/eye_slash.svg';
|
||||
import { ReactComponent as FavoriteSelectedIcon } from 'images/icons/favorite-selected.svg';
|
||||
import { ReactComponent as FavoriteSmallSelectedIcon } from 'images/icons/favorite_small_selected.svg';
|
||||
import { ReactComponent as FavoriteUnselectedIcon } from 'images/icons/favorite-unselected.svg';
|
||||
import { ReactComponent as FieldABCIcon } from 'images/icons/field_abc.svg';
|
||||
import { ReactComponent as FieldBooleanIcon } from 'images/icons/field_boolean.svg';
|
||||
import { ReactComponent as FieldDateIcon } from 'images/icons/field_date.svg';
|
||||
import { ReactComponent as FieldDerivedIcon } from 'images/icons/field_derived.svg';
|
||||
import { ReactComponent as FieldNumIcon } from 'images/icons/field_num.svg';
|
||||
import { ReactComponent as FieldStructIcon } from 'images/icons/field_struct.svg';
|
||||
import { ReactComponent as FileIcon } from 'images/icons/file.svg';
|
||||
import { ReactComponent as FilterIcon } from 'images/icons/filter.svg';
|
||||
import { ReactComponent as FilterSmallIcon } from 'images/icons/filter_small.svg';
|
||||
import { ReactComponent as FolderIcon } from 'images/icons/folder.svg';
|
||||
import { ReactComponent as FullIcon } from 'images/icons/full.svg';
|
||||
import { ReactComponent as FunctionIcon } from 'images/icons/function_x.svg';
|
||||
import { ReactComponent as GearIcon } from 'images/icons/gear.svg';
|
||||
import { ReactComponent as GridIcon } from 'images/icons/grid.svg';
|
||||
import { ReactComponent as ImageIcon } from 'images/icons/image.svg';
|
||||
import { ReactComponent as ImportIcon } from 'images/icons/import.svg';
|
||||
import { ReactComponent as InfoIcon } from 'images/icons/info.svg';
|
||||
import { ReactComponent as InfoSolidIcon } from 'images/icons/info-solid.svg';
|
||||
import { ReactComponent as InfoSolidSmallIcon } from 'images/icons/info_solid_small.svg';
|
||||
import { ReactComponent as JoinIcon } from 'images/icons/join.svg';
|
||||
import { ReactComponent as KeyboardIcon } from 'images/icons/keyboard.svg';
|
||||
import { ReactComponent as LayersIcon } from 'images/icons/layers.svg';
|
||||
import { ReactComponent as LightbulbIcon } from 'images/icons/lightbulb.svg';
|
||||
import { ReactComponent as LinkIcon } from 'images/icons/link.svg';
|
||||
import { ReactComponent as ListIcon } from 'images/icons/list.svg';
|
||||
import { ReactComponent as ListViewIcon } from 'images/icons/list_view.svg';
|
||||
import { ReactComponent as LocationIcon } from 'images/icons/location.svg';
|
||||
import { ReactComponent as LockLockedIcon } from 'images/icons/lock_locked.svg';
|
||||
import { ReactComponent as LockUnlockedIcon } from 'images/icons/lock_unlocked.svg';
|
||||
import { ReactComponent as MapIcon } from 'images/icons/map.svg';
|
||||
import { ReactComponent as MessageIcon } from 'images/icons/message.svg';
|
||||
import { ReactComponent as MinusIcon } from 'images/icons/minus.svg';
|
||||
import { ReactComponent as MinusSolidIcon } from 'images/icons/minus_solid.svg';
|
||||
import { ReactComponent as MoreHorizIcon } from 'images/icons/more_horiz.svg';
|
||||
import { ReactComponent as MoveIcon } from 'images/icons/move.svg';
|
||||
import { ReactComponent as NavChartsIcon } from 'images/icons/nav_charts.svg';
|
||||
import { ReactComponent as NavDashboardIcon } from 'images/icons/nav_dashboard.svg';
|
||||
import { ReactComponent as NavDataIcon } from 'images/icons/nav_data.svg';
|
||||
import { ReactComponent as NavExploreIcon } from 'images/icons/nav_explore.svg';
|
||||
import { ReactComponent as NavHomeIcon } from 'images/icons/nav_home.svg';
|
||||
import { ReactComponent as NavLabIcon } from 'images/icons/nav_lab.svg';
|
||||
import { ReactComponent as NoteIcon } from 'images/icons/note.svg';
|
||||
import { ReactComponent as OfflineIcon } from 'images/icons/offline.svg';
|
||||
import { ReactComponent as PaperclipIcon } from 'images/icons/paperclip.svg';
|
||||
import { ReactComponent as PlaceholderIcon } from 'images/icons/placeholder.svg';
|
||||
import { ReactComponent as PlusIcon } from 'images/icons/plus.svg';
|
||||
import { ReactComponent as PlusLargeIcon } from 'images/icons/plus_large.svg';
|
||||
import { ReactComponent as PlusSmallIcon } from 'images/icons/plus_small.svg';
|
||||
import { ReactComponent as PlusSolidIcon } from 'images/icons/plus_solid.svg';
|
||||
import { ReactComponent as QueuedIcon } from 'images/icons/queued.svg';
|
||||
import { ReactComponent as RefreshIcon } from 'images/icons/refresh.svg';
|
||||
import { ReactComponent as RunningIcon } from 'images/icons/running.svg';
|
||||
import { ReactComponent as SaveIcon } from 'images/icons/save.svg';
|
||||
import { ReactComponent as SQLIcon } from 'images/icons/sql.svg';
|
||||
import { ReactComponent as SearchIcon } from 'images/icons/search.svg';
|
||||
import { ReactComponent as ServerIcon } from 'images/icons/server.svg';
|
||||
import { ReactComponent as ShareIcon } from 'images/icons/share.svg';
|
||||
import { ReactComponent as SlackIcon } from 'images/icons/slack.svg';
|
||||
import { ReactComponent as SortAscIcon } from 'images/icons/sort_asc.svg';
|
||||
import { ReactComponent as SortDescIcon } from 'images/icons/sort_desc.svg';
|
||||
import { ReactComponent as SortIcon } from 'images/icons/sort.svg';
|
||||
import { ReactComponent as TableIcon } from 'images/icons/table.svg';
|
||||
import { ReactComponent as TagIcon } from 'images/icons/tag.svg';
|
||||
import { ReactComponent as TrashIcon } from 'images/icons/trash.svg';
|
||||
import { ReactComponent as TriangleChangeIcon } from 'images/icons/triangle_change.svg';
|
||||
import { ReactComponent as TriangleDownIcon } from 'images/icons/triangle_down.svg';
|
||||
import { ReactComponent as TriangleUpIcon } from 'images/icons/triangle_up.svg';
|
||||
import { ReactComponent as UpLevelIcon } from 'images/icons/up-level.svg';
|
||||
import { ReactComponent as UserIcon } from 'images/icons/user.svg';
|
||||
import { ReactComponent as WarningIcon } from 'images/icons/warning.svg';
|
||||
import { ReactComponent as WarningSolidIcon } from 'images/icons/warning_solid.svg';
|
||||
import { ReactComponent as XLargeIcon } from 'images/icons/x-large.svg';
|
||||
import { ReactComponent as XSmallIcon } from 'images/icons/x-small.svg';
|
||||
|
||||
import AntdEnhancedIcons from './AntdEnhanced';
|
||||
import { renderIcon } from './Icon';
|
||||
import IconType from './IconType';
|
||||
|
||||
export default {
|
||||
...AntdEnhancedIcons,
|
||||
Alert: (props: IconType) => renderIcon(AlertIcon, props),
|
||||
AlertSolid: (props: IconType) => renderIcon(AlertSolidIcon, props),
|
||||
AlertSolidSmall: (props: IconType) => renderIcon(AlertSolidSmallIcon, props),
|
||||
Binoculars: (props: IconType) => renderIcon(BinocularsIcon, props),
|
||||
Bolt: (props: IconType) => renderIcon(BoltIcon, props),
|
||||
BoltSmall: (props: IconType) => renderIcon(BoltSmallIcon, props),
|
||||
BoltSmallRun: (props: IconType) => renderIcon(BoltSmallRunIcon, props),
|
||||
Calendar: (props: IconType) => renderIcon(CalendarIcon, props),
|
||||
Cancel: (props: IconType) => renderIcon(CancelIcon, props),
|
||||
CancelSolid: (props: IconType) => renderIcon(CancelSolidIcon, props),
|
||||
CancelX: (props: IconType) => renderIcon(CancelXIcon, props),
|
||||
CardView: (props: IconType) => renderIcon(CardViewIcon, props),
|
||||
Cards: (props: IconType) => renderIcon(CardsIcon, props),
|
||||
CardsLocked: (props: IconType) => renderIcon(CardsLockedIcon, props),
|
||||
CaretDown: (props: IconType) => renderIcon(CaretDownIcon, props),
|
||||
CaretLeft: (props: IconType) => renderIcon(CaretLeftIcon, props),
|
||||
CaretRight: (props: IconType) => renderIcon(CaretRightIcon, props),
|
||||
CaretUp: (props: IconType) => renderIcon(CaretUpIcon, props),
|
||||
Certified: (props: IconType) => renderIcon(CertifiedIcon, props),
|
||||
Check: (props: IconType) => renderIcon(CheckIcon, props),
|
||||
CheckboxHalf: (props: IconType) => renderIcon(CheckboxHalfIcon, props),
|
||||
CheckboxOff: (props: IconType) => renderIcon(CheckboxOffIcon, props),
|
||||
CheckboxOn: (props: IconType) => renderIcon(CheckboxOnIcon, props),
|
||||
CircleCheck: (props: IconType) => renderIcon(CircleCheckIcon, props),
|
||||
CircleCheckSolid: (props: IconType) =>
|
||||
renderIcon(CircleCheckSolidIcon, props),
|
||||
Circle: (props: IconType) => renderIcon(CircleIcon, props),
|
||||
Clock: (props: IconType) => renderIcon(ClockIcon, props),
|
||||
Close: (props: IconType) => renderIcon(CloseIcon, props),
|
||||
Code: (props: IconType) => renderIcon(CodeIcon, props),
|
||||
Cog: (props: IconType) => renderIcon(CogIcon, props),
|
||||
Collapse: (props: IconType) => renderIcon(CollapseIcon, props),
|
||||
ColorPalette: (props: IconType) => renderIcon(ColorPaletteIcon, props),
|
||||
Components: (props: IconType) => renderIcon(ComponentsIcon, props),
|
||||
Copy: (props: IconType) => renderIcon(CopyIcon, props),
|
||||
CursorTarget: (props: IconType) => renderIcon(CursorTargeIcon, props),
|
||||
Database: (props: IconType) => renderIcon(DatabaseIcon, props),
|
||||
DatasetPhysical: (props: IconType) => renderIcon(DatasetPhysicalIcon, props),
|
||||
DatasetVirtualGreyscale: (props: IconType) =>
|
||||
renderIcon(DatasetVirtualGreyscaleIcon, props),
|
||||
DatasetVirtual: (props: IconType) => renderIcon(DatasetVirtualIcon, props),
|
||||
Download: (props: IconType) => renderIcon(DownloadIcon, props),
|
||||
EditAlt: (props: IconType) => renderIcon(EditAltIcon, props),
|
||||
Edit: (props: IconType) => renderIcon(EditIcon, props),
|
||||
Email: (props: IconType) => renderIcon(EmailIcon, props),
|
||||
Error: (props: IconType) => renderIcon(ErrorIcon, props),
|
||||
ErrorSolid: (props: IconType) => renderIcon(ErrorSolidIcon, props),
|
||||
ErrorSolidSmall: (props: IconType) => renderIcon(ErrorSolidSmallIcon, props),
|
||||
Exclamation: (props: IconType) => renderIcon(ExclamationIcon, props),
|
||||
Expand: (props: IconType) => renderIcon(ExpandIcon, props),
|
||||
Eye: (props: IconType) => renderIcon(EyeIcon, props),
|
||||
EyeSlash: (props: IconType) => renderIcon(EyeSlashIcon, props),
|
||||
FavoriteSelected: (props: IconType) =>
|
||||
renderIcon(FavoriteSelectedIcon, props),
|
||||
FavoriteSmallSelected: (props: IconType) =>
|
||||
renderIcon(FavoriteSmallSelectedIcon, props),
|
||||
FavoriteUnselected: (props: IconType) =>
|
||||
renderIcon(FavoriteUnselectedIcon, props),
|
||||
FieldABCIcon: (props: IconType) => renderIcon(FieldABCIcon, props),
|
||||
FieldBoolean: (props: IconType) => renderIcon(FieldBooleanIcon, props),
|
||||
FieldDate: (props: IconType) => renderIcon(FieldDateIcon, props),
|
||||
FieldDerived: (props: IconType) => renderIcon(FieldDerivedIcon, props),
|
||||
FieldNum: (props: IconType) => renderIcon(FieldNumIcon, props),
|
||||
FieldStruct: (props: IconType) => renderIcon(FieldStructIcon, props),
|
||||
File: (props: IconType) => renderIcon(FileIcon, props),
|
||||
Filter: (props: IconType) => renderIcon(FilterIcon, props),
|
||||
FilterSmall: (props: IconType) => renderIcon(FilterSmallIcon, props),
|
||||
Folder: (props: IconType) => renderIcon(FolderIcon, props),
|
||||
Full: (props: IconType) => renderIcon(FullIcon, props),
|
||||
Function: (props: IconType) => renderIcon(FunctionIcon, props),
|
||||
Gear: (props: IconType) => renderIcon(GearIcon, props),
|
||||
Grid: (props: IconType) => renderIcon(GridIcon, props),
|
||||
Image: (props: IconType) => renderIcon(ImageIcon, props),
|
||||
Import: (props: IconType) => renderIcon(ImportIcon, props),
|
||||
Info: (props: IconType) => renderIcon(InfoIcon, props),
|
||||
InfoSolid: (props: IconType) => renderIcon(InfoSolidIcon, props),
|
||||
InfoSolidSmall: (props: IconType) => renderIcon(InfoSolidSmallIcon, props),
|
||||
Join: (props: IconType) => renderIcon(JoinIcon, props),
|
||||
Keyboard: (props: IconType) => renderIcon(KeyboardIcon, props),
|
||||
Layers: (props: IconType) => renderIcon(LayersIcon, props),
|
||||
Lightbulb: (props: IconType) => renderIcon(LightbulbIcon, props),
|
||||
Link: (props: IconType) => renderIcon(LinkIcon, props),
|
||||
List: (props: IconType) => renderIcon(ListIcon, props),
|
||||
ListView: (props: IconType) => renderIcon(ListViewIcon, props),
|
||||
Location: (props: IconType) => renderIcon(LocationIcon, props),
|
||||
LockLocked: (props: IconType) => renderIcon(LockLockedIcon, props),
|
||||
LockUnlocked: (props: IconType) => renderIcon(LockUnlockedIcon, props),
|
||||
Map: (props: IconType) => renderIcon(MapIcon, props),
|
||||
Message: (props: IconType) => renderIcon(MessageIcon, props),
|
||||
Minus: (props: IconType) => renderIcon(MinusIcon, props),
|
||||
MinusSolid: (props: IconType) => renderIcon(MinusSolidIcon, props),
|
||||
MoreHoriz: (props: IconType) => renderIcon(MoreHorizIcon, props),
|
||||
Move: (props: IconType) => renderIcon(MoveIcon, props),
|
||||
NavCharts: (props: IconType) => renderIcon(NavChartsIcon, props),
|
||||
NavDashboard: (props: IconType) => renderIcon(NavDashboardIcon, props),
|
||||
NavData: (props: IconType) => renderIcon(NavDataIcon, props),
|
||||
NavExplore: (props: IconType) => renderIcon(NavExploreIcon, props),
|
||||
NavHome: (props: IconType) => renderIcon(NavHomeIcon, props),
|
||||
NavLab: (props: IconType) => renderIcon(NavLabIcon, props),
|
||||
Note: (props: IconType) => renderIcon(NoteIcon, props),
|
||||
Offline: (props: IconType) => renderIcon(OfflineIcon, props),
|
||||
Paperclip: (props: IconType) => renderIcon(PaperclipIcon, props),
|
||||
Placeholder: (props: IconType) => renderIcon(PlaceholderIcon, props),
|
||||
Plus: (props: IconType) => renderIcon(PlusIcon, props),
|
||||
PlusLarge: (props: IconType) => renderIcon(PlusLargeIcon, props),
|
||||
PlusSmall: (props: IconType) => renderIcon(PlusSmallIcon, props),
|
||||
PlusSolid: (props: IconType) => renderIcon(PlusSolidIcon, props),
|
||||
Queued: (props: IconType) => renderIcon(QueuedIcon, props),
|
||||
Refresh: (props: IconType) => renderIcon(RefreshIcon, props),
|
||||
Running: (props: IconType) => renderIcon(RunningIcon, props),
|
||||
Save: (props: IconType) => renderIcon(SaveIcon, props),
|
||||
SQL: (props: IconType) => renderIcon(SQLIcon, props),
|
||||
Search: (props: IconType) => renderIcon(SearchIcon, props),
|
||||
Server: (props: IconType) => renderIcon(ServerIcon, props),
|
||||
Share: (props: IconType) => renderIcon(ShareIcon, props),
|
||||
Slack: (props: IconType) => renderIcon(SlackIcon, props),
|
||||
SortAsc: (props: IconType) => renderIcon(SortAscIcon, props),
|
||||
SortDesc: (props: IconType) => renderIcon(SortDescIcon, props),
|
||||
Sort: (props: IconType) => renderIcon(SortIcon, props),
|
||||
Table: (props: IconType) => renderIcon(TableIcon, props),
|
||||
Tag: (props: IconType) => renderIcon(TagIcon, props),
|
||||
Trash: (props: IconType) => renderIcon(TrashIcon, props),
|
||||
TriangleChange: (props: IconType) => renderIcon(TriangleChangeIcon, props),
|
||||
TriangleDown: (props: IconType) => renderIcon(TriangleDownIcon, props),
|
||||
TriangleUp: (props: IconType) => renderIcon(TriangleUpIcon, props),
|
||||
UpLevel: (props: IconType) => renderIcon(UpLevelIcon, props),
|
||||
User: (props: IconType) => renderIcon(UserIcon, props),
|
||||
Warning: (props: IconType) => renderIcon(WarningIcon, props),
|
||||
WarningSolid: (props: IconType) => renderIcon(WarningSolidIcon, props),
|
||||
XLarge: (props: IconType) => renderIcon(XLargeIcon, props),
|
||||
XSmall: (props: IconType) => renderIcon(XSmallIcon, props),
|
||||
};
|
||||
@@ -19,7 +19,8 @@
|
||||
import React from 'react';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import Icon, { IconName } from 'src/components/Icon';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { TooltipPlacement } from 'antd/lib/tooltip';
|
||||
|
||||
export type ActionProps = {
|
||||
@@ -37,7 +38,6 @@ interface ActionsBarProps {
|
||||
const StyledActions = styled.span`
|
||||
white-space: nowrap;
|
||||
min-width: 100px;
|
||||
|
||||
svg,
|
||||
i {
|
||||
margin-right: 8px;
|
||||
@@ -50,10 +50,15 @@ const StyledActions = styled.span`
|
||||
}
|
||||
`;
|
||||
|
||||
const ActionWrapper = styled.span`
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
|
||||
export default function ActionsBar({ actions }: ActionsBarProps) {
|
||||
return (
|
||||
<StyledActions className="actions">
|
||||
{actions.map((action, index) => {
|
||||
const ActionIcon = Icons[action.icon];
|
||||
if (action.tooltip) {
|
||||
return (
|
||||
<Tooltip
|
||||
@@ -62,21 +67,21 @@ export default function ActionsBar({ actions }: ActionsBarProps) {
|
||||
placement={action.placement}
|
||||
key={index}
|
||||
>
|
||||
<span
|
||||
<ActionWrapper
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="action-button"
|
||||
data-test={action.label}
|
||||
onClick={action.onClick}
|
||||
>
|
||||
<Icon name={action.icon} />
|
||||
</span>
|
||||
<ActionIcon />
|
||||
</ActionWrapper>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
<ActionWrapper
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="action-button"
|
||||
@@ -84,8 +89,8 @@ export default function ActionsBar({ actions }: ActionsBarProps) {
|
||||
data-test={action.label}
|
||||
key={index}
|
||||
>
|
||||
<Icon name={action.icon} />
|
||||
</span>
|
||||
<ActionIcon />
|
||||
</ActionWrapper>
|
||||
);
|
||||
})}
|
||||
</StyledActions>
|
||||
|
||||
@@ -23,6 +23,7 @@ import DashboardImg from 'images/dashboard-card-fallback.svg';
|
||||
import ChartImg from 'images/chart-card-fallback.svg';
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import FaveStar from 'src/components/FaveStar';
|
||||
import ListViewCard from '.';
|
||||
|
||||
@@ -67,10 +68,10 @@ export const SupersetListViewCard = () => (
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item role="button" tabIndex={0} onClick={action('Delete')}>
|
||||
<ListViewCard.MenuIcon name="trash" /> Delete
|
||||
<Icons.Trash /> Delete
|
||||
</Menu.Item>
|
||||
<Menu.Item role="button" tabIndex={0} onClick={action('Edit')}>
|
||||
<ListViewCard.MenuIcon name="edit-alt" /> Edit
|
||||
<Icons.EditAlt /> Edit
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
|
||||
@@ -23,13 +23,6 @@ import { Card, Skeleton, ThinSkeleton } from 'src/common/components';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import ImageLoader, { BackgroundPosition } from './ImageLoader';
|
||||
|
||||
const MenuIcon = styled(Icon)`
|
||||
width: ${({ theme }) => theme.gridUnit * 4}px;
|
||||
height: ${({ theme }) => theme.gridUnit * 4}px;
|
||||
position: relative;
|
||||
top: ${({ theme }) => theme.gridUnit / 2}px;
|
||||
`;
|
||||
|
||||
const ActionsWrapper = styled.div`
|
||||
width: 64px;
|
||||
display: flex;
|
||||
@@ -250,5 +243,5 @@ function ListViewCard({
|
||||
}
|
||||
|
||||
ListViewCard.Actions = ActionsWrapper;
|
||||
ListViewCard.MenuIcon = MenuIcon;
|
||||
|
||||
export default ListViewCard;
|
||||
|
||||
@@ -24,7 +24,6 @@ import moment from 'moment';
|
||||
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
|
||||
import Button from 'src/components/Button';
|
||||
import FacePile from 'src/components/FacePile';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import ListView, {
|
||||
FilterOperators,
|
||||
@@ -297,7 +296,7 @@ function AlertList({
|
||||
label: 'execution-log-action',
|
||||
tooltip: t('Execution log'),
|
||||
placement: 'bottom',
|
||||
icon: 'note' as IconName,
|
||||
icon: 'Note',
|
||||
onClick: handleGotoExecutionLog,
|
||||
}
|
||||
: null,
|
||||
@@ -306,7 +305,7 @@ function AlertList({
|
||||
label: 'edit-action',
|
||||
tooltip: t('Edit'),
|
||||
placement: 'bottom',
|
||||
icon: 'edit' as IconName,
|
||||
icon: 'Edit',
|
||||
onClick: handleEdit,
|
||||
}
|
||||
: null,
|
||||
@@ -315,7 +314,7 @@ function AlertList({
|
||||
label: 'delete-action',
|
||||
tooltip: t('Delete'),
|
||||
placement: 'bottom',
|
||||
icon: 'trash' as IconName,
|
||||
icon: 'Trash',
|
||||
onClick: handleDelete,
|
||||
}
|
||||
: null,
|
||||
|
||||
@@ -31,7 +31,6 @@ import ListView, { ListViewProps } from 'src/components/ListView';
|
||||
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||
import { getClientErrorObject } from 'src/utils/getClientErrorObject';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import { useListViewResource } from 'src/views/CRUD/hooks';
|
||||
import { createErrorHandler } from 'src/views/CRUD/utils';
|
||||
|
||||
@@ -179,14 +178,14 @@ function AnnotationList({
|
||||
label: 'edit-action',
|
||||
tooltip: t('Edit annotation'),
|
||||
placement: 'bottom',
|
||||
icon: 'edit' as IconName,
|
||||
icon: 'Edit',
|
||||
onClick: handleEdit,
|
||||
},
|
||||
{
|
||||
label: 'delete-action',
|
||||
tooltip: t('Delete annotation'),
|
||||
placement: 'bottom',
|
||||
icon: 'trash' as IconName,
|
||||
icon: 'Trash',
|
||||
onClick: handleDelete,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -26,7 +26,6 @@ import { useListViewResource } from 'src/views/CRUD/hooks';
|
||||
import { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
|
||||
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
|
||||
import Button from 'src/components/Button';
|
||||
@@ -230,7 +229,7 @@ function AnnotationLayersList({
|
||||
label: 'edit-action',
|
||||
tooltip: t('Edit template'),
|
||||
placement: 'bottom',
|
||||
icon: 'edit' as IconName,
|
||||
icon: 'Edit',
|
||||
onClick: handleEdit,
|
||||
}
|
||||
: null,
|
||||
@@ -239,7 +238,7 @@ function AnnotationLayersList({
|
||||
label: 'delete-action',
|
||||
tooltip: t('Delete template'),
|
||||
placement: 'bottom',
|
||||
icon: 'trash' as IconName,
|
||||
icon: 'Trash',
|
||||
onClick: handleDelete,
|
||||
}
|
||||
: null,
|
||||
|
||||
@@ -21,6 +21,7 @@ import { t } from '@superset-ui/core';
|
||||
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import Chart from 'src/types/Chart';
|
||||
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
@@ -95,29 +96,33 @@ export default function ChartCard({
|
||||
className="action-button"
|
||||
onClick={confirmDelete}
|
||||
>
|
||||
<ListViewCard.MenuIcon name="trash" /> {t('Delete')}
|
||||
<Icons.Trash iconSize="l" /> {t('Delete')}
|
||||
</div>
|
||||
)}
|
||||
</ConfirmStatusChange>
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canExport && (
|
||||
<Menu.Item
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => handleBulkChartExport([chart])}
|
||||
>
|
||||
<ListViewCard.MenuIcon name="share" /> {t('Export')}
|
||||
<Menu.Item>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => handleBulkChartExport([chart])}
|
||||
>
|
||||
<Icons.Share iconSize="l" /> {t('Export')}
|
||||
</div>
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canEdit && (
|
||||
<Menu.Item
|
||||
data-test="chart-list-edit-option"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => openChartEditModal(chart)}
|
||||
>
|
||||
<ListViewCard.MenuIcon name="edit-alt" /> {t('Edit')}
|
||||
<Menu.Item>
|
||||
<div
|
||||
data-test="chart-list-edit-option"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => openChartEditModal(chart)}
|
||||
>
|
||||
<Icons.EditAlt iconSize="l" /> {t('Edit')}
|
||||
</div>
|
||||
</Menu.Item>
|
||||
)}
|
||||
</Menu>
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { SupersetClient, getChartMetadataRegistry, t } from '@superset-ui/core';
|
||||
import {
|
||||
SupersetClient,
|
||||
getChartMetadataRegistry,
|
||||
t,
|
||||
styled,
|
||||
} from '@superset-ui/core';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import rison from 'rison';
|
||||
import { uniqBy } from 'lodash';
|
||||
@@ -34,7 +39,6 @@ import {
|
||||
} from 'src/views/CRUD/hooks';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||
import Icon from 'src/components/Icon';
|
||||
import FaveStar from 'src/components/FaveStar';
|
||||
import ListView, {
|
||||
ListViewProps,
|
||||
@@ -47,6 +51,7 @@ import PropertiesModal from 'src/explore/components/PropertiesModal';
|
||||
import ImportModelsModal from 'src/components/ImportModal/index';
|
||||
import Chart from 'src/types/Chart';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import Icons from 'src/components/Icons';
|
||||
import ChartCard from './ChartCard';
|
||||
|
||||
const PAGE_SIZE = 25;
|
||||
@@ -111,6 +116,10 @@ interface ChartListProps {
|
||||
};
|
||||
}
|
||||
|
||||
const Actions = styled.div`
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
|
||||
function ChartList(props: ChartListProps) {
|
||||
const { addDangerToast, addSuccessToast } = props;
|
||||
|
||||
@@ -295,7 +304,7 @@ function ChartList(props: ChartListProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="actions">
|
||||
<Actions className="actions">
|
||||
{canDelete && (
|
||||
<ConfirmStatusChange
|
||||
title={t('Please confirm')}
|
||||
@@ -314,12 +323,13 @@ function ChartList(props: ChartListProps) {
|
||||
placement="bottom"
|
||||
>
|
||||
<span
|
||||
data-test="trash"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="action-button"
|
||||
onClick={confirmDelete}
|
||||
>
|
||||
<Icon name="trash" />
|
||||
<Icons.Trash />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -337,7 +347,7 @@ function ChartList(props: ChartListProps) {
|
||||
className="action-button"
|
||||
onClick={handleExport}
|
||||
>
|
||||
<Icon name="share" />
|
||||
<Icons.Share />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -353,11 +363,11 @@ function ChartList(props: ChartListProps) {
|
||||
className="action-button"
|
||||
onClick={openEditModal}
|
||||
>
|
||||
<Icon name="edit-alt" />
|
||||
<Icons.EditAlt data-test="edit-alt" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</span>
|
||||
</Actions>
|
||||
);
|
||||
},
|
||||
Header: t('Actions'),
|
||||
@@ -535,7 +545,7 @@ function ChartList(props: ChartListProps) {
|
||||
}
|
||||
if (isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT)) {
|
||||
subMenuButtons.push({
|
||||
name: <Icon name="import" />,
|
||||
name: <Icons.Import />,
|
||||
buttonStyle: 'link',
|
||||
onClick: openChartImportModal,
|
||||
});
|
||||
|
||||
@@ -29,7 +29,6 @@ import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
|
||||
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
|
||||
import CssTemplateModal from './CssTemplateModal';
|
||||
@@ -209,7 +208,7 @@ function CssTemplatesList({
|
||||
label: 'edit-action',
|
||||
tooltip: t('Edit template'),
|
||||
placement: 'bottom',
|
||||
icon: 'edit' as IconName,
|
||||
icon: 'Edit',
|
||||
onClick: handleEdit,
|
||||
}
|
||||
: null,
|
||||
@@ -218,7 +217,7 @@ function CssTemplatesList({
|
||||
label: 'delete-action',
|
||||
tooltip: t('Delete template'),
|
||||
placement: 'bottom',
|
||||
icon: 'trash' as IconName,
|
||||
icon: 'Trash',
|
||||
onClick: handleDelete,
|
||||
}
|
||||
: null,
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import Label from 'src/components/Label';
|
||||
import FacePile from 'src/components/FacePile';
|
||||
import FaveStar from 'src/components/FaveStar';
|
||||
@@ -68,24 +68,31 @@ function DashboardCard({
|
||||
const menu = (
|
||||
<Menu>
|
||||
{canEdit && openDashboardEditModal && (
|
||||
<Menu.Item
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() =>
|
||||
openDashboardEditModal && openDashboardEditModal(dashboard)
|
||||
}
|
||||
data-test="dashboard-card-option-edit-button"
|
||||
>
|
||||
<ListViewCard.MenuIcon name="edit-alt" /> {t('Edit')}
|
||||
<Menu.Item>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="action-button"
|
||||
onClick={() =>
|
||||
openDashboardEditModal && openDashboardEditModal(dashboard)
|
||||
}
|
||||
data-test="dashboard-card-option-edit-button"
|
||||
>
|
||||
<Icons.EditAlt iconSize="l" data-test="edit-alt" /> {t('Edit')}
|
||||
</div>
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canExport && (
|
||||
<Menu.Item
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => handleBulkDashboardExport([dashboard])}
|
||||
>
|
||||
<ListViewCard.MenuIcon name="share" /> {t('Export')}
|
||||
<Menu.Item>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => handleBulkDashboardExport([dashboard])}
|
||||
className="action-button"
|
||||
data-test="dashboard-card-option-export-button"
|
||||
>
|
||||
<Icons.Share iconSize="l" /> {t('Export')}
|
||||
</div>
|
||||
</Menu.Item>
|
||||
)}
|
||||
{canDelete && (
|
||||
@@ -117,7 +124,7 @@ function DashboardCard({
|
||||
onClick={confirmDelete}
|
||||
data-test="dashboard-card-option-delete-button"
|
||||
>
|
||||
<ListViewCard.MenuIcon name="trash" /> {t('Delete')}
|
||||
<Icons.Trash iconSize="l" /> {t('Delete')}
|
||||
</div>
|
||||
)}
|
||||
</ConfirmStatusChange>
|
||||
@@ -160,7 +167,7 @@ function DashboardCard({
|
||||
isStarred={favoriteStatus}
|
||||
/>
|
||||
<Dropdown overlay={menu}>
|
||||
<Icon name="more-horiz" />
|
||||
<Icons.MoreHoriz />
|
||||
</Dropdown>
|
||||
</ListViewCard.Actions>
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { SupersetClient, t } from '@superset-ui/core';
|
||||
import { styled, SupersetClient, t } from '@superset-ui/core';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import rison from 'rison';
|
||||
import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags';
|
||||
@@ -37,7 +37,7 @@ import ListView, {
|
||||
import Owner from 'src/types/Owner';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import FacePile from 'src/components/FacePile';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import FaveStar from 'src/components/FaveStar';
|
||||
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
@@ -82,6 +82,10 @@ interface Dashboard {
|
||||
created_by: object;
|
||||
}
|
||||
|
||||
const Actions = styled.div`
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
|
||||
function DashboardList(props: DashboardListProps) {
|
||||
const { addDangerToast, addSuccessToast } = props;
|
||||
|
||||
@@ -278,7 +282,7 @@ function DashboardList(props: DashboardListProps) {
|
||||
const handleExport = () => handleBulkDashboardExport([original]);
|
||||
|
||||
return (
|
||||
<span className="actions">
|
||||
<Actions className="actions">
|
||||
{canDelete && (
|
||||
<ConfirmStatusChange
|
||||
title={t('Please confirm')}
|
||||
@@ -302,10 +306,7 @@ function DashboardList(props: DashboardListProps) {
|
||||
className="action-button"
|
||||
onClick={confirmDelete}
|
||||
>
|
||||
<Icon
|
||||
data-test="dashboard-list-trash-icon"
|
||||
name="trash"
|
||||
/>
|
||||
<Icons.Trash data-test="dashboard-list-trash-icon" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -323,7 +324,7 @@ function DashboardList(props: DashboardListProps) {
|
||||
className="action-button"
|
||||
onClick={handleExport}
|
||||
>
|
||||
<Icon name="share" />
|
||||
<Icons.Share />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -339,11 +340,11 @@ function DashboardList(props: DashboardListProps) {
|
||||
className="action-button"
|
||||
onClick={handleEdit}
|
||||
>
|
||||
<Icon name="edit-alt" />
|
||||
<Icons.EditAlt data-test="edit-alt" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</span>
|
||||
</Actions>
|
||||
);
|
||||
},
|
||||
Header: t('Actions'),
|
||||
@@ -491,7 +492,7 @@ function DashboardList(props: DashboardListProps) {
|
||||
}
|
||||
if (isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT)) {
|
||||
subMenuButtons.push({
|
||||
name: <Icon name="import" />,
|
||||
name: <Icons.Import />,
|
||||
buttonStyle: 'link',
|
||||
onClick: openDashboardImportModal,
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import ListView, { Filters } from 'src/components/ListView';
|
||||
import { commonMenuData } from 'src/views/CRUD/data/common';
|
||||
import ImportModelsModal from 'src/components/ImportModal/index';
|
||||
@@ -55,12 +55,20 @@ interface DatabaseListProps {
|
||||
addSuccessToast: (msg: string) => void;
|
||||
}
|
||||
|
||||
const IconBlack = styled(Icon)`
|
||||
const IconCheck = styled(Icons.Check)`
|
||||
color: ${({ theme }) => theme.colors.grayscale.dark1};
|
||||
`;
|
||||
|
||||
const IconCancelX = styled(Icons.CancelX)`
|
||||
color: ${({ theme }) => theme.colors.grayscale.dark1};
|
||||
`;
|
||||
|
||||
const Actions = styled.div`
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
|
||||
function BooleanDisplay({ value }: { value: Boolean }) {
|
||||
return value ? <IconBlack name="check" /> : <IconBlack name="cancel-x" />;
|
||||
return value ? <IconCheck /> : <IconCancelX />;
|
||||
}
|
||||
|
||||
function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
@@ -176,7 +184,7 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
|
||||
if (isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT)) {
|
||||
menuData.buttons.push({
|
||||
name: <Icon name="import" />,
|
||||
name: <Icons.Import />,
|
||||
buttonStyle: 'link',
|
||||
onClick: openDatabaseImportModal,
|
||||
});
|
||||
@@ -289,7 +297,7 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<span className="actions">
|
||||
<Actions className="actions">
|
||||
{canDelete && (
|
||||
<span
|
||||
role="button"
|
||||
@@ -303,7 +311,7 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
title={t('Delete database')}
|
||||
placement="bottom"
|
||||
>
|
||||
<Icon name="trash" />
|
||||
<Icons.Trash />
|
||||
</Tooltip>
|
||||
</span>
|
||||
)}
|
||||
@@ -319,7 +327,7 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
className="action-button"
|
||||
onClick={handleExport}
|
||||
>
|
||||
<Icon name="share" />
|
||||
<Icons.Share />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -336,11 +344,11 @@ function DatabaseList({ addDangerToast, addSuccessToast }: DatabaseListProps) {
|
||||
className="action-button"
|
||||
onClick={handleEdit}
|
||||
>
|
||||
<Icon name="edit-alt" />
|
||||
<Icons.EditAlt data-test="edit-alt" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</span>
|
||||
</Actions>
|
||||
);
|
||||
},
|
||||
Header: t('Actions'),
|
||||
|
||||
@@ -42,7 +42,7 @@ import { commonMenuData } from 'src/views/CRUD/data/common';
|
||||
import Owner from 'src/types/Owner';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import { Tooltip } from 'src/common/components/Tooltip';
|
||||
import Icon from 'src/components/Icon';
|
||||
import Icons from 'src/components/Icons';
|
||||
import FacePile from 'src/components/FacePile';
|
||||
import CertifiedIconWithTooltip from 'src/components/CertifiedIconWithTooltip';
|
||||
import ImportModelsModal from 'src/components/ImportModal/index';
|
||||
@@ -72,6 +72,10 @@ const FlexRowContainer = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const Actions = styled.div`
|
||||
color: ${({ theme }) => theme.colors.grayscale.base};
|
||||
`;
|
||||
|
||||
type Dataset = {
|
||||
changed_by_name: string;
|
||||
changed_by_url: string;
|
||||
@@ -203,14 +207,14 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
id="physical-dataset-tooltip"
|
||||
title={t('Physical dataset')}
|
||||
>
|
||||
<Icon name="dataset-physical" />
|
||||
<Icons.DatasetPhysical />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip id="virtual-dataset-tooltip" title={t('Virtual dataset')}>
|
||||
<Icon name="dataset-virtual" />
|
||||
<Icons.DatasetVirtual />
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
@@ -320,7 +324,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<span className="actions">
|
||||
<Actions className="actions">
|
||||
{canDelete && (
|
||||
<Tooltip
|
||||
id="delete-action-tooltip"
|
||||
@@ -333,7 +337,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
className="action-button"
|
||||
onClick={handleDelete}
|
||||
>
|
||||
<Icon name="trash" />
|
||||
<Icons.Trash />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -349,7 +353,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
className="action-button"
|
||||
onClick={handleExport}
|
||||
>
|
||||
<Icon name="share" />
|
||||
<Icons.Share />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
@@ -365,11 +369,11 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
className="action-button"
|
||||
onClick={handleEdit}
|
||||
>
|
||||
<Icon name="edit-alt" />
|
||||
<Icons.EditAlt />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</span>
|
||||
</Actions>
|
||||
);
|
||||
},
|
||||
Header: t('Actions'),
|
||||
@@ -482,7 +486,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
|
||||
|
||||
if (isFeatureEnabled(FeatureFlag.VERSIONED_EXPORT)) {
|
||||
buttonArr.push({
|
||||
name: <Icon name="import" />,
|
||||
name: <Icons.Import />,
|
||||
buttonStyle: 'link',
|
||||
onClick: openDatasetImportModal,
|
||||
});
|
||||
|
||||
@@ -37,7 +37,6 @@ import SubMenu, {
|
||||
import ListView, { ListViewProps, Filters } from 'src/components/ListView';
|
||||
import DeleteModal from 'src/components/DeleteModal';
|
||||
import ActionsBar, { ActionProps } from 'src/components/ListView/ActionsBar';
|
||||
import { IconName } from 'src/components/Icon';
|
||||
import { commonMenuData } from 'src/views/CRUD/data/common';
|
||||
import { SavedQueryObject } from 'src/views/CRUD/types';
|
||||
import copyTextToClipboard from 'src/utils/copy';
|
||||
@@ -314,7 +313,7 @@ function SavedQueryList({
|
||||
label: 'preview-action',
|
||||
tooltip: t('Query preview'),
|
||||
placement: 'bottom',
|
||||
icon: 'binoculars' as IconName,
|
||||
icon: 'Binoculars',
|
||||
onClick: handlePreview,
|
||||
},
|
||||
canEdit
|
||||
@@ -322,7 +321,7 @@ function SavedQueryList({
|
||||
label: 'edit-action',
|
||||
tooltip: t('Edit query'),
|
||||
placement: 'bottom',
|
||||
icon: 'edit' as IconName,
|
||||
icon: 'Edit',
|
||||
onClick: handleEdit,
|
||||
}
|
||||
: null,
|
||||
@@ -330,7 +329,7 @@ function SavedQueryList({
|
||||
label: 'copy-action',
|
||||
tooltip: t('Copy query URL'),
|
||||
placement: 'bottom',
|
||||
icon: 'copy' as IconName,
|
||||
icon: 'Copy',
|
||||
onClick: handleCopy,
|
||||
},
|
||||
canDelete
|
||||
@@ -338,7 +337,7 @@ function SavedQueryList({
|
||||
label: 'delete-action',
|
||||
tooltip: t('Delete query'),
|
||||
placement: 'bottom',
|
||||
icon: 'trash' as IconName,
|
||||
icon: 'Trash',
|
||||
onClick: handleDelete,
|
||||
}
|
||||
: null,
|
||||
|
||||
Reference in New Issue
Block a user