diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts index a70ccaa463..ba68ce88e8 100644 --- a/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/chart_list/filter.test.ts @@ -36,6 +36,16 @@ describe('chart card view filters', () => { cy.get('[data-test="styled-card"]').should('not.exist'); }); + it('should filter by me correctly', () => { + // filter by me + cy.get('.Select__control').first().click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="styled-card"]').its('length').should('be.gt', 0); + cy.get('.Select__control').eq(1).click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="styled-card"]').its('length').should('be.gt', 0); + }); + it('should filter by created by correctly', () => { // filter by created by cy.get('.Select__control').eq(1).click(); @@ -94,6 +104,16 @@ describe('chart list view filters', () => { cy.get('[data-test="table-row"]').should('not.exist'); }); + it('should filter by me correctly', () => { + // filter by me + cy.get('.Select__control').first().click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="table-row"]').its('length').should('be.gt', 0); + cy.get('.Select__control').eq(1).click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="table-row"]').its('length').should('be.gt', 0); + }); + it('should filter by created by correctly', () => { // filter by created by cy.get('.Select__control').eq(1).click(); diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts b/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts index 8270bfec6f..506d0b9faf 100644 --- a/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts +++ b/superset-frontend/cypress-base/cypress/integration/dashboard_list/filter.test.ts @@ -36,6 +36,16 @@ describe('dashboard filters card view', () => { cy.get('[data-test="styled-card"]').should('not.exist'); }); + it('should filter by me correctly', () => { + // filter by me + cy.get('.Select__control').first().click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="styled-card"]').its('length').should('be.gt', 0); + cy.get('.Select__control').eq(1).click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="styled-card"]').its('length').should('be.gt', 0); + }); + it('should filter by created by correctly', () => { // filter by created by cy.get('.Select__control').eq(1).click(); @@ -79,6 +89,16 @@ describe('dashboard filters list view', () => { cy.get('[data-test="table-row"]').should('not.exist'); }); + it('should filter by me correctly', () => { + // filter by me + cy.get('.Select__control').first().click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="table-row"]').its('length').should('be.gt', 0); + cy.get('.Select__control').eq(1).click(); + cy.get('.Select__menu').contains('me').click(); + cy.get('[data-test="table-row"]').its('length').should('be.gt', 0); + }); + it('should filter by created by correctly', () => { // filter by created by cy.get('.Select__control').eq(1).click(); diff --git a/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayersList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayersList_spec.jsx index cfe74ffee6..987fc768bc 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayersList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayersList_spec.jsx @@ -55,6 +55,10 @@ const mocklayers = [...new Array(3)].map((_, i) => ({ desc: 'layer description', })); +const mockUser = { + userId: 1, +}; + fetchMock.get(layersInfoEndpoint, { permissions: ['can_delete'], }); @@ -74,7 +78,9 @@ fetchMock.get(layersRelatedEndpoint, { }); describe('AnnotationLayersList', () => { - const wrapper = mount(, { context: { store } }); + const wrapper = mount(, { + context: { store }, + }); beforeAll(async () => { await waitForComponentToPaint(wrapper); diff --git a/superset-frontend/spec/javascripts/views/CRUD/chart/ChartList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/chart/ChartList_spec.jsx index 3abedc37c3..b871421cd3 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/chart/ChartList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/chart/ChartList_spec.jsx @@ -36,9 +36,11 @@ const store = mockStore({}); const chartsInfoEndpoint = 'glob:*/api/v1/chart/_info*'; const chartssOwnersEndpoint = 'glob:*/api/v1/chart/related/owners*'; +const chartsCreatedByEndpoint = 'glob:*/api/v1/chart/related/created_by*'; const chartsEndpoint = 'glob:*/api/v1/chart/?*'; const chartsVizTypesEndpoint = 'glob:*/api/v1/chart/viz_types'; -const chartsDtasourcesEndpoint = 'glob:*/api/v1/chart/datasources'; +const chartsDatasourcesEndpoint = 'glob:*/api/v1/chart/datasources'; +const chartFavoriteStatusEndpoint = 'glob:*/api/v1/chart/favorite_status*'; const mockCharts = [...new Array(3)].map((_, i) => ({ changed_on: new Date().toISOString(), @@ -51,6 +53,10 @@ const mockCharts = [...new Array(3)].map((_, i) => ({ thumbnail_url: '/thumbnail', })); +const mockUser = { + userId: 1, +}; + fetchMock.get(chartsInfoEndpoint, { permissions: ['can_list', 'can_edit', 'can_delete'], }); @@ -58,6 +64,12 @@ fetchMock.get(chartsInfoEndpoint, { fetchMock.get(chartssOwnersEndpoint, { result: [], }); +fetchMock.get(chartsCreatedByEndpoint, { + result: [], +}); +fetchMock.get(chartFavoriteStatusEndpoint, { + result: [], +}); fetchMock.get(chartsEndpoint, { result: mockCharts, chart_count: 3, @@ -68,7 +80,7 @@ fetchMock.get(chartsVizTypesEndpoint, { count: 0, }); -fetchMock.get(chartsDtasourcesEndpoint, { +fetchMock.get(chartsDatasourcesEndpoint, { result: [], count: 0, }); @@ -85,7 +97,7 @@ describe('ChartList', () => { isFeatureEnabledMock.restore(); }); const mockedProps = {}; - const wrapper = mount(, { + const wrapper = mount(, { context: { store }, }); diff --git a/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplatesList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplatesList_spec.jsx index e5b63ab20c..afb53d30a6 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplatesList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplatesList_spec.jsx @@ -53,6 +53,10 @@ const mocktemplates = [...new Array(3)].map((_, i) => ({ template_name: `template ${i}`, })); +const mockUser = { + userId: 1, +}; + fetchMock.get(templatesInfoEndpoint, { permissions: ['can_delete'], }); @@ -72,7 +76,9 @@ fetchMock.get(templatesRelatedEndpoint, { }); describe('CssTemplatesList', () => { - const wrapper = mount(, { context: { store } }); + const wrapper = mount(, { + context: { store }, + }); beforeAll(async () => { await waitForComponentToPaint(wrapper); diff --git a/superset-frontend/spec/javascripts/views/CRUD/dashboard/DashboardList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/dashboard/DashboardList_spec.jsx index bdbd50dd99..42077dd5d7 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/dashboard/DashboardList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/dashboard/DashboardList_spec.jsx @@ -37,6 +37,10 @@ const store = mockStore({}); const dashboardsInfoEndpoint = 'glob:*/api/v1/dashboard/_info*'; const dashboardOwnersEndpoint = 'glob:*/api/v1/dashboard/related/owners*'; +const dashboardCreatedByEndpoint = + 'glob:*/api/v1/dashboard/related/created_by*'; +const dashboardFavoriteStatusEndpoint = + 'glob:*/api/v1/dashboard/favorite_status*'; const dashboardsEndpoint = 'glob:*/api/v1/dashboard/?*'; const mockDashboards = [...new Array(3)].map((_, i) => ({ @@ -53,12 +57,23 @@ const mockDashboards = [...new Array(3)].map((_, i) => ({ thumbnail_url: '/thumbnail', })); +const mockUser = { + userId: 1, +}; + fetchMock.get(dashboardsInfoEndpoint, { permissions: ['can_list', 'can_edit', 'can_delete'], }); fetchMock.get(dashboardOwnersEndpoint, { result: [], }); +fetchMock.get(dashboardCreatedByEndpoint, { + result: [], +}); +fetchMock.get(dashboardFavoriteStatusEndpoint, { + result: [], +}); + fetchMock.get(dashboardsEndpoint, { result: mockDashboards, dashboard_count: 3, @@ -77,7 +92,7 @@ describe('DashboardList', () => { }); const mockedProps = {}; - const wrapper = mount(, { + const wrapper = mount(, { context: { store }, }); diff --git a/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx index 7d802841ab..471072803b 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/data/database/DatabaseList_spec.jsx @@ -56,6 +56,10 @@ const mockdatabases = [...new Array(3)].map((_, i) => ({ id: i, })); +const mockUser = { + userId: 1, +}; + fetchMock.get(databasesInfoEndpoint, { permissions: ['can_delete'], }); @@ -77,7 +81,9 @@ fetchMock.get(databaseRelatedEndpoint, { }); describe('DatabaseList', () => { - const wrapper = mount(, { context: { store } }); + const wrapper = mount(, { + context: { store }, + }); beforeAll(async () => { await waitForComponentToPaint(wrapper); diff --git a/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx index ae6be2e7a3..b93ea5178f 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/data/dataset/DatasetList_spec.jsx @@ -52,6 +52,10 @@ const mockdatasets = [...new Array(3)].map((_, i) => ({ table_name: `coolest table ${i}`, })); +const mockUser = { + userId: 1, +}; + fetchMock.get(datasetsInfoEndpoint, { permissions: ['can_list', 'can_edit', 'can_add', 'can_delete'], }); @@ -70,7 +74,7 @@ fetchMock.get(databaseEndpoint, { }); async function mountAndWait(props) { - const mounted = mount(, { + const mounted = mount(, { context: { store }, }); await waitForComponentToPaint(mounted); diff --git a/superset-frontend/spec/javascripts/views/CRUD/data/savedquery/SavedQueryList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/data/savedquery/SavedQueryList_spec.jsx index 1420d86cec..daff76b826 100644 --- a/superset-frontend/spec/javascripts/views/CRUD/data/savedquery/SavedQueryList_spec.jsx +++ b/superset-frontend/spec/javascripts/views/CRUD/data/savedquery/SavedQueryList_spec.jsx @@ -91,7 +91,9 @@ fetchMock.get(queriesDistinctEndpoint, { }); describe('SavedQueryList', () => { - const wrapper = mount(, { context: { store } }); + const wrapper = mount(, { + context: { store }, + }); beforeAll(async () => { await waitForComponentToPaint(wrapper); diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx index 11db5b32ed..d066d4dd12 100644 --- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx +++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx @@ -41,11 +41,15 @@ const MOMENT_FORMAT = 'MMM DD, YYYY'; interface AnnotationLayersListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } function AnnotationLayersList({ addDangerToast, addSuccessToast, + user, }: AnnotationLayersListProps) { const { state: { @@ -293,6 +297,7 @@ function AnnotationLayersList({ errMsg, ), ), + user.userId, ), paginate: true, }, diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx index a7e727cf28..e7cf14a855 100644 --- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx +++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx @@ -90,6 +90,9 @@ const createFetchDatasets = (handleError: (err: Response) => void) => async ( interface ChartListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } function ChartList(props: ChartListProps) { @@ -346,6 +349,7 @@ function ChartList(props: ChartListProps) { ), ), ), + props.user.userId, ), paginate: true, }, @@ -366,6 +370,7 @@ function ChartList(props: ChartListProps) { ), ), ), + props.user.userId, ), paginate: true, }, diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx index ef9134754d..5769fee058 100644 --- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx +++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx @@ -40,11 +40,15 @@ const PAGE_SIZE = 25; interface CssTemplatesListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } function CssTemplatesList({ addDangerToast, addSuccessToast, + user, }: CssTemplatesListProps) { const { state: { @@ -280,6 +284,7 @@ function CssTemplatesList({ errMsg, ), ), + user.userId, ), paginate: true, }, diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx index 59853bc21c..8b9f51267a 100644 --- a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx +++ b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx @@ -46,6 +46,9 @@ const PAGE_SIZE = 25; interface DashboardListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } interface Dashboard { @@ -333,6 +336,7 @@ function DashboardList(props: DashboardListProps) { ), ), ), + props.user.userId, ), paginate: true, }, @@ -353,6 +357,7 @@ function DashboardList(props: DashboardListProps) { ), ), ), + props.user.userId, ), paginate: true, }, diff --git a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx index 8cf43458c2..f31da4ce05 100644 --- a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx +++ b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.tsx @@ -78,11 +78,15 @@ type Dataset = { interface DatasetListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } const DatasetList: FunctionComponent = ({ addDangerToast, addSuccessToast, + user, }) => { const { state: { @@ -366,6 +370,7 @@ const DatasetList: FunctionComponent = ({ errMsg, ), ), + user.userId, ), paginate: true, }, diff --git a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx index 0ecac3a270..7215565c09 100644 --- a/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx +++ b/superset-frontend/src/views/CRUD/data/savedquery/SavedQueryList.tsx @@ -47,6 +47,9 @@ const PAGE_SIZE = 25; interface SavedQueryListProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; + user: { + userId: string | number; + }; } const StyledTableLabel = styled.div` @@ -65,6 +68,7 @@ const StyledPopoverItem = styled.div` function SavedQueryList({ addDangerToast, addSuccessToast, + user, }: SavedQueryListProps) { const { state: { diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index 98d3147622..2cc99991c9 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -33,9 +33,11 @@ const createFetchResourceMethod = (method: string) => ( resource: string, relation: string, handleError: (error: Response) => void, + userId?: string | number, ) => async (filterValue = '', pageIndex?: number, pageSize?: number) => { const resourceEndpoint = `/api/v1/${resource}/${method}/${relation}`; - + const options = + userId && pageIndex === 0 ? [{ label: 'me', value: userId }] : []; try { const queryParams = rison.encode({ ...(pageIndex ? { page: pageIndex } : {}), @@ -45,13 +47,14 @@ const createFetchResourceMethod = (method: string) => ( const { json = {} } = await SupersetClient.get({ endpoint: `${resourceEndpoint}?q=${queryParams}`, }); - - return json?.result?.map( + const data = json?.result?.map( ({ text: label, value }: { text: string; value: any }) => ({ label, value, }), ); + + return options.concat(data); } catch (e) { handleError(e); }