feat: add created by chart CRUD view (#11067)

This commit is contained in:
Lily Kuang
2020-09-30 13:53:04 -07:00
committed by GitHub
parent 0bcc9d77a7
commit 5b284e67eb
6 changed files with 132 additions and 25 deletions

View File

@@ -18,7 +18,7 @@
*/ */
import { CHART_LIST } from './chart_list.helper'; import { CHART_LIST } from './chart_list.helper';
describe('chart filters', () => { describe('chart card view filters', () => {
beforeEach(() => { beforeEach(() => {
cy.login(); cy.login();
cy.server(); cy.server();
@@ -36,26 +36,88 @@ describe('chart filters', () => {
cy.get('.ant-card').should('not.exist'); cy.get('.ant-card').should('not.exist');
}); });
it('should filter by created by correctly', () => {
// filter by created by
cy.get('.Select__control').eq(1).click();
cy.get('.Select__menu').contains('alpha user').click();
cy.get('.ant-card').should('not.exist');
cy.get('.Select__control').eq(1).click();
cy.get('.Select__menu').contains('gamma user').click();
cy.get('.ant-card').should('not.exist');
});
it('should filter by viz type correctly', () => { it('should filter by viz type correctly', () => {
// filter by viz type // filter by viz type
cy.get('.Select__control').eq(1).click(); cy.get('.Select__control').eq(2).click();
cy.get('.Select__menu').contains('area').click({ timeout: 5000 }); cy.get('.Select__menu').contains('area').click({ timeout: 5000 });
cy.get('.ant-card').its('length').should('be.gt', 0); cy.get('.ant-card').its('length').should('be.gt', 0);
cy.get('.ant-card').contains("World's Pop Growth").should('exist'); cy.get('.ant-card').contains("World's Pop Growth").should('exist');
cy.get('.Select__control').eq(1).click(); cy.get('.Select__control').eq(2).click();
cy.get('.Select__control').eq(1).type('world_map{enter}'); cy.get('.Select__control').eq(2).type('world_map{enter}');
cy.get('.ant-card').should('have.length', 1); cy.get('.ant-card').should('have.length', 1);
cy.get('.ant-card').contains('% Rural').should('exist'); cy.get('.ant-card').contains('% Rural').should('exist');
}); });
it('should filter by datasource correctly', () => { it('should filter by datasource correctly', () => {
// filter by datasource // filter by datasource
cy.get('.Select__control').eq(2).click(); cy.get('.Select__control').eq(3).click();
cy.get('.Select__menu').contains('unicode_test').click(); cy.get('.Select__menu').contains('unicode_test').click();
cy.get('.ant-card').should('have.length', 1); cy.get('.ant-card').should('have.length', 1);
cy.get('.ant-card').contains('Unicode Cloud').should('exist'); cy.get('.ant-card').contains('Unicode Cloud').should('exist');
cy.get('.Select__control').eq(2).click(); cy.get('.Select__control').eq(3).click();
cy.get('.Select__control').eq(2).type('energy_usage{enter}{enter}'); cy.get('.Select__control').eq(3).type('energy_usage{enter}{enter}');
cy.get('.ant-card').its('length').should('be.gt', 0); cy.get('.ant-card').its('length').should('be.gt', 0);
}); });
}); });
describe('chart list view filters', () => {
beforeEach(() => {
cy.login();
cy.server();
cy.visit(CHART_LIST);
cy.get('[data-test="list-view"]').click();
});
it('should filter by owners correctly', () => {
// filter by owners
cy.get('.Select__control').first().click();
cy.get('.Select__menu').contains('alpha user').click();
cy.get('.table-row').should('not.exist');
cy.get('.Select__control').first().click();
cy.get('.Select__menu').contains('gamma user').click();
cy.get('.table-row').should('not.exist');
});
it('should filter by created by correctly', () => {
// filter by created by
cy.get('.Select__control').eq(1).click();
cy.get('.Select__menu').contains('alpha user').click();
cy.get('.table-row').should('not.exist');
cy.get('.Select__control').eq(1).click();
cy.get('.Select__menu').contains('gamma user').click();
cy.get('.table-row').should('not.exist');
});
it('should filter by viz type correctly', () => {
// filter by viz type
cy.get('.Select__control').eq(2).click();
cy.get('.Select__menu').contains('area').click({ timeout: 5000 });
cy.get('.table-row').its('length').should('be.gt', 0);
cy.get('.table-row').contains("World's Pop Growth").should('exist');
cy.get('.Select__control').eq(2).click();
cy.get('.Select__control').eq(2).type('world_map{enter}');
cy.get('.table-row').should('have.length', 1);
cy.get('.table-row').contains('% Rural').should('exist');
});
it('should filter by datasource correctly', () => {
// filter by datasource
cy.get('.Select__control').eq(3).click();
cy.get('.Select__menu').contains('unicode_test').click();
cy.get('.table-row').should('have.length', 1);
cy.get('.table-row').contains('Unicode Cloud').should('exist');
cy.get('.Select__control').eq(3).click();
cy.get('.Select__control').eq(3).type('energy_usage{enter}{enter}');
cy.get('.table-row').its('length').should('be.gt', 0);
});
});

View File

@@ -26,7 +26,7 @@ describe('chart list view', () => {
cy.get('[data-test="list-view"]').click(); cy.get('[data-test="list-view"]').click();
}); });
it.skip('should load rows', () => { it('should load rows', () => {
cy.get('.chart-list-view'); cy.get('.chart-list-view');
cy.get('table[role="table"]').should('be.visible'); cy.get('table[role="table"]').should('be.visible');
@@ -38,7 +38,8 @@ describe('chart list view', () => {
cy.get('th[role="columnheader"]:nth-child(4)').contains('Dataset'); cy.get('th[role="columnheader"]:nth-child(4)').contains('Dataset');
cy.get('th[role="columnheader"]:nth-child(5)').contains('Modified By'); cy.get('th[role="columnheader"]:nth-child(5)').contains('Modified By');
cy.get('th[role="columnheader"]:nth-child(6)').contains('Last Modified'); cy.get('th[role="columnheader"]:nth-child(6)').contains('Last Modified');
cy.get('th[role="columnheader"]:nth-child(7)').contains('Actions'); cy.get('th[role="columnheader"]:nth-child(7)').contains('Created By');
cy.get('th[role="columnheader"]:nth-child(8)').contains('Actions');
cy.get('.table-row').should('have.length', 25); cy.get('.table-row').should('have.length', 25);
}); });

View File

@@ -63,6 +63,7 @@ describe('dashboard filters list view', () => {
cy.login(); cy.login();
cy.server(); cy.server();
cy.visit(DASHBOARD_LIST); cy.visit(DASHBOARD_LIST);
cy.get('[data-test="list-view"]').click();
}); });
it('should filter by owners correctly', () => { it('should filter by owners correctly', () => {

View File

@@ -257,6 +257,17 @@ function ChartList(props: ChartListProps) {
hidden: true, hidden: true,
disableSortBy: true, disableSortBy: true,
}, },
{
Cell: ({
row: {
original: { created_by: createdBy },
},
}: any) =>
createdBy ? `${createdBy.first_name} ${createdBy.last_name}` : '',
Header: t('Created By'),
accessor: 'created_by',
disableSortBy: true,
},
{ {
Cell: ({ row: { original } }: any) => { Cell: ({ row: { original } }: any) => {
const handleDelete = () => handleChartDelete(original); const handleDelete = () => handleChartDelete(original);
@@ -324,7 +335,27 @@ function ChartList(props: ChartListProps) {
createErrorHandler(errMsg => createErrorHandler(errMsg =>
props.addDangerToast( props.addDangerToast(
t( t(
'An error occurred while fetching chart dataset values: %s', 'An error occurred while fetching chart owners values: %s',
errMsg,
),
),
),
),
paginate: true,
},
{
Header: t('Created By'),
id: 'created_by',
input: 'select',
operator: 'rel_o_m',
unfilteredLabel: 'All',
fetchSelects: createFetchRelated(
'chart',
'created_by',
createErrorHandler(errMsg =>
props.addDangerToast(
t(
'An error occurred while fetching chart created by values: %s',
errMsg, errMsg,
), ),
), ),

View File

@@ -107,22 +107,25 @@ class ChartRestApi(BaseSupersetModelRestApi):
"changed_by_url", "changed_by_url",
"changed_on_delta_humanized", "changed_on_delta_humanized",
"changed_on_utc", "changed_on_utc",
"created_by.first_name",
"created_by.id",
"created_by.last_name",
"datasource_id", "datasource_id",
"datasource_name_text", "datasource_name_text",
"datasource_type", "datasource_type",
"datasource_url", "datasource_url",
"description", "description",
"id", "id",
"owners.first_name",
"owners.id",
"owners.last_name",
"owners.username",
"params", "params",
"slice_name", "slice_name",
"table.default_endpoint", "table.default_endpoint",
"table.table_name", "table.table_name",
"thumbnail_url", "thumbnail_url",
"url", "url",
"owners.id",
"owners.username",
"owners.first_name",
"owners.last_name",
"viz_type", "viz_type",
] ]
list_select_columns = list_columns + ["changed_by_fk", "changed_on"] list_select_columns = list_columns + ["changed_by_fk", "changed_on"]
@@ -135,6 +138,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
"viz_type", "viz_type",
] ]
search_columns = [ search_columns = [
"created_by",
"datasource_id", "datasource_id",
"datasource_name", "datasource_name",
"datasource_type", "datasource_type",
@@ -172,10 +176,11 @@ class ChartRestApi(BaseSupersetModelRestApi):
} }
related_field_filters = { related_field_filters = {
"owners": RelatedFieldFilter("first_name", FilterRelatedOwners) "owners": RelatedFieldFilter("first_name", FilterRelatedOwners),
"created_by": RelatedFieldFilter("first_name", FilterRelatedOwners),
} }
allowed_rel_fields = {"owners"} allowed_rel_fields = {"owners", "created_by"}
def __init__(self) -> None: def __init__(self) -> None:
if is_feature_enabled("THUMBNAILS"): if is_feature_enabled("THUMBNAILS"):

View File

@@ -48,6 +48,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
slice_name: str, slice_name: str,
owners: List[int], owners: List[int],
datasource_id: int, datasource_id: int,
created_by=None,
datasource_type: str = "table", datasource_type: str = "table",
description: Optional[str] = None, description: Optional[str] = None,
viz_type: Optional[str] = None, viz_type: Optional[str] = None,
@@ -62,15 +63,16 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
datasource_type, datasource_id, db.session datasource_type, datasource_id, db.session
) )
slice = Slice( slice = Slice(
slice_name=slice_name, cache_timeout=cache_timeout,
created_by=created_by,
datasource_id=datasource.id, datasource_id=datasource.id,
datasource_name=datasource.name, datasource_name=datasource.name,
datasource_type=datasource.type, datasource_type=datasource.type,
owners=obj_owners,
description=description, description=description,
viz_type=viz_type, owners=obj_owners,
params=params, params=params,
cache_timeout=cache_timeout, slice_name=slice_name,
viz_type=viz_type,
) )
db.session.add(slice) db.session.add(slice)
db.session.commit() db.session.commit()
@@ -93,12 +95,12 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
""" """
Chart API: Test delete bulk Chart API: Test delete bulk
""" """
admin_id = self.get_user("admin").id admin = self.get_user("admin")
chart_count = 4 chart_count = 4
chart_ids = list() chart_ids = list()
for chart_name_index in range(chart_count): for chart_name_index in range(chart_count):
chart_ids.append( chart_ids.append(
self.insert_chart(f"title{chart_name_index}", [admin_id], 1).id self.insert_chart(f"title{chart_name_index}", [admin.id], 1, admin).id
) )
self.login(username="admin") self.login(username="admin")
argument = chart_ids argument = chart_ids
@@ -365,7 +367,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
admin = self.get_user("admin") admin = self.get_user("admin")
gamma = self.get_user("gamma") gamma = self.get_user("gamma")
chart_id = self.insert_chart("title", [admin.id], 1).id chart_id = self.insert_chart("title", [admin.id], 1, admin).id
birth_names_table_id = SupersetTestCase.get_table_by_name("birth_names").id birth_names_table_id = SupersetTestCase.get_table_by_name("birth_names").id
chart_data = { chart_data = {
"slice_name": "title1_changed", "slice_name": "title1_changed",
@@ -384,6 +386,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
self.assertEqual(rv.status_code, 200) self.assertEqual(rv.status_code, 200)
model = db.session.query(Slice).get(chart_id) model = db.session.query(Slice).get(chart_id)
related_dashboard = db.session.query(Dashboard).get(1) related_dashboard = db.session.query(Dashboard).get(1)
self.assertEqual(model.created_by, admin)
self.assertEqual(model.slice_name, "title1_changed") self.assertEqual(model.slice_name, "title1_changed")
self.assertEqual(model.description, "description1") self.assertEqual(model.description, "description1")
self.assertIn(admin, model.owners) self.assertIn(admin, model.owners)
@@ -902,7 +905,9 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
self.assertEqual(rv.status_code, 400) self.assertEqual(rv.status_code, 400)
def test_chart_data_with_invalid_datasource(self): def test_chart_data_with_invalid_datasource(self):
"""Chart data API: Test chart data query with invalid schema""" """
Chart data API: Test chart data query with invalid schema
"""
self.login(username="admin") self.login(username="admin")
table = self.get_table_by_name("birth_names") table = self.get_table_by_name("birth_names")
payload = get_query_context(table.name, table.id, table.type) payload = get_query_context(table.name, table.id, table.type)
@@ -911,7 +916,9 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
self.assertEqual(rv.status_code, 400) self.assertEqual(rv.status_code, 400)
def test_chart_data_with_invalid_enum_value(self): def test_chart_data_with_invalid_enum_value(self):
"""Chart data API: Test chart data query with invalid enum value""" """
Chart data API: Test chart data query with invalid enum value
"""
self.login(username="admin") self.login(username="admin")
table = self.get_table_by_name("birth_names") table = self.get_table_by_name("birth_names")
payload = get_query_context(table.name, table.id, table.type) payload = get_query_context(table.name, table.id, table.type)