Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
60d7e430
Commit
60d7e430
authored
Dec 19, 2017
by
Marcus Efraimsson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashfolders: support creating new folder from the folder picker. #10197
parent
908b6c8d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
290 additions
and
132 deletions
+290
-132
public/app/core/services/backend_srv.ts
+1
-1
public/app/features/dashboard/all.ts
+29
-28
public/app/features/dashboard/folder_picker/folder_picker.html
+47
-0
public/app/features/dashboard/folder_picker/folder_picker.ts
+161
-0
public/app/features/dashboard/folder_picker/picker.ts
+0
-103
public/app/features/dashboard/validation_srv.ts
+48
-0
public/sass/components/_gf-form.scss
+4
-0
No files found.
public/app/core/services/backend_srv.ts
View file @
60d7e430
...
...
@@ -251,7 +251,7 @@ export class BackendSrv {
createDashboardFolder
(
name
)
{
const
dash
=
{
schemaVersion
:
16
,
title
:
name
,
title
:
name
.
trim
()
,
editable
:
true
,
panels
:
[]
};
...
...
public/app/features/dashboard/all.ts
View file @
60d7e430
import
"./dashboard_ctrl"
;
import
"./alerting_srv"
;
import
"./history/history"
;
import
"./dashboardLoaderSrv"
;
import
"./dashnav/dashnav"
;
import
"./submenu/submenu"
;
import
"./save_as_modal"
;
import
"./save_modal"
;
import
"./shareModalCtrl"
;
import
"./shareSnapshotCtrl"
;
import
"./dashboard_srv"
;
import
"./view_state_srv"
;
import
"./time_srv"
;
import
"./unsavedChangesSrv"
;
import
"./unsaved_changes_modal"
;
import
"./timepicker/timepicker"
;
import
"./upload"
;
import
"./export/export_modal"
;
import
"./export_data/export_data_modal"
;
import
"./ad_hoc_filters"
;
import
"./repeat_option/repeat_option"
;
import
"./dashgrid/DashboardGridDirective"
;
import
"./dashgrid/PanelLoader"
;
import
"./dashgrid/RowOptions"
;
import
"./acl/acl"
;
import
"./folder_picker/picker"
;
import
"./move_to_folder_modal/move_to_folder"
;
import
"./settings/settings"
;
import
'./dashboard_ctrl'
;
import
'./alerting_srv'
;
import
'./history/history'
;
import
'./dashboardLoaderSrv'
;
import
'./dashnav/dashnav'
;
import
'./submenu/submenu'
;
import
'./save_as_modal'
;
import
'./save_modal'
;
import
'./shareModalCtrl'
;
import
'./shareSnapshotCtrl'
;
import
'./dashboard_srv'
;
import
'./view_state_srv'
;
import
'./validation_srv'
;
import
'./time_srv'
;
import
'./unsavedChangesSrv'
;
import
'./unsaved_changes_modal'
;
import
'./timepicker/timepicker'
;
import
'./upload'
;
import
'./export/export_modal'
;
import
'./export_data/export_data_modal'
;
import
'./ad_hoc_filters'
;
import
'./repeat_option/repeat_option'
;
import
'./dashgrid/DashboardGridDirective'
;
import
'./dashgrid/PanelLoader'
;
import
'./dashgrid/RowOptions'
;
import
'./acl/acl'
;
import
'./folder_picker/folder_picker'
;
import
'./move_to_folder_modal/move_to_folder'
;
import
'./settings/settings'
;
import
coreModule
from
"app/core/core_module"
;
import
{
DashboardListCtrl
}
from
"./dashboard_list_ctrl"
;
...
...
public/app/features/dashboard/folder_picker/folder_picker.html
0 → 100644
View file @
60d7e430
<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-show=
"ctrl.createNewFolder"
give-focus=
"ctrl.createNewFolder"
ng-model=
"ctrl.newFolderName"
ng-model-options=
"{ debounce: 400 }"
ng-class=
"{'validation-error': !ctrl.isNewFolderNameValid()}"
ng-change=
"ctrl.newFolderNameChanged()"
/>
</div>
<div
class=
"gf-form"
ng-show=
"ctrl.createNewFolder"
>
<label
class=
"gf-form-label text-success"
ng-show=
"ctrl.newFolderNameTouched && !ctrl.hasValidationError"
>
<i
class=
"fa fa-check"
></i>
</label>
</div>
<div
class=
"gf-form"
ng-show=
"ctrl.createNewFolder"
>
<button
class=
"gf-form-label"
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-show=
"ctrl.createNewFolder"
>
<button
class=
"gf-form-label"
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>
\ No newline at end of file
public/app/features/dashboard/folder_picker/folder_picker.ts
0 → 100644
View file @
60d7e430
///<reference path="../../../headers/common.d.ts" />
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
;
rootName
=
'Root'
;
folder
:
any
;
createNewFolder
:
boolean
;
newFolderName
:
string
;
newFolderNameTouched
:
boolean
;
hasValidationError
:
boolean
;
validationError
:
any
;
/** @ngInject */
constructor
(
private
backendSrv
,
private
validationSrv
)
{
if
(
!
this
.
labelClass
)
{
this
.
labelClass
=
"width-7"
;
}
this
.
loadInitialValue
();
}
getOptions
(
query
)
{
var
params
=
{
query
:
query
,
type
:
'dash-folder'
,
};
return
this
.
backendSrv
.
search
(
params
).
then
(
result
=>
{
if
(
query
===
''
||
query
.
toLowerCase
()
===
"r"
||
query
.
toLowerCase
()
===
"ro"
||
query
.
toLowerCase
()
===
"roo"
||
query
.
toLowerCase
()
===
"root"
)
{
result
.
unshift
({
title
:
this
.
rootName
,
id
:
0
});
}
if
(
this
.
enableCreateNew
&&
query
===
''
)
{
result
.
unshift
({
title
:
'-- New Folder --'
,
id
:
-
1
});
}
return
_
.
map
(
result
,
item
=>
{
return
{
text
:
item
.
title
,
value
:
item
.
id
};
});
});
}
onFolderChange
(
option
)
{
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
.
validateNewDashboardOrFolderName
(
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
.
createDashboardFolder
(
this
.
newFolderName
).
then
(
result
=>
{
appEvents
.
emit
(
'alert-success'
,
[
'Folder Created'
,
'OK'
]);
this
.
closeCreateFolder
();
this
.
folder
=
{
text
:
result
.
dashboard
.
title
,
value
:
result
.
dashboard
.
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
()
{
if
(
this
.
initialFolderId
&&
this
.
initialFolderId
>
0
)
{
this
.
getOptions
(
''
).
then
(
result
=>
{
this
.
folder
=
_
.
find
(
result
,
{
value
:
this
.
initialFolderId
});
this
.
onFolderLoad
();
});
}
else
{
if
(
this
.
initialTitle
)
{
this
.
folder
=
{
text
:
this
.
initialTitle
,
value
:
null
};
}
else
{
this
.
folder
=
{
text
:
this
.
rootName
,
value
:
0
};
}
this
.
onFolderLoad
();
}
}
private
onFolderLoad
()
{
if
(
this
.
onLoad
)
{
this
.
onLoad
({
$folder
:
{
id
:
this
.
folder
.
value
,
title
:
this
.
folder
.
text
}});
}
}
}
export
function
folderPicker
()
{
return
{
restrict
:
'E'
,
templateUrl
:
'public/app/features/dashboard/folder_picker/folder_picker.html'
,
controller
:
FolderPickerCtrl
,
bindToController
:
true
,
controllerAs
:
'ctrl'
,
scope
:
{
initialTitle
:
'<'
,
initialFolderId
:
'<'
,
labelClass
:
'@'
,
rootName
:
'@'
,
onChange
:
'&'
,
onLoad
:
'&'
,
onCreateFolder
:
'&'
,
enterFolderCreation
:
'&'
,
exitFolderCreation
:
'&'
,
enableCreateNew
:
'@'
}
};
}
coreModule
.
directive
(
'folderPicker'
,
folderPicker
);
public/app/features/dashboard/folder_picker/picker.ts
deleted
100644 → 0
View file @
908b6c8d
///<reference path="../../../headers/common.d.ts" />
import
coreModule
from
"app/core/core_module"
;
import
_
from
"lodash"
;
export
class
FolderPickerCtrl
{
initialTitle
:
string
;
initialFolderId
?:
number
;
labelClass
:
string
;
onChange
:
any
;
onLoad
:
any
;
rootName
=
"Root"
;
folder
:
any
;
/** @ngInject */
constructor
(
private
backendSrv
)
{
if
(
!
this
.
labelClass
)
{
this
.
labelClass
=
"width-7"
;
}
if
(
this
.
initialFolderId
&&
this
.
initialFolderId
>
0
)
{
this
.
getOptions
(
""
).
then
(
result
=>
{
this
.
folder
=
_
.
find
(
result
,
{
value
:
this
.
initialFolderId
});
this
.
onFolderLoad
();
});
}
else
{
if
(
this
.
initialTitle
)
{
this
.
folder
=
{
text
:
this
.
initialTitle
,
value
:
null
};
}
else
{
this
.
folder
=
{
text
:
this
.
rootName
,
value
:
0
};
}
this
.
onFolderLoad
();
}
}
getOptions
(
query
)
{
var
params
=
{
query
:
query
,
type
:
"dash-folder"
};
return
this
.
backendSrv
.
search
(
params
).
then
(
result
=>
{
if
(
query
===
""
||
query
.
toLowerCase
()
===
"r"
||
query
.
toLowerCase
()
===
"ro"
||
query
.
toLowerCase
()
===
"roo"
||
query
.
toLowerCase
()
===
"root"
)
{
result
.
unshift
({
title
:
this
.
rootName
,
id
:
0
});
}
return
_
.
map
(
result
,
item
=>
{
return
{
text
:
item
.
title
,
value
:
item
.
id
};
});
});
}
onFolderLoad
()
{
if
(
this
.
onLoad
)
{
this
.
onLoad
({
$folder
:
{
id
:
this
.
folder
.
value
,
title
:
this
.
folder
.
text
}
});
}
}
onFolderChange
(
option
)
{
this
.
onChange
({
$folder
:
{
id
:
option
.
value
,
title
:
option
.
text
}
});
}
}
const
template
=
`
<div class="gf-form">
<label class="gf-form-label {{ctrl.labelClass}}">Folder</label>
<div class="dropdown">
<gf-form-dropdown model="ctrl.folder"
get-options="ctrl.getOptions($query)"
on-change="ctrl.onFolderChange($option)">
</gf-form-dropdown>
</div>
</div>
`
;
export
function
folderPicker
()
{
return
{
restrict
:
"E"
,
template
:
template
,
controller
:
FolderPickerCtrl
,
bindToController
:
true
,
controllerAs
:
"ctrl"
,
scope
:
{
initialTitle
:
"<"
,
initialFolderId
:
"<"
,
labelClass
:
"@"
,
rootName
:
"@"
,
onChange
:
"&"
,
onLoad
:
"&"
}
};
}
coreModule
.
directive
(
"folderPicker"
,
folderPicker
);
public/app/features/dashboard/validation_srv.ts
0 → 100644
View file @
60d7e430
///<reference path="../../headers/common.d.ts" />
import
coreModule
from
'app/core/core_module'
;
export
class
ValidationSrv
{
rootName
=
'root'
;
/** @ngInject */
constructor
(
private
$q
,
private
backendSrv
)
{}
validateNewDashboardOrFolderName
(
name
)
{
name
=
(
name
||
''
).
trim
();
if
(
name
.
length
===
0
)
{
return
this
.
$q
.
reject
({
type
:
'REQUIRED'
,
message
:
'Name is required'
});
}
if
(
name
.
toLowerCase
()
===
this
.
rootName
)
{
return
this
.
$q
.
reject
({
type
:
'EXISTING'
,
message
:
'A folder or dashboard with the same name already exists'
});
}
let
deferred
=
this
.
$q
.
defer
();
this
.
backendSrv
.
search
({
query
:
name
}).
then
(
res
=>
{
for
(
let
hit
of
res
)
{
if
(
name
.
toLowerCase
()
===
hit
.
title
.
toLowerCase
())
{
deferred
.
reject
({
type
:
'EXISTING'
,
message
:
'A folder or dashboard with the same name already exists'
});
break
;
}
}
deferred
.
resolve
();
});
return
deferred
.
promise
;
}
}
coreModule
.
service
(
'validationSrv'
,
ValidationSrv
);
public/sass/components/_gf-form.scss
View file @
60d7e430
...
...
@@ -109,6 +109,10 @@ $input-border: 1px solid $input-border-color;
&
--error
{
color
:
$critical
;
}
&
:disabled
{
color
:
$text-color-weak
}
}
.gf-form-label
+
.gf-form-label
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment