feat: filter by me on CRUD list view (#11683)

This commit is contained in:
Lily Kuang 2020-11-25 11:56:48 -08:00 committed by GitHub
parent c354e7e0ab
commit 9c69679e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 135 additions and 12 deletions

View File

@ -36,6 +36,16 @@ describe('chart card view filters', () => {
cy.get('[data-test="styled-card"]').should('not.exist'); 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', () => { it('should filter by created by correctly', () => {
// filter by created by // filter by created by
cy.get('.Select__control').eq(1).click(); 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'); 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', () => { it('should filter by created by correctly', () => {
// filter by created by // filter by created by
cy.get('.Select__control').eq(1).click(); cy.get('.Select__control').eq(1).click();

View File

@ -36,6 +36,16 @@ describe('dashboard filters card view', () => {
cy.get('[data-test="styled-card"]').should('not.exist'); 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', () => { it('should filter by created by correctly', () => {
// filter by created by // filter by created by
cy.get('.Select__control').eq(1).click(); 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'); 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', () => { it('should filter by created by correctly', () => {
// filter by created by // filter by created by
cy.get('.Select__control').eq(1).click(); cy.get('.Select__control').eq(1).click();

View File

@ -55,6 +55,10 @@ const mocklayers = [...new Array(3)].map((_, i) => ({
desc: 'layer description', desc: 'layer description',
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(layersInfoEndpoint, { fetchMock.get(layersInfoEndpoint, {
permissions: ['can_delete'], permissions: ['can_delete'],
}); });
@ -74,7 +78,9 @@ fetchMock.get(layersRelatedEndpoint, {
}); });
describe('AnnotationLayersList', () => { describe('AnnotationLayersList', () => {
const wrapper = mount(<AnnotationLayersList />, { context: { store } }); const wrapper = mount(<AnnotationLayersList user={mockUser} />, {
context: { store },
});
beforeAll(async () => { beforeAll(async () => {
await waitForComponentToPaint(wrapper); await waitForComponentToPaint(wrapper);

View File

@ -36,9 +36,11 @@ const store = mockStore({});
const chartsInfoEndpoint = 'glob:*/api/v1/chart/_info*'; const chartsInfoEndpoint = 'glob:*/api/v1/chart/_info*';
const chartssOwnersEndpoint = 'glob:*/api/v1/chart/related/owners*'; const chartssOwnersEndpoint = 'glob:*/api/v1/chart/related/owners*';
const chartsCreatedByEndpoint = 'glob:*/api/v1/chart/related/created_by*';
const chartsEndpoint = 'glob:*/api/v1/chart/?*'; const chartsEndpoint = 'glob:*/api/v1/chart/?*';
const chartsVizTypesEndpoint = 'glob:*/api/v1/chart/viz_types'; 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) => ({ const mockCharts = [...new Array(3)].map((_, i) => ({
changed_on: new Date().toISOString(), changed_on: new Date().toISOString(),
@ -51,6 +53,10 @@ const mockCharts = [...new Array(3)].map((_, i) => ({
thumbnail_url: '/thumbnail', thumbnail_url: '/thumbnail',
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(chartsInfoEndpoint, { fetchMock.get(chartsInfoEndpoint, {
permissions: ['can_list', 'can_edit', 'can_delete'], permissions: ['can_list', 'can_edit', 'can_delete'],
}); });
@ -58,6 +64,12 @@ fetchMock.get(chartsInfoEndpoint, {
fetchMock.get(chartssOwnersEndpoint, { fetchMock.get(chartssOwnersEndpoint, {
result: [], result: [],
}); });
fetchMock.get(chartsCreatedByEndpoint, {
result: [],
});
fetchMock.get(chartFavoriteStatusEndpoint, {
result: [],
});
fetchMock.get(chartsEndpoint, { fetchMock.get(chartsEndpoint, {
result: mockCharts, result: mockCharts,
chart_count: 3, chart_count: 3,
@ -68,7 +80,7 @@ fetchMock.get(chartsVizTypesEndpoint, {
count: 0, count: 0,
}); });
fetchMock.get(chartsDtasourcesEndpoint, { fetchMock.get(chartsDatasourcesEndpoint, {
result: [], result: [],
count: 0, count: 0,
}); });
@ -85,7 +97,7 @@ describe('ChartList', () => {
isFeatureEnabledMock.restore(); isFeatureEnabledMock.restore();
}); });
const mockedProps = {}; const mockedProps = {};
const wrapper = mount(<ChartList {...mockedProps} />, { const wrapper = mount(<ChartList {...mockedProps} user={mockUser} />, {
context: { store }, context: { store },
}); });

View File

@ -53,6 +53,10 @@ const mocktemplates = [...new Array(3)].map((_, i) => ({
template_name: `template ${i}`, template_name: `template ${i}`,
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(templatesInfoEndpoint, { fetchMock.get(templatesInfoEndpoint, {
permissions: ['can_delete'], permissions: ['can_delete'],
}); });
@ -72,7 +76,9 @@ fetchMock.get(templatesRelatedEndpoint, {
}); });
describe('CssTemplatesList', () => { describe('CssTemplatesList', () => {
const wrapper = mount(<CssTemplatesList />, { context: { store } }); const wrapper = mount(<CssTemplatesList user={mockUser} />, {
context: { store },
});
beforeAll(async () => { beforeAll(async () => {
await waitForComponentToPaint(wrapper); await waitForComponentToPaint(wrapper);

View File

@ -37,6 +37,10 @@ const store = mockStore({});
const dashboardsInfoEndpoint = 'glob:*/api/v1/dashboard/_info*'; const dashboardsInfoEndpoint = 'glob:*/api/v1/dashboard/_info*';
const dashboardOwnersEndpoint = 'glob:*/api/v1/dashboard/related/owners*'; 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 dashboardsEndpoint = 'glob:*/api/v1/dashboard/?*';
const mockDashboards = [...new Array(3)].map((_, i) => ({ const mockDashboards = [...new Array(3)].map((_, i) => ({
@ -53,12 +57,23 @@ const mockDashboards = [...new Array(3)].map((_, i) => ({
thumbnail_url: '/thumbnail', thumbnail_url: '/thumbnail',
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(dashboardsInfoEndpoint, { fetchMock.get(dashboardsInfoEndpoint, {
permissions: ['can_list', 'can_edit', 'can_delete'], permissions: ['can_list', 'can_edit', 'can_delete'],
}); });
fetchMock.get(dashboardOwnersEndpoint, { fetchMock.get(dashboardOwnersEndpoint, {
result: [], result: [],
}); });
fetchMock.get(dashboardCreatedByEndpoint, {
result: [],
});
fetchMock.get(dashboardFavoriteStatusEndpoint, {
result: [],
});
fetchMock.get(dashboardsEndpoint, { fetchMock.get(dashboardsEndpoint, {
result: mockDashboards, result: mockDashboards,
dashboard_count: 3, dashboard_count: 3,
@ -77,7 +92,7 @@ describe('DashboardList', () => {
}); });
const mockedProps = {}; const mockedProps = {};
const wrapper = mount(<DashboardList {...mockedProps} />, { const wrapper = mount(<DashboardList {...mockedProps} user={mockUser} />, {
context: { store }, context: { store },
}); });

View File

@ -56,6 +56,10 @@ const mockdatabases = [...new Array(3)].map((_, i) => ({
id: i, id: i,
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(databasesInfoEndpoint, { fetchMock.get(databasesInfoEndpoint, {
permissions: ['can_delete'], permissions: ['can_delete'],
}); });
@ -77,7 +81,9 @@ fetchMock.get(databaseRelatedEndpoint, {
}); });
describe('DatabaseList', () => { describe('DatabaseList', () => {
const wrapper = mount(<DatabaseList />, { context: { store } }); const wrapper = mount(<DatabaseList user={mockUser} />, {
context: { store },
});
beforeAll(async () => { beforeAll(async () => {
await waitForComponentToPaint(wrapper); await waitForComponentToPaint(wrapper);

View File

@ -52,6 +52,10 @@ const mockdatasets = [...new Array(3)].map((_, i) => ({
table_name: `coolest table ${i}`, table_name: `coolest table ${i}`,
})); }));
const mockUser = {
userId: 1,
};
fetchMock.get(datasetsInfoEndpoint, { fetchMock.get(datasetsInfoEndpoint, {
permissions: ['can_list', 'can_edit', 'can_add', 'can_delete'], permissions: ['can_list', 'can_edit', 'can_add', 'can_delete'],
}); });
@ -70,7 +74,7 @@ fetchMock.get(databaseEndpoint, {
}); });
async function mountAndWait(props) { async function mountAndWait(props) {
const mounted = mount(<DatasetList {...props} />, { const mounted = mount(<DatasetList {...props} user={mockUser} />, {
context: { store }, context: { store },
}); });
await waitForComponentToPaint(mounted); await waitForComponentToPaint(mounted);

View File

@ -91,7 +91,9 @@ fetchMock.get(queriesDistinctEndpoint, {
}); });
describe('SavedQueryList', () => { describe('SavedQueryList', () => {
const wrapper = mount(<SavedQueryList />, { context: { store } }); const wrapper = mount(<SavedQueryList />, {
context: { store },
});
beforeAll(async () => { beforeAll(async () => {
await waitForComponentToPaint(wrapper); await waitForComponentToPaint(wrapper);

View File

@ -41,11 +41,15 @@ const MOMENT_FORMAT = 'MMM DD, YYYY';
interface AnnotationLayersListProps { interface AnnotationLayersListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
function AnnotationLayersList({ function AnnotationLayersList({
addDangerToast, addDangerToast,
addSuccessToast, addSuccessToast,
user,
}: AnnotationLayersListProps) { }: AnnotationLayersListProps) {
const { const {
state: { state: {
@ -293,6 +297,7 @@ function AnnotationLayersList({
errMsg, errMsg,
), ),
), ),
user.userId,
), ),
paginate: true, paginate: true,
}, },

View File

@ -90,6 +90,9 @@ const createFetchDatasets = (handleError: (err: Response) => void) => async (
interface ChartListProps { interface ChartListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
function ChartList(props: ChartListProps) { function ChartList(props: ChartListProps) {
@ -346,6 +349,7 @@ function ChartList(props: ChartListProps) {
), ),
), ),
), ),
props.user.userId,
), ),
paginate: true, paginate: true,
}, },
@ -366,6 +370,7 @@ function ChartList(props: ChartListProps) {
), ),
), ),
), ),
props.user.userId,
), ),
paginate: true, paginate: true,
}, },

View File

@ -40,11 +40,15 @@ const PAGE_SIZE = 25;
interface CssTemplatesListProps { interface CssTemplatesListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
function CssTemplatesList({ function CssTemplatesList({
addDangerToast, addDangerToast,
addSuccessToast, addSuccessToast,
user,
}: CssTemplatesListProps) { }: CssTemplatesListProps) {
const { const {
state: { state: {
@ -280,6 +284,7 @@ function CssTemplatesList({
errMsg, errMsg,
), ),
), ),
user.userId,
), ),
paginate: true, paginate: true,
}, },

View File

@ -46,6 +46,9 @@ const PAGE_SIZE = 25;
interface DashboardListProps { interface DashboardListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
interface Dashboard { interface Dashboard {
@ -333,6 +336,7 @@ function DashboardList(props: DashboardListProps) {
), ),
), ),
), ),
props.user.userId,
), ),
paginate: true, paginate: true,
}, },
@ -353,6 +357,7 @@ function DashboardList(props: DashboardListProps) {
), ),
), ),
), ),
props.user.userId,
), ),
paginate: true, paginate: true,
}, },

View File

@ -78,11 +78,15 @@ type Dataset = {
interface DatasetListProps { interface DatasetListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
const DatasetList: FunctionComponent<DatasetListProps> = ({ const DatasetList: FunctionComponent<DatasetListProps> = ({
addDangerToast, addDangerToast,
addSuccessToast, addSuccessToast,
user,
}) => { }) => {
const { const {
state: { state: {
@ -366,6 +370,7 @@ const DatasetList: FunctionComponent<DatasetListProps> = ({
errMsg, errMsg,
), ),
), ),
user.userId,
), ),
paginate: true, paginate: true,
}, },

View File

@ -47,6 +47,9 @@ const PAGE_SIZE = 25;
interface SavedQueryListProps { interface SavedQueryListProps {
addDangerToast: (msg: string) => void; addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void; addSuccessToast: (msg: string) => void;
user: {
userId: string | number;
};
} }
const StyledTableLabel = styled.div` const StyledTableLabel = styled.div`
@ -65,6 +68,7 @@ const StyledPopoverItem = styled.div`
function SavedQueryList({ function SavedQueryList({
addDangerToast, addDangerToast,
addSuccessToast, addSuccessToast,
user,
}: SavedQueryListProps) { }: SavedQueryListProps) {
const { const {
state: { state: {

View File

@ -33,9 +33,11 @@ const createFetchResourceMethod = (method: string) => (
resource: string, resource: string,
relation: string, relation: string,
handleError: (error: Response) => void, handleError: (error: Response) => void,
userId?: string | number,
) => async (filterValue = '', pageIndex?: number, pageSize?: number) => { ) => async (filterValue = '', pageIndex?: number, pageSize?: number) => {
const resourceEndpoint = `/api/v1/${resource}/${method}/${relation}`; const resourceEndpoint = `/api/v1/${resource}/${method}/${relation}`;
const options =
userId && pageIndex === 0 ? [{ label: 'me', value: userId }] : [];
try { try {
const queryParams = rison.encode({ const queryParams = rison.encode({
...(pageIndex ? { page: pageIndex } : {}), ...(pageIndex ? { page: pageIndex } : {}),
@ -45,13 +47,14 @@ const createFetchResourceMethod = (method: string) => (
const { json = {} } = await SupersetClient.get({ const { json = {} } = await SupersetClient.get({
endpoint: `${resourceEndpoint}?q=${queryParams}`, endpoint: `${resourceEndpoint}?q=${queryParams}`,
}); });
const data = json?.result?.map(
return json?.result?.map(
({ text: label, value }: { text: string; value: any }) => ({ ({ text: label, value }: { text: string; value: any }) => ({
label, label,
value, value,
}), }),
); );
return options.concat(data);
} catch (e) { } catch (e) {
handleError(e); handleError(e);
} }