mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
dashboard_folders: refactoring picker and folder selection in dashboard settings & save as menu
This commit is contained in:
parent
5b35a21d6f
commit
d9dca72ee4
@ -40,8 +40,8 @@ func GetDashboard(c *middleware.Context) Response {
|
||||
slug := strings.ToLower(c.Params(":slug"))
|
||||
|
||||
query := m.GetDashboardQuery{Slug: slug, OrgId: c.OrgId}
|
||||
err := bus.Dispatch(&query)
|
||||
if err != nil {
|
||||
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return ApiError(404, "Dashboard not found", err)
|
||||
}
|
||||
|
||||
@ -70,27 +70,39 @@ func GetDashboard(c *middleware.Context) Response {
|
||||
creator = getUserLogin(dash.CreatedBy)
|
||||
}
|
||||
|
||||
meta := dtos.DashboardMeta{
|
||||
IsStarred: isStarred,
|
||||
Slug: slug,
|
||||
Type: m.DashTypeDB,
|
||||
CanStar: c.IsSignedIn,
|
||||
CanSave: canSave,
|
||||
CanEdit: canEdit,
|
||||
Created: dash.Created,
|
||||
Updated: dash.Updated,
|
||||
UpdatedBy: updater,
|
||||
CreatedBy: creator,
|
||||
Version: dash.Version,
|
||||
HasAcl: dash.HasAcl,
|
||||
IsFolder: dash.IsFolder,
|
||||
FolderId: dash.ParentId,
|
||||
FolderTitle: "Root",
|
||||
}
|
||||
|
||||
// lookup folder title
|
||||
if dash.ParentId > 0 {
|
||||
query := m.GetDashboardQuery{Id: dash.ParentId, OrgId: c.OrgId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
return ApiError(500, "Dashboard folder could not be read", err)
|
||||
}
|
||||
meta.FolderTitle = query.Result.Title
|
||||
}
|
||||
|
||||
// make sure db version is in sync with json model version
|
||||
dash.Data.Set("version", dash.Version)
|
||||
|
||||
dto := dtos.DashboardFullWithMeta{
|
||||
Dashboard: dash.Data,
|
||||
Meta: dtos.DashboardMeta{
|
||||
IsStarred: isStarred,
|
||||
Slug: slug,
|
||||
Type: m.DashTypeDB,
|
||||
CanStar: c.IsSignedIn,
|
||||
CanSave: canSave,
|
||||
CanEdit: canEdit,
|
||||
Created: dash.Created,
|
||||
Updated: dash.Updated,
|
||||
UpdatedBy: updater,
|
||||
CreatedBy: creator,
|
||||
Version: dash.Version,
|
||||
HasAcl: dash.HasAcl,
|
||||
IsFolder: dash.IsFolder,
|
||||
ParentId: dash.ParentId,
|
||||
},
|
||||
Meta: meta,
|
||||
}
|
||||
|
||||
c.TimeRequest(metrics.M_Api_Dashboard_Get)
|
||||
|
@ -7,23 +7,24 @@ import (
|
||||
)
|
||||
|
||||
type DashboardMeta struct {
|
||||
IsStarred bool `json:"isStarred,omitempty"`
|
||||
IsHome bool `json:"isHome,omitempty"`
|
||||
IsSnapshot bool `json:"isSnapshot,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
CanSave bool `json:"canSave"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanStar bool `json:"canStar"`
|
||||
Slug string `json:"slug"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Version int `json:"version"`
|
||||
HasAcl bool `json:"hasAcl"`
|
||||
IsFolder bool `json:"isFolder"`
|
||||
ParentId int64 `json:"parentId"`
|
||||
IsStarred bool `json:"isStarred,omitempty"`
|
||||
IsHome bool `json:"isHome,omitempty"`
|
||||
IsSnapshot bool `json:"isSnapshot,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
CanSave bool `json:"canSave"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
CanStar bool `json:"canStar"`
|
||||
Slug string `json:"slug"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Version int `json:"version"`
|
||||
HasAcl bool `json:"hasAcl"`
|
||||
IsFolder bool `json:"isFolder"`
|
||||
FolderId int64 `json:"folderId"`
|
||||
FolderTitle string `json:"folderTitle"`
|
||||
}
|
||||
|
||||
type DashboardFullWithMeta struct {
|
||||
|
@ -197,7 +197,7 @@ export class NavModelSrv {
|
||||
clickHandler: () => dashNavCtrl.showHelpModal()
|
||||
});
|
||||
|
||||
if (this.contextSrv.isEditor) {
|
||||
if (this.contextSrv.isEditor && !dashboard.meta.isFolder) {
|
||||
menu.push({
|
||||
title: 'Save As ...',
|
||||
icon: 'fa fa-fw fa-save',
|
||||
|
@ -128,8 +128,10 @@ export class DashboardCtrl {
|
||||
$rootScope.$broadcast("refresh");
|
||||
};
|
||||
|
||||
$scope.onFolderChange = function(parentId) {
|
||||
$scope.dashboard.parentId = parentId;
|
||||
$scope.onFolderChange = function(folder) {
|
||||
$scope.dashboard.parentId = folder.id;
|
||||
$scope.dashboard.meta.folderId = folder.id;
|
||||
$scope.dashboard.meta.folderTitle= folder.title;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,17 +113,8 @@ export class DashboardSrv {
|
||||
}
|
||||
|
||||
showSaveAsModal() {
|
||||
var newScope = this.$rootScope.$new();
|
||||
newScope.clone = this.dash.getSaveModelClone();
|
||||
newScope.clone.editable = true;
|
||||
newScope.clone.hideControls = false;
|
||||
newScope.clone.meta = {};
|
||||
newScope.clone.meta.parentId = this.dash.meta.parentId;
|
||||
newScope.clone.meta.isFolder = this.dash.meta.isFolder;
|
||||
|
||||
this.$rootScope.appEvent('show-modal', {
|
||||
templateHtml: '<save-dashboard-as-modal dismiss="dismiss()"></save-dashboard-as-modal>',
|
||||
scope: newScope,
|
||||
modalClass: 'modal--narrow'
|
||||
});
|
||||
}
|
||||
@ -131,7 +122,6 @@ export class DashboardSrv {
|
||||
showSaveModal() {
|
||||
this.$rootScope.appEvent('show-modal', {
|
||||
templateHtml: '<save-dashboard-modal dismiss="dismiss()"></save-dashboard-modal>',
|
||||
scope: this.$rootScope.$new(),
|
||||
modalClass: 'modal--narrow'
|
||||
});
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-7">Folder</label>
|
||||
<div class="dropdown">
|
||||
<metric-segment segment="ctrl.selectedFolderSegment"
|
||||
get-options="ctrl.getOptions()"
|
||||
on-change="ctrl.folderChanged()"></metric-segment>
|
||||
</div>
|
||||
</div>
|
@ -6,47 +6,38 @@ import _ from 'lodash';
|
||||
|
||||
export class FolderPickerCtrl {
|
||||
folders: Folder[];
|
||||
selectedFolder: number;
|
||||
selectedFolderSegment: any;
|
||||
selectedOption: any;
|
||||
initialTitle: string;
|
||||
onChange: any;
|
||||
rootFolderName: string;
|
||||
labelClass: string;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $scope, private $sce, private uiSegmentSrv) {
|
||||
this.selectedFolderSegment = this.uiSegmentSrv.newSegment({value: this.rootFolderName || 'Root', selectMode: true});
|
||||
this.get();
|
||||
constructor(private backendSrv, private $scope, private $sce) {
|
||||
if (!this.labelClass) {
|
||||
this.labelClass = "width-7";
|
||||
}
|
||||
|
||||
this.selectedOption = {text: this.initialTitle, value: null};
|
||||
}
|
||||
|
||||
get() {
|
||||
getOptions(query) {
|
||||
var params = {
|
||||
query: query,
|
||||
type: 'dash-folder',
|
||||
};
|
||||
|
||||
return this.backendSrv.search(params).then(result => {
|
||||
this.folders = [{id: 0, title: this.rootFolderName || 'Root', type: 'dash-folder'}];
|
||||
this.folders.push(...result);
|
||||
|
||||
if (this.selectedFolder) {
|
||||
const selected = _.find(this.folders, {id: this.selectedFolder});
|
||||
|
||||
this.selectedFolderSegment.value = selected.title;
|
||||
this.selectedFolderSegment.text = selected.title;
|
||||
this.selectedFolderSegment.html = this.$sce.trustAsHtml(selected.title);
|
||||
if (query === "") {
|
||||
result.unshift({title: "Root", value: 0});
|
||||
}
|
||||
return _.map(result, item => {
|
||||
return {text: item.title, value: item.id};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getOptions() {
|
||||
return Promise.resolve(this.folders.map(folder => {
|
||||
return this.uiSegmentSrv.newSegment(folder.title);
|
||||
}));
|
||||
}
|
||||
|
||||
folderChanged() {
|
||||
const selected = _.find(this.folders, {title: this.selectedFolderSegment.value});
|
||||
if (selected) {
|
||||
this.onChange({$folderId: selected.id});
|
||||
}
|
||||
folderChanged(option) {
|
||||
this.onChange({$folder: {id: option.value, title: option.text}});
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,17 +52,29 @@ export interface Folder {
|
||||
dashboards?: any;
|
||||
}
|
||||
|
||||
const template = `
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label {{ctrl.labelClass}}">Folder</label>
|
||||
<div class="dropdown">
|
||||
<gf-form-dropdown model="ctrl.selectedOption"
|
||||
get-options="ctrl.getOptions($query)"
|
||||
on-change="ctrl.folderChanged($option)">
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export function folderPicker() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'public/app/features/dashboard/folder_picker/picker.html',
|
||||
template: template,
|
||||
controller: FolderPickerCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
selectedFolder: "<",
|
||||
initialTitle: "<",
|
||||
onChange: "&",
|
||||
rootFolderName: "@"
|
||||
labelClass: "@",
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -45,7 +45,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<folder-picker ng-if="!dashboardMeta.isFolder" selected-folder="dashboardMeta.parentId" on-change="onFolderChange($folderId)"></folder-picker>
|
||||
<folder-picker ng-if="!dashboardMeta.isFolder"
|
||||
initial-title="dashboardMeta.folderTitle"
|
||||
on-change="onFolderChange($folder)"
|
||||
label-class="width-7">
|
||||
</folder-picker>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
|
@ -18,11 +18,13 @@ const template = `
|
||||
<form name="ctrl.saveForm" ng-submit="ctrl.save()" class="modal-content" novalidate>
|
||||
<div class="p-t-2">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">New name</label>
|
||||
<label class="gf-form-label width-7">New name</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.clone.title" give-focus="true" required>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<folder-picker ng-if="!ctrl.clone.meta.isFolder" selected-folder="ctrl.clone.meta.parentId" on-change="ctrl.onFolderChange($folderId)">
|
||||
<folder-picker initial-title="ctrl.folderTitle"
|
||||
on-change="ctrl.onFolderChange($folder)"
|
||||
label-class="width-7">
|
||||
</folder-picker>
|
||||
</div>
|
||||
</div>
|
||||
@ -37,6 +39,7 @@ const template = `
|
||||
|
||||
export class SaveDashboardAsModalCtrl {
|
||||
clone: any;
|
||||
folderTitle: any;
|
||||
dismiss: () => void;
|
||||
|
||||
/** @ngInject */
|
||||
@ -47,6 +50,7 @@ export class SaveDashboardAsModalCtrl {
|
||||
this.clone.title += ' Copy';
|
||||
this.clone.editable = true;
|
||||
this.clone.hideControls = false;
|
||||
this.folderTitle = dashboard.meta.folderTitle || 'Root';
|
||||
|
||||
// remove alerts
|
||||
this.clone.rows.forEach(row => {
|
||||
@ -68,8 +72,8 @@ export class SaveDashboardAsModalCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
onFolderChange(parentId) {
|
||||
this.clone.parentId = parentId;
|
||||
onFolderChange(folder) {
|
||||
this.clone.parentId = folder.id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,10 @@
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Folder</span>
|
||||
<folder-picker selected-folder="ctrl.panel.folderId" on-change="ctrl.onFolderChange" root-folder-name="All"></folder-picker>
|
||||
<folder-picker initial-text="ctrl.folderTitle"
|
||||
on-change="ctrl.onFolderChange($folder)"
|
||||
label-class="width-6">
|
||||
</folder-picker>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
|
@ -10,6 +10,7 @@ class DashListCtrl extends PanelCtrl {
|
||||
|
||||
groups: any[];
|
||||
modes: any[];
|
||||
folderTitle: any;
|
||||
|
||||
panelDefaults = {
|
||||
query: '',
|
||||
@ -19,7 +20,7 @@ class DashListCtrl extends PanelCtrl {
|
||||
search: false,
|
||||
starred: true,
|
||||
headings: true,
|
||||
folderId: 0
|
||||
folderId: 0,
|
||||
};
|
||||
|
||||
/** @ngInject */
|
||||
@ -65,6 +66,10 @@ class DashListCtrl extends PanelCtrl {
|
||||
this.editorTabIndex = 1;
|
||||
this.modes = ['starred', 'search', 'recently viewed'];
|
||||
this.addEditorTab('Options', 'public/app/plugins/panel/dashlist/editor.html');
|
||||
|
||||
if (!this.panel.folderId) {
|
||||
this.folderTitle = "All";
|
||||
}
|
||||
}
|
||||
|
||||
onRefresh() {
|
||||
@ -126,9 +131,10 @@ class DashListCtrl extends PanelCtrl {
|
||||
});
|
||||
}
|
||||
|
||||
onFolderChange(parentId) {
|
||||
this.$scope.$parent.ctrl.panel.folderId = parentId;
|
||||
this.$scope.$parent.ctrl.refresh();
|
||||
onFolderChange(folder) {
|
||||
this.panel.folderId = folder.id;
|
||||
this.panel.folderTitle = folder.title;
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user