mirror of
https://github.com/apache/superset.git
synced 2026-04-19 16:14:52 +00:00
committed by
GitHub
parent
147605cb40
commit
1b908ab9f1
@@ -171,15 +171,17 @@ export default class ResultSet extends React.PureComponent<
|
||||
appContainer?.getAttribute('data-bootstrap') || '{}',
|
||||
);
|
||||
|
||||
const datasets = await getByUser(bootstrapData.user.userId);
|
||||
const userDatasetsOwned = datasets.map(
|
||||
(r: { table_name: string; id: number }) => ({
|
||||
datasetName: r.table_name,
|
||||
datasetId: r.id,
|
||||
}),
|
||||
);
|
||||
if (bootstrapData.user && bootstrapData.user.id) {
|
||||
const datasets = await getByUser(bootstrapData.user.userId);
|
||||
const userDatasetsOwned = datasets.map(
|
||||
(r: { table_name: string; id: number }) => ({
|
||||
datasetName: r.table_name,
|
||||
datasetId: r.id,
|
||||
}),
|
||||
);
|
||||
|
||||
this.setState({ userDatasetsOwned });
|
||||
this.setState({ userDatasetsOwned });
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps: ResultSetProps) {
|
||||
|
||||
@@ -180,6 +180,7 @@ export function Menu({
|
||||
title={t('Settings')}
|
||||
onMouseEnter={() => setDropdownOpen(true)}
|
||||
onMouseLeave={() => setDropdownOpen(false)}
|
||||
onToggle={value => setDropdownOpen(value)}
|
||||
open={dropdownOpen}
|
||||
>
|
||||
<DropdownMenu>
|
||||
|
||||
@@ -60,6 +60,7 @@ export default function MenuObject({
|
||||
title={label}
|
||||
onMouseEnter={() => setDropdownOpen(true)}
|
||||
onMouseLeave={() => setDropdownOpen(false)}
|
||||
onToggle={value => setDropdownOpen(value)}
|
||||
open={dropdownOpen}
|
||||
>
|
||||
<Menu>
|
||||
|
||||
@@ -51,6 +51,7 @@ export default function NewMenu() {
|
||||
title={<StyledI className="fa fa-plus" />}
|
||||
onMouseEnter={() => setDropdownOpen(true)}
|
||||
onMouseLeave={() => setDropdownOpen(false)}
|
||||
onToggle={value => setDropdownOpen(value)}
|
||||
open={dropdownOpen}
|
||||
>
|
||||
<Menu>
|
||||
|
||||
@@ -138,41 +138,44 @@ const SubMenu: React.FunctionComponent<SubMenuProps> = props => {
|
||||
props.tabs.map(tab => {
|
||||
if ((props.usesRouter || hasHistory) && !!tab.usesRouter) {
|
||||
return (
|
||||
<li
|
||||
className={tab.name === props.activeChild ? 'active' : ''}
|
||||
key={`${tab.label}`}
|
||||
>
|
||||
<div>
|
||||
<Link to={tab.url || ''}>{tab.label}</Link>
|
||||
</div>
|
||||
</li>
|
||||
<React.Fragment key={tab.label}>
|
||||
<li
|
||||
className={tab.name === props.activeChild ? 'active' : ''}
|
||||
>
|
||||
<div>
|
||||
<Link to={tab.url || ''}>{tab.label}</Link>
|
||||
</div>
|
||||
</li>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<li
|
||||
className={cx('no-router', {
|
||||
active: tab.name === props.activeChild,
|
||||
})}
|
||||
key={`${tab.label}`}
|
||||
>
|
||||
<a href={tab.url} onClick={tab.onClick}>
|
||||
{tab.label}
|
||||
</a>
|
||||
</li>
|
||||
<React.Fragment key={tab.label}>
|
||||
<li
|
||||
className={cx('no-router', {
|
||||
active: tab.name === props.activeChild,
|
||||
})}
|
||||
>
|
||||
<a href={tab.url} onClick={tab.onClick}>
|
||||
{tab.label}
|
||||
</a>
|
||||
</li>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</Nav>
|
||||
<Nav className="navbar-right">
|
||||
{props.buttons?.map((btn, i) => (
|
||||
<Button
|
||||
key={`${i}`}
|
||||
buttonStyle={btn.buttonStyle}
|
||||
onClick={btn.onClick}
|
||||
data-test={btn['data-test']}
|
||||
>
|
||||
{btn.name}
|
||||
</Button>
|
||||
<React.Fragment key={`${i}`}>
|
||||
<Button
|
||||
buttonStyle={btn.buttonStyle}
|
||||
onClick={btn.onClick}
|
||||
data-test={btn['data-test']}
|
||||
>
|
||||
{btn.name}
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Nav>
|
||||
</Navbar>
|
||||
|
||||
@@ -300,7 +300,7 @@ export type SelectComponentsType = Omit<
|
||||
export type InputProps = ReactSelectInputProps & {
|
||||
placeholder?: ReactNode;
|
||||
selectProps: SelectProps;
|
||||
autocomplete?: string;
|
||||
autoComplete?: string;
|
||||
onPaste?: SupersetStyledSelectProps<OptionType>['onPaste'];
|
||||
inputStyle?: object;
|
||||
};
|
||||
@@ -352,7 +352,7 @@ export const DEFAULT_COMPONENTS: SelectComponentsType = {
|
||||
{...props}
|
||||
placeholder={isMultiWithValue ? placeholder : undefined}
|
||||
css={getStyles('input', props)}
|
||||
autocomplete="chrome-off"
|
||||
autoComplete="chrome-off"
|
||||
inputStyle={
|
||||
isMultiWithValue
|
||||
? { ...INPUT_TAG_BASE_STYLES, width: '100%' }
|
||||
|
||||
@@ -343,7 +343,7 @@ export default class AdhocFilterEditPopoverSimpleTabContent extends React.Compon
|
||||
filterBy={
|
||||
column.saved_metric_name || column.column_name || column.label
|
||||
}
|
||||
key={column.id}
|
||||
key={column.id || column.optionName}
|
||||
>
|
||||
{this.renderSubjectOptionLabel(column)}
|
||||
</Select.Option>
|
||||
|
||||
@@ -77,6 +77,7 @@ class AdhocFilterControl extends React.Component {
|
||||
this.onFilterEdit = this.onFilterEdit.bind(this);
|
||||
this.moveLabel = this.moveLabel.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.mapOption = this.mapOption.bind(this);
|
||||
this.getMetricExpression = this.getMetricExpression.bind(this);
|
||||
|
||||
const filters = (this.props.value || []).map(filter =>
|
||||
@@ -176,15 +177,18 @@ class AdhocFilterControl extends React.Component {
|
||||
}
|
||||
|
||||
onNewFilter(newFilter) {
|
||||
this.setState(
|
||||
prevState => ({
|
||||
...prevState,
|
||||
values: [...prevState.values, newFilter],
|
||||
}),
|
||||
() => {
|
||||
this.onChange(this.state.values);
|
||||
},
|
||||
);
|
||||
const mappedOption = this.mapOption(newFilter);
|
||||
if (mappedOption) {
|
||||
this.setState(
|
||||
prevState => ({
|
||||
...prevState,
|
||||
values: [...prevState.values, mappedOption],
|
||||
}),
|
||||
() => {
|
||||
this.props.onChange(this.state.values);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onFilterEdit(changedFilter) {
|
||||
@@ -200,56 +204,7 @@ class AdhocFilterControl extends React.Component {
|
||||
|
||||
onChange(opts) {
|
||||
const options = (opts || [])
|
||||
.map(option => {
|
||||
// already a AdhocFilter, skip
|
||||
if (option instanceof AdhocFilter) {
|
||||
return option;
|
||||
}
|
||||
// via datasource saved metric
|
||||
if (option.saved_metric_name) {
|
||||
return new AdhocFilter({
|
||||
expressionType:
|
||||
this.props.datasource.type === 'druid'
|
||||
? EXPRESSION_TYPES.SIMPLE
|
||||
: EXPRESSION_TYPES.SQL,
|
||||
subject:
|
||||
this.props.datasource.type === 'druid'
|
||||
? option.saved_metric_name
|
||||
: this.getMetricExpression(option.saved_metric_name),
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
});
|
||||
}
|
||||
// has a custom label, meaning it's custom column
|
||||
if (option.label) {
|
||||
return new AdhocFilter({
|
||||
expressionType:
|
||||
this.props.datasource.type === 'druid'
|
||||
? EXPRESSION_TYPES.SIMPLE
|
||||
: EXPRESSION_TYPES.SQL,
|
||||
subject:
|
||||
this.props.datasource.type === 'druid'
|
||||
? option.label
|
||||
: new AdhocMetric(option).translateToSql(),
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
});
|
||||
}
|
||||
// add a new filter item
|
||||
if (option.column_name) {
|
||||
return new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: option.column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
isNew: true,
|
||||
});
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.map(option => this.mapOption(option))
|
||||
.filter(option => option);
|
||||
this.props.onChange(options);
|
||||
}
|
||||
@@ -271,6 +226,57 @@ class AdhocFilterControl extends React.Component {
|
||||
this.setState({ values: newValues });
|
||||
}
|
||||
|
||||
mapOption(option) {
|
||||
// already a AdhocFilter, skip
|
||||
if (option instanceof AdhocFilter) {
|
||||
return option;
|
||||
}
|
||||
// via datasource saved metric
|
||||
if (option.saved_metric_name) {
|
||||
return new AdhocFilter({
|
||||
expressionType:
|
||||
this.props.datasource.type === 'druid'
|
||||
? EXPRESSION_TYPES.SIMPLE
|
||||
: EXPRESSION_TYPES.SQL,
|
||||
subject:
|
||||
this.props.datasource.type === 'druid'
|
||||
? option.saved_metric_name
|
||||
: this.getMetricExpression(option.saved_metric_name),
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
});
|
||||
}
|
||||
// has a custom label, meaning it's custom column
|
||||
if (option.label) {
|
||||
return new AdhocFilter({
|
||||
expressionType:
|
||||
this.props.datasource.type === 'druid'
|
||||
? EXPRESSION_TYPES.SIMPLE
|
||||
: EXPRESSION_TYPES.SQL,
|
||||
subject:
|
||||
this.props.datasource.type === 'druid'
|
||||
? option.label
|
||||
: new AdhocMetric(option).translateToSql(),
|
||||
operator: OPERATORS['>'],
|
||||
comparator: 0,
|
||||
clause: CLAUSES.HAVING,
|
||||
});
|
||||
}
|
||||
// add a new filter item
|
||||
if (option.column_name) {
|
||||
return new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: option.column_name,
|
||||
operator: OPERATORS['=='],
|
||||
comparator: '',
|
||||
clause: CLAUSES.WHERE,
|
||||
isNew: true,
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
optionsForSelect(props) {
|
||||
const options = [
|
||||
...props.columns,
|
||||
|
||||
@@ -296,9 +296,18 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
const id = database.id || 0;
|
||||
setTabKey(DEFAULT_TAB_KEY);
|
||||
|
||||
fetchResource(id).then(() => {
|
||||
setDB(dbFetched);
|
||||
});
|
||||
fetchResource(id)
|
||||
.then(() => {
|
||||
setDB(dbFetched);
|
||||
})
|
||||
.catch(e =>
|
||||
addDangerToast(
|
||||
t(
|
||||
'Sorry there was an error fetching database information: %s',
|
||||
e.message,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if (!isEditMode && (!db || db.id || (isHidden && show))) {
|
||||
setTabKey(DEFAULT_TAB_KEY);
|
||||
|
||||
@@ -59,14 +59,14 @@ export default function EmptyState({ tableName, tab }: EmptyStateProps) {
|
||||
SAVED_QUERIES: 'empty-queries.svg',
|
||||
};
|
||||
const mine = (
|
||||
<div>{`No ${
|
||||
<span>{`No ${
|
||||
tableName === 'SAVED_QUERIES'
|
||||
? t('saved queries')
|
||||
: t(`${tableName.toLowerCase()}`)
|
||||
} yet`}</div>
|
||||
} yet`}</span>
|
||||
);
|
||||
const recent = (
|
||||
<div className="no-recents">
|
||||
<span className="no-recents">
|
||||
{(() => {
|
||||
if (tab === 'Viewed') {
|
||||
return t(
|
||||
@@ -90,7 +90,7 @@ export default function EmptyState({ tableName, tab }: EmptyStateProps) {
|
||||
}
|
||||
return null;
|
||||
})()}
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
// Mine and Recent Activity(all tabs) tab empty state
|
||||
if (tab === 'Mine' || tableName === 'RECENTS') {
|
||||
@@ -131,9 +131,9 @@ export default function EmptyState({ tableName, tab }: EmptyStateProps) {
|
||||
<Empty
|
||||
image="/static/assets/images/star-circle.svg"
|
||||
description={
|
||||
<div className="no-favorites">
|
||||
<span className="no-favorites">
|
||||
{t("You don't have any favorites yet!")}
|
||||
</div>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user