mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Began work on improving structure and organization of components under features/dashboard, #14062
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
import _ from 'lodash';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import appEvents from 'app/core/app_events';
|
||||
|
||||
export class FolderPickerCtrl {
|
||||
initialTitle: string;
|
||||
initialFolderId?: number;
|
||||
labelClass: string;
|
||||
onChange: any;
|
||||
onLoad: any;
|
||||
onCreateFolder: any;
|
||||
enterFolderCreation: any;
|
||||
exitFolderCreation: any;
|
||||
enableCreateNew: boolean;
|
||||
enableReset: boolean;
|
||||
rootName = 'General';
|
||||
folder: any;
|
||||
createNewFolder: boolean;
|
||||
newFolderName: string;
|
||||
newFolderNameTouched: boolean;
|
||||
hasValidationError: boolean;
|
||||
validationError: any;
|
||||
isEditor: boolean;
|
||||
dashboardId?: number;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private validationSrv, private contextSrv) {
|
||||
this.isEditor = this.contextSrv.isEditor;
|
||||
|
||||
if (!this.labelClass) {
|
||||
this.labelClass = 'width-7';
|
||||
}
|
||||
|
||||
this.loadInitialValue();
|
||||
}
|
||||
|
||||
getOptions(query) {
|
||||
const params = {
|
||||
query: query,
|
||||
type: 'dash-folder',
|
||||
permission: 'Edit',
|
||||
};
|
||||
|
||||
return this.backendSrv.get('api/search', params).then(result => {
|
||||
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) {
|
||||
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 => {
|
||||
this.hasValidationError = true;
|
||||
this.validationError = err.message;
|
||||
});
|
||||
}
|
||||
|
||||
createFolder(evt) {
|
||||
if (evt) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
return this.backendSrv.createFolder({ title: this.newFolderName }).then(result => {
|
||||
appEvents.emit('alert-success', ['Folder Created', 'OK']);
|
||||
|
||||
this.closeCreateFolder();
|
||||
this.folder = { text: result.title, value: result.id };
|
||||
this.onFolderChange(this.folder);
|
||||
});
|
||||
}
|
||||
|
||||
cancelCreateFolder(evt) {
|
||||
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: this.initialTitle, value: null };
|
||||
const rootFolder = { text: this.rootName, value: 0 };
|
||||
|
||||
this.getOptions('').then(result => {
|
||||
let folder;
|
||||
if (this.initialFolderId) {
|
||||
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);
|
||||
@@ -0,0 +1 @@
|
||||
export { FolderPickerCtrl } from './FolderPickerCtrl';
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label {{ctrl.labelClass}}">Folder</label>
|
||||
<div class="dropdown" ng-hide="ctrl.createNewFolder">
|
||||
<gf-form-dropdown model="ctrl.folder"
|
||||
get-options="ctrl.getOptions($query)"
|
||||
on-change="ctrl.onFolderChange($option)">
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
<input type="text"
|
||||
class="gf-form-input max-width-10"
|
||||
ng-if="ctrl.createNewFolder"
|
||||
give-focus="ctrl.createNewFolder"
|
||||
ng-model="ctrl.newFolderName"
|
||||
ng-model-options="{ debounce: 400 }"
|
||||
ng-change="ctrl.newFolderNameChanged()" />
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.createNewFolder">
|
||||
<button class="btn btn-inverse"
|
||||
ng-click="ctrl.createFolder($event)"
|
||||
ng-disabled="!ctrl.newFolderNameTouched || ctrl.hasValidationError">
|
||||
<i class="fa fa-fw fa-save"></i> Create
|
||||
</button>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.createNewFolder">
|
||||
<button class="btn btn-inverse" ng-click="ctrl.cancelCreateFolder($event)">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-inline" ng-if="ctrl.newFolderNameTouched && ctrl.hasValidationError">
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label text-warning gf-form-label--grow">
|
||||
<i class="fa fa-warning"></i>
|
||||
{{ctrl.validationError}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user