Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
135
noc
Commits
70c9b9f1
Commit
70c9b9f1
authored
Aug 22, 2020
by
Andrey Vertiprahov
Browse files
Merge branch 'alarm-tag-tree' into 'master'
tag tree widget See merge request
noc/noc!4154
parents
56ca1a06
20d3797c
Changes
15
Hide whitespace changes
Inline
Side-by-side
lib/app/extmodelapplication.py
View file @
70c9b9f1
...
...
@@ -9,6 +9,7 @@
import
datetime
from
collections
import
defaultdict
from
functools
import
reduce
import
re
# Third-party modules
from
django.http
import
HttpResponse
...
...
@@ -72,6 +73,8 @@ class ExtModelApplication(ExtApplication):
SECRET_MASK
=
"********"
file_fields_mask
=
None
rx_oper_splitter
=
re
.
compile
(
r
"^(?P<field>\S+)(?P<f_num>\d+)__in"
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
self
.
db_table
=
self
.
model
.
_meta
.
db_table
...
...
@@ -259,6 +262,19 @@ class ExtModelApplication(ExtApplication):
def
cleaned_query
(
self
,
q
):
nq
=
{}
q
=
q
.
copy
()
# Extract IN
# extjs not working with same parameter name in query
for
p
in
list
(
q
.
keys
()):
if
p
.
endswith
(
self
.
in_param
):
match
=
self
.
rx_oper_splitter
.
match
(
p
)
if
match
:
field
=
self
.
rx_oper_splitter
.
match
(
p
).
group
(
"field"
)
+
self
.
in_param
if
field
not
in
q
:
q
[
field
]
=
"%s"
%
(
q
[
p
])
else
:
q
[
field
]
+=
",%s"
%
(
q
[
p
])
del
q
[
p
]
for
p
in
q
:
if
p
.
endswith
(
"__exists"
):
v
=
BooleanParameter
().
clean
(
q
[
p
])
...
...
@@ -312,6 +328,8 @@ class ExtModelApplication(ExtApplication):
except
self
.
fk_fields
[
np
].
DoesNotExist
:
nq
[
np
]
=
0
# False search
continue
elif
np
in
self
.
clean_fields
and
self
.
in_param
in
p
:
v
=
ListOfParameter
(
self
.
clean_fields
[
np
]).
clean
(
v
)
elif
np
in
self
.
clean_fields
:
# @todo: Check for valid lookup types
v
=
self
.
clean_fields
[
np
].
clean
(
v
)
# Write back
...
...
services/web/apps/fm/alarm/views.py
View file @
70c9b9f1
...
...
@@ -174,6 +174,10 @@ class AlarmApplication(ExtApplication):
if
q
[
"administrative_domain"
]
!=
"_root_"
:
q
[
"adm_path"
]
=
int
(
q
[
"administrative_domain"
])
q
.
pop
(
"administrative_domain"
)
if
"administrative_domain__in"
in
q
:
if
"_root_"
not
in
q
[
"administrative_domain__in"
]:
q
[
"adm_path__in"
]
=
q
[
"administrative_domain__in"
]
q
.
pop
(
"administrative_domain__in"
)
if
"segment"
in
q
:
if
q
[
"segment"
]
!=
"_root_"
:
q
[
"segment_path"
]
=
bson
.
ObjectId
(
q
[
"segment"
])
...
...
ui/web/core/combotree/ComboTree.js
View file @
70c9b9f1
...
...
@@ -188,10 +188,6 @@ Ext.define("NOC.core.combotree.ComboTree", {
expanded
:
true
,
children
:
[]
},
// ToDo make variable for theme
bodyStyle
:
{
background
:
"
#ecf0f1
"
},
tbar
:
[
searchField
],
...
...
@@ -240,18 +236,15 @@ Ext.define("NOC.core.combotree.ComboTree", {
doFilter
:
function
()
{
var
me
=
this
,
parentNode
=
me
.
getParentNode
();
if
(
parentNode
)
{
parentNode
.
removeAll
();
if
(
me
.
searchField
.
getValue
())
{
parentNode
.
appendChild
(
me
.
cache
.
filter
(
function
(
node
)
{
return
node
.
data
[
me
.
displayField
].
toLowerCase
()
.
indexOf
(
me
.
searchField
.
getValue
().
toLowerCase
())
!==
-
1
;
}
));
}
else
{
parentNode
.
appendChild
(
me
.
cache
);
parentNode
.
expand
();
}
me
.
treePicker
.
getStore
().
filterBy
(
function
(
record
)
{
if
(
record
.
parentNode
.
id
!==
me
.
currentLeaf
)
{
return
true
;
}
if
(
!
me
.
searchField
.
getValue
())
{
return
true
;
}
return
record
.
get
(
me
.
displayField
).
toLowerCase
().
indexOf
(
me
.
searchField
.
getValue
().
toLowerCase
())
!==
-
1
;
})
}
},
// event handlers
...
...
ui/web/css/extjs.css
View file @
70c9b9f1
...
...
@@ -440,6 +440,7 @@ TABLE {
.x-fieldset
{
overflow
:
visible
;
background
:
unset
;
}
.fas
{
...
...
ui/web/css/ux.css
View file @
70c9b9f1
...
...
@@ -84,13 +84,13 @@
cursor
:
default
;
}
.x-panel-body-default
{
background-color
:
#ecf0f1
!important
;
}
/*
.x-panel-body-default {
*/
/*
background-color: #ecf0f1 !important;
*/
/*}*/
.x-grid-row
{
background-color
:
#ecf0f1
!important
;
}
/*
.x-grid-row {
*/
/*
background-color: #ecf0f1 !important;
*/
/*}*/
.x-summary
{
color
:
#7f8c8d
;
...
...
ui/web/fm/alarm/ApplicationController.js
View file @
70c9b9f1
...
...
@@ -237,12 +237,12 @@ Ext.define("NOC.fm.alarm.ApplicationController", {
Ext
.
each
([
"
managed_object
"
,
"
managedobjectselector
"
,
"
segment
"
,
"
administrative_domain
"
"
segment
"
],
restoreCombo
,
this
);
// restore tag fields
Ext
.
each
([
"
alarm_class
"
"
alarm_class
"
,
"
administrative_domain
"
],
restoreTagField
,
this
);
// don't change, http params is string compare with int, 0 == "0"
if
(
params
.
hasOwnProperty
(
"
cleared_after
"
)
&&
params
.
cleared_after
!=
0
)
{
...
...
@@ -303,12 +303,12 @@ Ext.define("NOC.fm.alarm.ApplicationController", {
{
key
:
"
timestamp__lte
"
},
// tree
{
key
:
"
segment
"
,
valueField
:
"
id
"
},
{
key
:
"
administrative_domain
"
,
valueField
:
"
id
"
},
// combo
{
key
:
"
managed_object
"
,
valueField
:
"
id
"
},
{
key
:
"
managedobjectselector
"
,
valueField
:
"
id
"
},
// tag field
{
key
:
"
alarm_class
"
,
valueField
:
"
id
"
}
{
key
:
"
alarm_class
"
,
valueField
:
"
id
"
},
{
key
:
"
administrative_domain
"
,
valueField
:
"
id
"
}
],
setParam
);
if
(
value
.
hasOwnProperty
(
"
profiles
"
))
{
var
i
,
len
=
value
.
profiles
.
length
;
...
...
ui/web/fm/alarm/view/grids/Lookup.js
View file @
70c9b9f1
...
...
@@ -74,7 +74,7 @@ Ext.define("NOC.fm.alarm.view.grids.Lookup", {
initComponent
:
function
()
{
this
.
store
.
proxy
.
url
=
this
.
url
;
// Fix combobox with remote paging
this
.
pickerId
=
me
.
getId
()
+
'
_picker
'
;
this
.
pickerId
=
this
.
getId
()
+
'
_picker
'
;
// end
this
.
callParent
();
}
...
...
ui/web/fm/alarm/view/grids/Sidebar.js
View file @
70c9b9f1
...
...
@@ -216,12 +216,13 @@ Ext.define("NOC.fm.alarm.view.grids.Sidebar", {
}
},
{
xtype
:
"
noc.core.combotree
"
,
restUrl
:
"
/sa/administrativedomain/
"
,
xtype
:
"
fm.alarm.tagfield
"
,
url
:
"
/sa/administrativedomain/lookup/
"
,
isTree
:
true
,
fieldLabel
:
__
(
"
Adm. Domain
"
),
name
:
"
administrative_domain
"
,
bind
:
{
select
ion
:
"
{activeFilter.administrative_domain}
"
select
ed
:
"
{activeFilter.administrative_domain}
"
}
},
{
...
...
ui/web/fm/alarm/view/grids/Tagfield.js
View file @
70c9b9f1
//---------------------------------------------------------------------
// fm.alarm
application
// fm.alarm
.tagfield widget
//---------------------------------------------------------------------
// Copyright (C) 2007-20
19
The NOC Project
// Copyright (C) 2007-20
20
The NOC Project
// See LICENSE for details
//---------------------------------------------------------------------
console
.
debug
(
"
Defining NOC.fm.alarm.view.grids.Tagfield
"
);
...
...
@@ -11,6 +11,7 @@ Ext.define("NOC.fm.alarm.view.grids.Tagfield", {
alias
:
"
widget.fm.alarm.tagfield
"
,
controller
:
"
fm.alarm.tagfield
"
,
requires
:
[
"
NOC.fm.alarm.view.grids.TreePicker
"
,
"
NOC.fm.alarm.view.grids.TagfieldController
"
],
displayField
:
"
label
"
,
...
...
@@ -21,6 +22,7 @@ Ext.define("NOC.fm.alarm.view.grids.Tagfield", {
queryDelay
:
200
,
minChars
:
2
,
pageSize
:
true
,
isTree
:
false
,
store
:
{
fields
:
[
"
id
"
,
"
label
"
],
pageSize
:
25
,
...
...
@@ -48,10 +50,21 @@ Ext.define("NOC.fm.alarm.view.grids.Tagfield", {
"
selected
"
],
listeners
:
{
change
:
"
onChange
"
change
:
"
onChange
TagValue
"
},
initComponent
:
function
()
{
this
.
store
.
proxy
.
url
=
this
.
url
;
if
(
this
.
isTree
)
{
// this.treePicker = this.createTreePicker();
this
.
triggers
.
picker
.
cls
=
"
theme-classic fas fa fa-folder-open-o
"
;
this
.
treePicker
=
Ext
.
create
({
xtype
:
"
fm.alarm.treepicker
"
,
displayField
:
this
.
displayField
,
scope
:
this
,
});
}
// Fix combobox when use remote paging
this
.
pickerId
=
this
.
getId
()
+
'
-picker
'
;
this
.
callParent
();
},
setSelected
:
function
(
value
,
skip
)
{
...
...
@@ -62,5 +75,25 @@ Ext.define("NOC.fm.alarm.view.grids.Tagfield", {
},
setWidgetValues
:
function
(
data
)
{
this
.
setSelection
(
data
);
}
},
onTriggerClick
:
function
(
el
)
{
if
(
!
el
)
{
return
;
}
if
(
this
.
isTree
)
{
var
position
,
heightAbove
=
this
.
getPosition
()[
1
]
-
Ext
.
getBody
().
getScroll
().
top
,
heightBelow
=
Ext
.
Element
.
getViewportHeight
()
-
heightAbove
-
this
.
getHeight
();
this
.
treePicker
.
setWidth
(
this
.
getWidth
());
this
.
treePicker
.
height
=
Math
.
max
(
heightAbove
,
heightBelow
)
-
5
;
this
.
setEditable
(
false
);
position
=
this
.
getPosition
();
if
(
heightAbove
>
heightBelow
)
{
position
[
1
]
-=
this
.
treePicker
.
height
-
this
.
getHeight
();
}
this
.
treePicker
.
showAt
(
position
);
}
else
{
Ext
.
form
.
field
.
Tag
.
prototype
.
onTriggerClick
.
apply
(
this
,
arguments
);
}
},
});
ui/web/fm/alarm/view/grids/TagfieldController.js
View file @
70c9b9f1
//---------------------------------------------------------------------
//
fm.alarm application
//
Tagfield controller
//---------------------------------------------------------------------
// Copyright (C) 2007-20
18
The NOC Project
// Copyright (C) 2007-20
20
The NOC Project
// See LICENSE for details
//---------------------------------------------------------------------
console
.
debug
(
"
Defining NOC.fm.alarm.view.grids.TagfieldController
"
);
...
...
@@ -9,8 +9,12 @@ Ext.define("NOC.fm.alarm.view.grids.TagfieldController", {
extend
:
"
Ext.app.ViewController
"
,
alias
:
"
controller.fm.alarm.tagfield
"
,
onChange
:
function
(
self
)
{
var
selected
=
self
.
getPicker
().
getSelectionModel
().
getSelection
();
this
.
getView
().
setSelected
(
selected
,
true
);
}
onChangeTagValue
:
function
(
self
)
{
var
view
=
this
.
getView
(),
selected
=
self
.
getPicker
().
getSelectionModel
().
getSelection
();
if
(
view
.
isTree
)
{
view
.
treePicker
.
getController
().
selectNode
(
selected
);
}
view
.
setSelected
(
selected
,
true
);
},
});
\ No newline at end of file
ui/web/fm/alarm/view/grids/TreePicker.js
0 → 100644
View file @
70c9b9f1
//---------------------------------------------------------------------
// fm.alarm.treepicker widget
//---------------------------------------------------------------------
// Copyright (C) 2007-2020 The NOC Project
// See LICENSE for details
//---------------------------------------------------------------------
console
.
debug
(
"
Defining NOC.fm.alarm.view.grids.TreePicker
"
);
Ext
.
define
(
"
NOC.fm.alarm.view.grids.TreePicker
"
,
{
extend
:
"
Ext.tree.Panel
"
,
alias
:
"
widget.fm.alarm.treepicker
"
,
controller
:
"
fm.alarm.treepicker
"
,
requires
:
[
"
NOC.fm.alarm.view.grids.TreePickerController
"
],
baseCls
:
Ext
.
baseCSSPrefix
+
"
boundlist
"
,
shrinkWrap
:
2
,
shrinkWrapDock
:
true
,
animCollapse
:
true
,
singleExpand
:
false
,
useArrows
:
true
,
scrollable
:
true
,
floating
:
true
,
manageHeight
:
false
,
collapseFirst
:
false
,
currentLeaf
:
false
,
rootVisible
:
false
,
root
:
{
expanded
:
true
,
children
:
[]
},
selModel
:
{
mode
:
"
SIMPLE
"
},
tbar
:
[
{
xtype
:
"
searchfield
"
,
width
:
"
90%
"
,
emptyText
:
__
(
"
pattern
"
),
enableKeyEvents
:
true
,
triggers
:
{
clear
:
{
cls
:
"
x-form-clear-trigger
"
,
hidden
:
true
,
handler
:
"
onClearSearchField
"
}
},
listeners
:
{
keyup
:
"
onChangeSearchField
"
}
},
{
glyph
:
NOC
.
glyph
.
times_circle
,
tooltip
:
__
(
"
Close
"
),
handler
:
"
onClosePanel
"
}
],
listeners
:
{
itemclick
:
"
onItemClick
"
,
itemkeydown
:
"
onPickerKeyDown
"
,
beforeitemexpand
:
"
onItemBeforeExpand
"
,
itemexpand
:
"
onItemExpand
"
,
focusleave
:
"
onLeaveFocusTreePicker
"
},
initComponent
:
function
()
{
// tree panel store
this
.
treeStore
=
Ext
.
create
(
"
Ext.data.Store
"
,
Ext
.
merge
(
Ext
.
clone
(
this
.
scope
.
getStore
()),
{
autoLoad
:
true
,
proxy
:
{
extraParams
:
{
parent
:
""
}
},
listeners
:
{
scope
:
this
.
getController
(),
load
:
this
.
getController
().
onLoadTree
}
},
true
));
this
.
callParent
();
}
});
\ No newline at end of file
ui/web/fm/alarm/view/grids/TreePickerController.js
0 → 100644
View file @
70c9b9f1
//---------------------------------------------------------------------
// fm.alarm.treepicker controller
//---------------------------------------------------------------------
// Copyright (C) 2007-2020 The NOC Project
// See LICENSE for details
//---------------------------------------------------------------------
console
.
debug
(
"
Defining NOC.fm.alarm.view.grids.TreePickerController
"
);
Ext
.
define
(
"
NOC.fm.alarm.view.grids.TreePickerController
"
,
{
extend
:
"
Ext.app.ViewController
"
,
alias
:
"
controller.fm.alarm.treepicker
"
,
requires
:
[],
// store events
onLoadTree
:
function
(
store
,
records
,
success
)
{
var
parentNode
=
this
.
getParentNode
(),
me
=
this
.
getView
(),
parentField
=
me
.
scope
;
if
(
!
parentNode
.
hasChildNodes
()
&&
success
)
{
parentNode
.
appendChild
(
records
.
map
(
function
(
item
)
{
return
Ext
.
merge
({
leaf
:
!
item
.
get
(
"
has_children
"
),
qtip
:
item
.
get
(
parentField
.
displayField
)
},
item
.
getData
());
}));
parentNode
.
expand
();
}
if
(
!
me
.
cache
)
{
// first run, root elements
me
.
cache
=
Ext
.
clone
(
parentNode
.
childNodes
);
}
},
// tree panel events
onClosePanel
:
function
()
{
this
.
getView
().
hide
();
},
onItemClick
:
function
(
view
,
record
)
{
this
.
selectItem
(
record
);
},
onPickerKeyDown
:
function
(
view
,
record
,
item
,
index
,
e
)
{
var
key
=
e
.
getKey
();
if
(
key
===
e
.
ENTER
)
{
this
.
selectItem
(
record
);
}
},
onItemBeforeExpand
:
function
(
self
)
{
var
me
=
this
.
getView
(),
node
;
if
(
me
.
currentLeaf
&&
(
me
.
currentLeaf
!==
self
.
getId
()))
{
node
=
me
.
getStore
().
getNodeById
(
me
.
currentLeaf
);
node
.
appendChild
(
me
.
cache
);
}
me
.
currentLeaf
=
self
.
getId
();
me
.
cache
=
Ext
.
clone
(
self
.
childNodes
);
if
(
!
self
.
hasChildNodes
())
{
this
.
loadChildren
(
me
.
currentLeaf
);
return
false
;
}
},
onItemExpand
:
function
()
{
this
.
doFilter
();
},
onLeaveFocusTreePicker
:
function
()
{
this
.
getView
().
scope
.
setEditable
(
true
);
this
.
getView
().
hide
();
},
// search field events
onClearSearchField
:
function
(
self
)
{
self
.
setValue
();
self
.
getTrigger
(
"
clear
"
).
hide
();
this
.
doFilter
();
},
onChangeSearchField
:
function
(
self
)
{
if
(
self
.
getValue
()
==
null
||
!
self
.
getValue
().
length
)
{
this
.
onClearSearchField
(
self
);
return
;
}
this
.
doFilter
();
self
.
getTrigger
(
"
clear
"
).
show
();
},
//
getParentNode
:
function
()
{
var
me
=
this
.
getView
(),
store
=
me
.
getStore
();
if
(
!
me
.
currentLeaf
)
{
return
store
.
getRootNode
();
}
else
{
return
store
.
getById
(
me
.
currentLeaf
);
}
},
loadChildren
:
function
(
id
)
{
var
me
=
this
.
getView
();
if
(
!
me
.
hidden
)
{
me
.
mask
(
__
(
"
loading ...
"
));
}
me
.
treeStore
.
load
({
params
:
{
parent
:
id
},
callback
:
function
()
{
if
(
!
me
.
hidden
)
{
me
.
unmask
();
}
}
});
},
selectItem
:
function
(
record
)
{
var
parent
=
this
.
getView
().
scope
,
value
=
{},
isExist
,
selected
=
parent
.
getSelected
();
if
(
selected
)
{
isExist
=
Ext
.
Array
.
findBy
(
selected
,
function
(
el
)
{
return
el
.
id
===
record
.
id
});
}
if
(
isExist
)
{
parent
.
removeValue
(
isExist
);
}
else
{
value
[
parent
.
valueField
]
=
record
.
id
;
value
[
parent
.
displayField
]
=
record
.
get
(
parent
.
displayField
);
parent
.
addValue
(
Ext
.
create
(
"
Ext.data.Model
"
,
value
));
}
},
selectNode
:
function
()
{
var
me
=
this
.
getView
(),
selection
=
[];
if
(
me
)
{
// maping to tree-picker store
Ext
.
Array
.
each
(
me
.
scope
.
getPicker
().
getSelectionModel
().
getSelection
(),
function
(
record
)
{
var
node
=
me
.
getStore
().
getNodeById
(
record
.
id
);
if
(
node
)
{
selection
.
push
(
node
);
}
});
if
(
selection
.
length
)
{
me
.
getSelectionModel
().
select
(
selection
);
}
if
(
selection
.
length
===
0
)
{
me
.
getSelectionModel
().
deselectAll
(
selection
);
}
}
},
doFilter
:
function
()
{
var
me
=
this
.
getView
(),
parentNode
=
this
.
getParentNode
(),
searchField
=
me
.
down
(
"
[xtype=searchfield]
"
);
if
(
parentNode
)
{
me
.
getStore
().
filterBy
(
function
(
record
)
{
if
(
record
.
parentNode
.
id
!==
me
.
currentLeaf
)
{
return
true
;
}
if
(
!
searchField
.
getValue
())
{
return
true
;
}
return
record
.
get
(
me
.
scope
.
displayField
).
toLowerCase
().
indexOf
(
searchField
.
getValue
().
toLowerCase
())
!==
-
1
;
})
this
.
selectNode
();
}
},
});
\ No newline at end of file
ui/web/inv/map/MapPanel.js
View file @
70c9b9f1
...
...
@@ -125,9 +125,6 @@ Ext.define("NOC.inv.map.MapPanel", {
xtype
:
"
component
"
,
autoScroll
:
true
,
layout
:
"
fit
"
,
style
:
{
background
:
"
#ecf0f1
"
}
}
]
});
...
...
ui/web/inv/map/MiniMap.js
View file @
70c9b9f1
...
...
@@ -30,9 +30,6 @@ Ext.define('NOC.inv.map.MiniMap', {
width
:
w
,
model
:
mapPanel
.
graph
,
gridSize
:
1
,
background
:
{
color
:
'
#ecf0f1
'
},
interactive
:
false
});
this
.
miniPaper
.
on
(
'
blank:pointerdown
'
,
function
(
evt
,
x
,
y
)
{
...
...
ui/web/inv/map/inspectors/Inspector.js
View file @
70c9b9f1
...
...
@@ -11,9 +11,6 @@ Ext.define('NOC.inv.map.inspectors.Inspector', {
title
:
undefined
,
scrollable
:
'
vertical
'
,
bodyStyle
:
{
background
:
'
#c0c0c0
'
},
defaults
:
{
padding
:
4
},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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