Skip to content

Commit

Permalink
fix: Owners selection in dataset edit UX (#17063)
Browse files Browse the repository at this point in the history
* boilerplate

* update owner select component

* this is working

* update onchange

* refactorig

* you need to useMemo or things break

* update test

* prettier

* move logic into bootstrap data endpoint

* address concerns

* oops

* oops

* fix test
  • Loading branch information
hughhhh authored Oct 13, 2021
1 parent 11d52cb commit 959fd76
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 24 deletions.
1 change: 1 addition & 0 deletions superset-frontend/spec/fixtures/mockDatasource.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export default {
id,
granularity_sqla: [['ds', 'ds']],
name: 'birth_names',
owners: [{ first_name: 'joe', last_name: 'man', id: 1 }],
database: {
allow_multi_schema_metadata_fetch: null,
name: 'main',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ describe('FiltersBadge', () => {
wrapper.find('[data-test="incompatible-filter-count"]'),
).toHaveText('1');
// to look at the shape of the wrapper use:
// console.log(wrapper.debug())
expect(wrapper.find(Icons.AlertSolid)).toExist();
});
});
Expand Down
60 changes: 40 additions & 20 deletions superset-frontend/src/datasource/DatasourceEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import rison from 'rison';
import React from 'react';
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'src/common/components';
import { Radio } from 'src/components/Radio';
Expand All @@ -26,6 +26,8 @@ import Alert from 'src/components/Alert';
import Badge from 'src/components/Badge';
import shortid from 'shortid';
import { styled, SupersetClient, t, supersetTheme } from '@superset-ui/core';
import { Select } from 'src/components';
import { FormLabel } from 'src/components/Form';
import Button from 'src/components/Button';
import Tabs from 'src/components/Tabs';
import CertifiedIcon from 'src/components/CertifiedIcon';
Expand All @@ -40,9 +42,7 @@ import { getClientErrorObject } from 'src/utils/getClientErrorObject';

import CheckboxControl from 'src/explore/components/controls/CheckboxControl';
import TextControl from 'src/explore/components/controls/TextControl';
import { Select } from 'src/components';
import TextAreaControl from 'src/explore/components/controls/TextAreaControl';
import SelectAsyncControl from 'src/explore/components/controls/SelectAsyncControl';
import SpatialControl from 'src/explore/components/controls/SpatialControl';

import CollectionTable from 'src/CRUD/CollectionTable';
Expand Down Expand Up @@ -374,12 +374,44 @@ const defaultProps = {
onChange: () => {},
};

function OwnersSelector({ datasource, onChange }) {
const loadOptions = useCallback((search = '', page, pageSize) => {
const query = rison.encode({ filter: search, page, page_size: pageSize });
return SupersetClient.get({
endpoint: `/api/v1/dataset/related/owners?q=${query}`,
}).then(response => ({
data: response.json.result.map(item => ({
value: item.value,
label: item.text,
})),
totalCount: response.json.count,
}));
}, []);

return (
<Select
ariaLabel={t('Select owners')}
mode="multiple"
name="owners"
value={datasource.owners}
options={loadOptions}
onChange={onChange}
header={<FormLabel>{t('Owners')}</FormLabel>}
allowClear
/>
);
}

class DatasourceEditor extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
datasource: {
...props.datasource,
owners: props.datasource.owners.map(owner => ({
value: owner.id,
label: `${owner.first_name} ${owner.last_name}`,
})),
metrics: props.datasource.metrics?.map(metric => {
const {
certified_by: certifiedByMetric,
Expand Down Expand Up @@ -717,23 +749,11 @@ class DatasourceEditor extends React.PureComponent {
}
/>
)}
<Field
fieldKey="owners"
label={t('Owners')}
description={t('Owners of the dataset')}
control={
<SelectAsyncControl
dataEndpoint="api/v1/dataset/related/owners"
multi
mutator={data =>
data.result.map(pk => ({
value: pk.value,
label: `${pk.text}`,
}))
}
/>
}
controlProps={{}}
<OwnersSelector
datasource={datasource}
onChange={newOwners => {
this.onDatasourceChange({ ...datasource, owners: newOwners });
}}
/>
</Fieldset>
);
Expand Down
4 changes: 3 additions & 1 deletion superset-frontend/src/datasource/DatasourceModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ const DatasourceModal: FunctionComponent<DatasourceModalProps> = ({
currentDatasource.schema;

setIsSaving(true);

SupersetClient.post({
endpoint: '/datasource/save/',
postPayload: {
Expand All @@ -119,6 +118,9 @@ const DatasourceModal: FunctionComponent<DatasourceModalProps> = ({
}),
),
type: currentDatasource.type || currentDatasource.datasource_type,
owners: currentDatasource.owners.map(
(o: { label: string; value: number }) => o.value,
),
},
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const createProps = () => ({
name: 'channels',
type: 'table',
columns: [],
owners: [{ first_name: 'john', last_name: 'doe', id: 1, username: 'jd' }],
},
validationErrors: [],
name: 'datasource',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
endpoint: `/api/v1/dataset/${id}`,
})
.then(({ json = {} }) => {
const owners = json.result.owners.map((owner: any) => owner.id);
const addCertificationFields = json.result.columns.map(
(column: ColumnObject) => {
const {
Expand All @@ -181,7 +180,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
);
// eslint-disable-next-line no-param-reassign
json.result.columns = [...addCertificationFields];
setDatasetCurrentlyEditing({ ...json.result, owners });
setDatasetCurrentlyEditing(json.result);
})
.catch(() => {
addDangerToast(
Expand Down
12 changes: 12 additions & 0 deletions superset/connectors/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,18 @@ def name(self) -> str:
def kind(self) -> DatasourceKind:
return DatasourceKind.VIRTUAL if self.sql else DatasourceKind.PHYSICAL

@property
def owners_data(self) -> List[Dict[str, Any]]:
return [
{
"first_name": o.first_name,
"last_name": o.last_name,
"username": o.username,
"id": o.id,
}
for o in self.owners
]

@property
def is_virtual(self) -> bool:
return self.kind == DatasourceKind.VIRTUAL
Expand Down
3 changes: 3 additions & 0 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,9 @@ def explore(
except (SupersetException, SQLAlchemyError):
datasource_data = dummy_datasource_data

if datasource:
datasource_data["owners"] = datasource.owners_data

bootstrap_data = {
"can_add": slice_add_perm,
"can_download": slice_download_perm,
Expand Down

0 comments on commit 959fd76

Please sign in to comment.