blob: 9b42c81224cf4c094f3dc8fd51e74d02952699a3 [file] [log] [blame]
/**
* 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, { FC, useMemo } from 'react';
import { styled, t } from '@superset-ui/core';
import { Tooltip } from 'src/components/Tooltip';
import { useDispatch, useSelector } from 'react-redux';
import EditableTitle from 'src/components/EditableTitle';
import SliceHeaderControls, {
SliceHeaderControlsProps,
} from 'src/dashboard/components/SliceHeaderControls';
import FiltersBadge from 'src/dashboard/components/FiltersBadge';
import Icons from 'src/components/Icons';
import { RootState } from 'src/dashboard/types';
import FilterIndicator from 'src/dashboard/components/FiltersBadge/FilterIndicator';
import { clearDataMask } from 'src/dataMask/actions';
type SliceHeaderProps = SliceHeaderControlsProps & {
innerRef?: string;
updateSliceName?: (arg0: string) => void;
editMode?: boolean;
annotationQuery?: object;
annotationError?: object;
sliceName?: string;
filters: object;
handleToggleFullSize: () => void;
formData: object;
};
const annotationsLoading = t('Annotation layers are still loading.');
const annotationsError = t('One ore more annotation layers failed loading.');
const CrossFilterIcon = styled(Icons.CursorTarget)`
cursor: pointer;
color: ${({ theme }) => theme.colors.primary.base};
height: 22px;
width: 22px;
`;
const SliceHeader: FC<SliceHeaderProps> = ({
innerRef = null,
forceRefresh = () => ({}),
updateSliceName = () => ({}),
toggleExpandSlice = () => ({}),
logExploreChart = () => ({}),
exploreUrl = '#',
exportCSV = () => ({}),
editMode = false,
annotationQuery = {},
annotationError = {},
cachedDttm = null,
updatedDttm = null,
isCached = [],
isExpanded = false,
sliceName = '',
supersetCanExplore = false,
supersetCanShare = false,
supersetCanCSV = false,
sliceCanEdit = false,
exportFullCSV,
slice,
componentId,
dashboardId,
addSuccessToast,
addDangerToast,
handleToggleFullSize,
isFullSize,
chartStatus,
formData,
}) => {
const dispatch = useDispatch();
// TODO: change to indicator field after it will be implemented
const crossFilterValue = useSelector<RootState, any>(
state => state.dataMask[slice?.slice_id]?.filterState?.value,
);
const indicator = useMemo(
() => ({
value: crossFilterValue,
name: t('Emitted values'),
}),
[crossFilterValue],
);
return (
<div className="chart-header" data-test="slice-header" ref={innerRef}>
<div className="header-title">
<EditableTitle
title={
sliceName ||
(editMode
? '---' // this makes an empty title clickable
: '')
}
canEdit={editMode}
emptyText=""
onSaveTitle={updateSliceName}
showTooltip={false}
/>
{!!Object.values(annotationQuery).length && (
<Tooltip
id="annotations-loading-tooltip"
placement="top"
title={annotationsLoading}
>
<i
role="img"
aria-label={annotationsLoading}
className="fa fa-refresh warning"
/>
</Tooltip>
)}
{!!Object.values(annotationError).length && (
<Tooltip
id="annoation-errors-tooltip"
placement="top"
title={annotationsError}
>
<i
role="img"
aria-label={annotationsError}
className="fa fa-exclamation-circle danger"
/>
</Tooltip>
)}
</div>
<div className="header-controls">
{!editMode && (
<>
{crossFilterValue && (
<Tooltip
placement="top"
title={
<FilterIndicator
indicator={indicator}
text={t('Click to clear emitted filters')}
/>
}
>
<CrossFilterIcon
onClick={() => dispatch(clearDataMask(slice?.slice_id))}
/>
</Tooltip>
)}
<FiltersBadge chartId={slice.slice_id} />
<SliceHeaderControls
slice={slice}
isCached={isCached}
isExpanded={isExpanded}
cachedDttm={cachedDttm}
updatedDttm={updatedDttm}
toggleExpandSlice={toggleExpandSlice}
forceRefresh={forceRefresh}
logExploreChart={logExploreChart}
exploreUrl={exploreUrl}
exportCSV={exportCSV}
exportFullCSV={exportFullCSV}
supersetCanExplore={supersetCanExplore}
supersetCanShare={supersetCanShare}
supersetCanCSV={supersetCanCSV}
sliceCanEdit={sliceCanEdit}
componentId={componentId}
dashboardId={dashboardId}
addSuccessToast={addSuccessToast}
addDangerToast={addDangerToast}
handleToggleFullSize={handleToggleFullSize}
isFullSize={isFullSize}
chartStatus={chartStatus}
formData={formData}
/>
</>
)}
</div>
</div>
);
};
export default SliceHeader;