diff --git a/public/app/features/dashboard/create_folder_ctrl.ts b/public/app/features/dashboard/create_folder_ctrl.ts index f3d9167278b..0c582164e2b 100644 --- a/public/app/features/dashboard/create_folder_ctrl.ts +++ b/public/app/features/dashboard/create_folder_ctrl.ts @@ -27,7 +27,7 @@ export class CreateFolderCtrl { this.titleTouched = true; this.validationSrv - .validateNewDashboardOrFolderName(this.title) + .validateNewFolderName(this.title) .then(() => { this.hasValidationError = false; }) diff --git a/public/app/features/dashboard/dashboard_import_ctrl.ts b/public/app/features/dashboard/dashboard_import_ctrl.ts index 86fe12eab8a..c3af0a51a19 100644 --- a/public/app/features/dashboard/dashboard_import_ctrl.ts +++ b/public/app/features/dashboard/dashboard_import_ctrl.ts @@ -93,7 +93,7 @@ export class DashboardImportCtrl { this.nameExists = false; this.validationSrv - .validateNewDashboardOrFolderName(this.dash.title) + .validateNewDashboardName(0, this.dash.title) .then(() => { this.hasNameValidationError = false; }) diff --git a/public/app/features/dashboard/folder_picker/folder_picker.ts b/public/app/features/dashboard/folder_picker/folder_picker.ts index 5eb3d094641..56284a877c5 100644 --- a/public/app/features/dashboard/folder_picker/folder_picker.ts +++ b/public/app/features/dashboard/folder_picker/folder_picker.ts @@ -67,7 +67,7 @@ export class FolderPickerCtrl { this.newFolderNameTouched = true; this.validationSrv - .validateNewDashboardOrFolderName(this.newFolderName) + .validateNewFolderName(this.newFolderName) .then(() => { this.hasValidationError = false; }) diff --git a/public/app/features/dashboard/specs/dashboard_import_ctrl.jest.ts b/public/app/features/dashboard/specs/dashboard_import_ctrl.jest.ts index 739485b235d..3d311b8b4f8 100644 --- a/public/app/features/dashboard/specs/dashboard_import_ctrl.jest.ts +++ b/public/app/features/dashboard/specs/dashboard_import_ctrl.jest.ts @@ -19,7 +19,7 @@ describe('DashboardImportCtrl', function() { }; validationSrv = { - validateNewDashboardOrFolderName: jest.fn().mockReturnValue(Promise.resolve()), + validateNewDashboardName: jest.fn().mockReturnValue(Promise.resolve()), }; ctx.ctrl = new DashboardImportCtrl(backendSrv, validationSrv, navModelSrv, {}, {}, {}); diff --git a/public/app/features/dashboard/validation_srv.ts b/public/app/features/dashboard/validation_srv.ts index 8460f4efa71..817be7ca0e3 100644 --- a/public/app/features/dashboard/validation_srv.ts +++ b/public/app/features/dashboard/validation_srv.ts @@ -1,13 +1,27 @@ import coreModule from 'app/core/core_module'; +const hitTypes = { + FOLDER: 'dash-folder', + DASHBOARD: 'dash-db', +}; + export class ValidationSrv { rootName = 'general'; /** @ngInject */ constructor(private $q, private backendSrv) {} - validateNewDashboardOrFolderName(name) { + validateNewDashboardName(folderId, name) { + return this.validate(folderId, name, 'A dashboard in this folder with the same name already exists'); + } + + validateNewFolderName(name) { + return this.validate(0, name, 'A folder or dashboard in the general folder with the same name already exists'); + } + + private validate(folderId, name, existingErrorMessage) { name = (name || '').trim(); + const nameLowerCased = name.toLowerCase(); if (name.length === 0) { return this.$q.reject({ @@ -16,7 +30,7 @@ export class ValidationSrv { }); } - if (name.toLowerCase() === this.rootName) { + if (folderId === 0 && nameLowerCased === this.rootName) { return this.$q.reject({ type: 'EXISTING', message: 'This is a reserved name and cannot be used for a folder.', @@ -25,12 +39,26 @@ export class ValidationSrv { let deferred = this.$q.defer(); - this.backendSrv.search({ query: name }).then(res => { - for (let hit of res) { - if (name.toLowerCase() === hit.title.toLowerCase()) { + const promises = []; + promises.push(this.backendSrv.search({ type: hitTypes.FOLDER, folderIds: [folderId], query: name })); + promises.push(this.backendSrv.search({ type: hitTypes.DASHBOARD, folderIds: [folderId], query: name })); + + this.$q.all(promises).then(res => { + let hits = []; + + if (res.length > 0 && res[0].length > 0) { + hits = res[0]; + } + + if (res.length > 1 && res[1].length > 0) { + hits = hits.concat(res[1]); + } + + for (let hit of hits) { + if (nameLowerCased === hit.title.toLowerCase()) { deferred.reject({ type: 'EXISTING', - message: 'A folder or dashboard with the same name already exists', + message: existingErrorMessage, }); break; }