grafana/public/app/features/dashboard/components/FolderPicker/FolderPickerCtrl.ts

206 lines
5.8 KiB
TypeScript

import { map, find } from 'lodash';
import { IScope } from 'angular';
import { AppEvents } from '@grafana/data';
import coreModule from 'app/core/core_module';
import appEvents from 'app/core/app_events';
import { backendSrv } from 'app/core/services/backend_srv';
import { ValidationSrv } from 'app/features/manage-dashboards';
import { ContextSrv } from 'app/core/services/context_srv';
import { promiseToDigest } from '../../../../core/utils/promiseToDigest';
import { createFolder } from 'app/features/manage-dashboards/state/actions';
export class FolderPickerCtrl {
declare initialTitle: string;
initialFolderId?: number;
labelClass?: string;
onChange: any;
onLoad: any;
onCreateFolder: any;
enterFolderCreation: any;
exitFolderCreation: any;
declare enableCreateNew: boolean;
declare enableReset: boolean;
rootName = 'General';
folder: any;
createNewFolder?: boolean;
newFolderName?: string;
newFolderNameTouched?: boolean;
hasValidationError?: boolean;
validationError: any;
isEditor: boolean;
dashboardId?: number;
/** @ngInject */
constructor(private validationSrv: ValidationSrv, private contextSrv: ContextSrv, private $scope: IScope) {
this.isEditor = this.contextSrv.isEditor;
if (this.labelClass === undefined) {
this.labelClass = 'width-7';
}
this.loadInitialValue();
}
getOptions(query: string) {
const params = {
query,
type: 'dash-folder',
permission: 'Edit',
};
return promiseToDigest(this.$scope)(
backendSrv.get('api/search', params).then((result: any) => {
if (
this.isEditor &&
(query === '' ||
query.toLowerCase() === 'g' ||
query.toLowerCase() === 'ge' ||
query.toLowerCase() === 'gen' ||
query.toLowerCase() === 'gene' ||
query.toLowerCase() === 'gener' ||
query.toLowerCase() === 'genera' ||
query.toLowerCase() === 'general')
) {
result.unshift({ title: this.rootName, id: 0 });
}
if (this.isEditor && this.enableCreateNew && query === '') {
result.unshift({ title: '-- New folder --', id: -1 });
}
if (this.enableReset && query === '' && this.initialTitle !== '') {
result.unshift({ title: this.initialTitle, id: null });
}
return map(result, (item) => {
return { text: item.title, value: item.id };
});
})
);
}
onFolderChange(option: { value: number; text: string }) {
if (!option) {
option = { value: 0, text: this.rootName };
} else if (option.value === -1) {
this.createNewFolder = true;
this.enterFolderCreation();
return;
}
this.onChange({ $folder: { id: option.value, title: option.text } });
}
newFolderNameChanged() {
this.newFolderNameTouched = true;
this.validationSrv
.validateNewFolderName(this.newFolderName)
.then(() => {
this.hasValidationError = false;
})
.catch((err: any) => {
this.hasValidationError = true;
this.validationError = err.message;
});
}
createFolder(evt: any) {
if (evt) {
evt.stopPropagation();
evt.preventDefault();
}
return promiseToDigest(this.$scope)(
createFolder({ title: this.newFolderName }).then((result: { title: string; id: number }) => {
appEvents.emit(AppEvents.alertSuccess, ['Folder created', 'OK']);
this.closeCreateFolder();
this.folder = { text: result.title, value: result.id };
this.onFolderChange(this.folder);
})
);
}
cancelCreateFolder(evt: any) {
if (evt) {
evt.stopPropagation();
evt.preventDefault();
}
this.closeCreateFolder();
this.loadInitialValue();
}
private closeCreateFolder() {
this.exitFolderCreation();
this.createNewFolder = false;
this.hasValidationError = false;
this.validationError = null;
this.newFolderName = '';
this.newFolderNameTouched = false;
}
private loadInitialValue() {
const resetFolder: { text: string; value: any } = { text: this.initialTitle, value: null };
const rootFolder: { text: string; value: any } = { text: this.rootName, value: 0 };
this.getOptions('').then((result: any[]) => {
let folder: { text: string; value: any } | undefined;
if (this.initialFolderId) {
// @ts-ignore
folder = find(result, { value: this.initialFolderId });
} else if (this.enableReset && this.initialTitle && this.initialFolderId === null) {
folder = resetFolder;
}
if (!folder) {
if (this.isEditor) {
folder = rootFolder;
} else {
// We shouldn't assign a random folder without the user actively choosing it on a persisted dashboard
const isPersistedDashBoard = this.dashboardId ? true : false;
if (isPersistedDashBoard) {
folder = resetFolder;
} else {
folder = result.length > 0 ? result[0] : resetFolder;
}
}
}
this.folder = folder;
// if this is not the same as our initial value notify parent
if (this.folder.value !== this.initialFolderId) {
this.onChange({ $folder: { id: this.folder.value, title: this.folder.text } });
}
});
}
}
export function folderPicker() {
return {
restrict: 'E',
templateUrl: 'public/app/features/dashboard/components/FolderPicker/template.html',
controller: FolderPickerCtrl,
bindToController: true,
controllerAs: 'ctrl',
scope: {
initialTitle: '<',
initialFolderId: '<',
labelClass: '@',
rootName: '@',
onChange: '&',
onCreateFolder: '&',
enterFolderCreation: '&',
exitFolderCreation: '&',
enableCreateNew: '@',
enableReset: '@',
dashboardId: '<?',
},
};
}
coreModule.directive('folderPicker', folderPicker);