diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap index 3a03c5c01b3c2..ea86ea58faf61 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap @@ -101,8 +101,11 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = ` }, ] } + onTableChange={[Function]} pagination={ Object { + "pageIndex": 0, + "pageSize": 5, "pageSizeOptions": Array [ 5, 10, @@ -246,6 +249,10 @@ exports[`Flyout conflicts should allow conflict resolution 2`] = ` "newIndexPatternId": "2", }, ], + "unmatchedReferencesTablePagination": Object { + "pageIndex": 0, + "pageSize": 5, + }, }, }, ], @@ -403,8 +410,11 @@ exports[`Flyout legacy conflicts should allow conflict resolution 1`] = ` }, ] } + onTableChange={[Function]} pagination={ Object { + "pageIndex": 0, + "pageSize": 5, "pageSizeOptions": Array [ 5, 10, diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx index 3165ea4ca0794..75792becc29d8 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx @@ -88,6 +88,7 @@ export interface FlyoutState { conflictedSavedObjectsLinkedToSavedSearches?: any[]; conflictedSearchDocs?: any[]; unmatchedReferences?: ProcessedImportResponse['unmatchedReferences']; + unmatchedReferencesTablePagination: { pageIndex: number; pageSize: number }; failedImports?: ProcessedImportResponse['failedImports']; successfulImports?: ProcessedImportResponse['successfulImports']; conflictingRecord?: ConflictingRecord; @@ -115,6 +116,10 @@ export class Flyout extends Component { conflictedSavedObjectsLinkedToSavedSearches: undefined, conflictedSearchDocs: undefined, unmatchedReferences: undefined, + unmatchedReferencesTablePagination: { + pageIndex: 0, + pageSize: 5, + }, conflictingRecord: undefined, error: undefined, file: undefined, @@ -467,7 +472,7 @@ export class Flyout extends Component { }; renderUnmatchedReferences() { - const { unmatchedReferences } = this.state; + const { unmatchedReferences, unmatchedReferencesTablePagination: tablePagination } = this.state; if (!unmatchedReferences) { return null; @@ -527,22 +532,28 @@ export class Flyout extends Component { { defaultMessage: 'New index pattern' } ), render: (id: string) => { - const options = this.state.indexPatterns!.map( - (indexPattern) => - ({ - text: indexPattern.title, - value: indexPattern.id, - 'data-test-subj': `indexPatternOption-${indexPattern.title}`, - } as { text: string; value: string; 'data-test-subj'?: string }) - ); - - options.unshift({ - text: '-- Skip Import --', - value: '', - }); + const options = [ + { + text: '-- Skip Import --', + value: '', + }, + ...this.state.indexPatterns!.map( + (indexPattern) => + ({ + text: indexPattern.title, + value: indexPattern.id, + 'data-test-subj': `indexPatternOption-${indexPattern.title}`, + } as { text: string; value: string; 'data-test-subj'?: string }) + ), + ]; + + const selectedValue = + unmatchedReferences?.find((unmatchedRef) => unmatchedRef.existingIndexPatternId === id) + ?.newIndexPatternId ?? ''; return ( this.onIndexChanged(id, e)} options={options} @@ -553,6 +564,7 @@ export class Flyout extends Component { ]; const pagination = { + ...tablePagination, pageSizeOptions: [5, 10, 25], }; @@ -561,6 +573,16 @@ export class Flyout extends Component { items={unmatchedReferences as any[]} columns={columns} pagination={pagination} + onTableChange={({ page }) => { + if (page) { + this.setState({ + unmatchedReferencesTablePagination: { + pageSize: page.size, + pageIndex: page.index, + }, + }); + } + }} /> ); } diff --git a/test/functional/apps/management/_import_objects.ts b/test/functional/apps/management/_import_objects.ts index 0b417d7d23e93..ddabb32bf5909 100644 --- a/test/functional/apps/management/_import_objects.ts +++ b/test/functional/apps/management/_import_objects.ts @@ -421,21 +421,40 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(isSavedObjectImported).to.be(true); }); - it('should import saved objects with index patterns when index patterns does not exists', async () => { - // First, we need to delete the index pattern - await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*'); - await PageObjects.savedObjects.clickDelete(); - - // Then, import the objects + it('should preserve index patterns selection when switching between pages', async () => { await PageObjects.savedObjects.importFile( - path.join(__dirname, 'exports', '_import_objects_with_index_patterns.json') + path.join(__dirname, 'exports', '_import_objects_missing_all_index_patterns.json') ); - await PageObjects.savedObjects.checkImportSucceeded(); - await PageObjects.savedObjects.clickImportDone(); - const objects = await PageObjects.savedObjects.getRowTitles(); - const isSavedObjectImported = objects.includes('saved object imported with index pattern'); - expect(isSavedObjectImported).to.be(true); + await PageObjects.savedObjects.setOverriddenIndexPatternValue( + 'missing-index-pattern-1', + 'index-pattern-test-1' + ); + + await testSubjects.click('pagination-button-next'); + + await PageObjects.savedObjects.setOverriddenIndexPatternValue( + 'missing-index-pattern-7', + 'index-pattern-test-2' + ); + + await testSubjects.click('pagination-button-previous'); + + const selectedIdForMissingIndexPattern1 = await testSubjects.getAttribute( + 'managementChangeIndexSelection-missing-index-pattern-1', + 'value' + ); + + expect(selectedIdForMissingIndexPattern1).to.eql('f1e4c910-a2e6-11e7-bb30-233be9be6a20'); + + await testSubjects.click('pagination-button-next'); + + const selectedIdForMissingIndexPattern7 = await testSubjects.getAttribute( + 'managementChangeIndexSelection-missing-index-pattern-7', + 'value' + ); + + expect(selectedIdForMissingIndexPattern7).to.eql('f1e4c910-a2e6-11e7-bb30-233be9be6a87'); }); }); }); diff --git a/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json b/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json new file mode 100644 index 0000000000000..45572b0bf34fe --- /dev/null +++ b/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json @@ -0,0 +1,121 @@ +[ + { + "_id": "test-vis-1", + "_type": "visualization", + "_source": { + "title": "Test VIS 1", + "visState": "{\"title\":\"test vis 1\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-1\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-2", + "_type": "visualization", + "_source": { + "title": "Test VIS 2", + "visState": "{\"title\":\"test vis 2\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-2\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-3", + "_type": "visualization", + "_source": { + "title": "Test VIS 3", + "visState": "{\"title\":\"test vis 3\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-3\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-4", + "_type": "visualization", + "_source": { + "title": "Test VIS 4", + "visState": "{\"title\":\"test vis 4\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-4\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-5", + "_type": "visualization", + "_source": { + "title": "Test VIS 5", + "visState": "{\"title\":\"test vis 5\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-5\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-6", + "_type": "visualization", + "_source": { + "title": "Test VIS 6", + "visState": "{\"title\":\"test vis 6\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-6\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-7", + "_type": "visualization", + "_source": { + "title": "Test VIS 7", + "visState": "{\"title\":\"test vis 7\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-7\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + } +] diff --git a/test/functional/page_objects/management/saved_objects_page.ts b/test/functional/page_objects/management/saved_objects_page.ts index 8e65b6488836c..0742f14b2eeb4 100644 --- a/test/functional/page_objects/management/saved_objects_page.ts +++ b/test/functional/page_objects/management/saved_objects_page.ts @@ -126,6 +126,12 @@ export function SavedObjectsPageProvider({ getService, getPageObjects }: FtrProv } } + async setOverriddenIndexPatternValue(oldName: string, newName: string) { + const select = await testSubjects.find(`managementChangeIndexSelection-${oldName}`); + const option = await testSubjects.findDescendant(`indexPatternOption-${newName}`, select); + await option.click(); + } + async clickCopyToSpaceByTitle(title: string) { const table = keyBy(await this.getElementsInTable(), 'title'); // should we check if table size > 0 and log error if not?