Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
humanities
gargantext
Commits
c74a8774
Commit
c74a8774
authored
Sep 19, 2016
by
delanoe
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/romain-testing' into testing
parents
5cc4fa3a
a94986db
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
222 additions
and
17 deletions
+222
-17
nodes.py
gargantext/views/api/nodes.py
+50
-2
garganrest.js
static/lib/gargantext/garganrest.js
+3
-0
graph_renamer.js
static/lib/gargantext/graph_renamer.js
+103
-0
menu.css
static/lib/gargantext/menu.css
+22
-0
myGraphs.html
templates/pages/corpora/myGraphs.html
+13
-12
menu.html
templates/pages/menu.html
+31
-3
No files found.
gargantext/views/api/nodes.py
View file @
c74a8774
...
...
@@ -22,8 +22,15 @@ _node_available_types = NODETYPES
def
_query_nodes
(
request
,
node_id
=
None
):
user
=
cache
.
User
[
request
.
user
.
id
]
if
request
.
user
.
id
is
None
:
raise
TypeError
(
"This API request must come from an authenticated user."
)
else
:
# we query among the nodes that belong to this user
user
=
cache
.
User
[
request
.
user
.
id
]
# parameters validation
# fixme: this validation does not allow custom keys in url (eg '?name=' for rename action)
parameters
=
get_parameters
(
request
)
parameters
=
validate
(
parameters
,
{
'type'
:
dict
,
'items'
:
{
'formated'
:
{
'type'
:
str
,
'required'
:
False
,
'default'
:
'json'
},
...
...
@@ -255,7 +262,7 @@ class NodeListHaving(APIView):
class
NodeResource
(
APIView
):
#
TODO either real authentification test or remove check on user.id
#
contains a check on user.id (within _query_nodes)
def
get
(
self
,
request
,
node_id
):
parameters
,
query
,
count
=
_query_nodes
(
request
,
node_id
)
if
not
len
(
query
):
...
...
@@ -265,6 +272,7 @@ class NodeResource(APIView):
field
:
getattr
(
node
,
field
)
for
field
in
parameters
[
'fields'
]
})
# contains a check on user.id (within _query_nodes)
def
delete
(
self
,
request
,
node_id
):
parameters
,
query
,
count
=
_query_nodes
(
request
,
node_id
)
if
not
len
(
query
):
...
...
@@ -275,6 +283,46 @@ class NodeResource(APIView):
session
.
commit
()
return
JsonHttpResponse
({
'deleted'
:
result
.
rowcount
})
def
post
(
self
,
request
,
node_id
):
"""
For the moment, only used to rename a node
params in request.GET:
none (not allowed by _query_nodes validation)
params in request.DATA:
["name": the_new_name_str]
TODO 1 factorize with .projects.ProjectView.put and .post (thx c24b)
TODO 2 allow other changes than name
"""
# contains a check on user.id (within _query_nodes)
parameters
,
query
,
count
=
_query_nodes
(
request
,
node_id
)
the_node
=
query
.
pop
()
# retrieve the name
if
'name'
in
request
.
data
:
new_name
=
request
.
data
[
'name'
]
else
:
return
JsonHttpResponse
({
"detail"
:
"A 'name' parameter is required in data payload"
},
400
)
# check for conflicts
other
=
session
.
query
(
Node
)
.
filter
(
Node
.
name
==
new_name
)
.
count
()
if
other
>
0
:
return
JsonHttpResponse
({
"detail"
:
"A node with this name already exists"
},
409
)
# normal case: do the renaming
else
:
setattr
(
the_node
,
'name'
,
new_name
)
session
.
commit
()
return
JsonHttpResponse
({
'renamed'
:
new_name
},
200
)
class
CorpusFavorites
(
APIView
):
...
...
static/lib/gargantext/garganrest.js
View file @
c74a8774
...
...
@@ -64,6 +64,9 @@ var Resource = function(url_path) {
success
:
callback
});
};
// TODO allow also POST with params
// TODO this.post function(id, criteria OR params, callback)
// change an item
this
.
change
=
this
.
update
=
function
(
id
,
callback
)
{
$
.
ajax
({
...
...
static/lib/gargantext/graph_renamer.js
0 → 100644
View file @
c74a8774
var
coocId
=
null
;
var
coocName
=
null
;
var
graphNameBox
=
document
.
getElementById
(
"graph-name"
)
var
changeNameText
=
'type name here'
// initial tests
var
coocIdMatch
=
window
.
location
.
search
.
match
(
/cooc_id=
(\d
+
)
/
)
if
(
!
coocIdMatch
)
{
console
.
error
(
"could not find cooc_id in url (this graph is not saved in DB yet): can't show the rename input"
)
$
(
'#graph-rename'
).
remove
()
}
else
{
// we got a real COOCCURRENCES node
coocId
=
parseInt
(
coocIdMatch
.
pop
())
// check if has a name already
garganrest
.
nodes
.
get
(
coocId
,
testName
)
}
// HELPER FUNCTIONS
// ----------------
function
testName
(
jsonNode
)
{
var
aName
=
jsonNode
.
name
// names like "GRAPH EXPLORER COOC (in:4885)" are default so counted as null
if
(
!
aName
||
aName
.
match
(
/^GRAPH EXPLORER COOC/
))
{
// there's no real name => leave the page editable
coocName
=
null
}
else
{
// we got a real name => just fill it in the page
coocName
=
aName
showName
(
coocName
,
graphNameBox
)
}
console
.
warn
(
'coocName for this graph:'
,
coocName
)
}
function
makeEditable
(
textElement
,
callback
)
{
var
newInput
=
'<input id="graphname-edit" type="text"'
newInput
+=
' value="'
+
changeNameText
+
'"'
;
newInput
+=
' onfocus="return cleanInput(this)"'
;
newInput
+=
' onblur="return refillInput(this)"'
;
newInput
+=
' onkeypress="return checkEnterKey(event,submitName,this)"'
;
newInput
+=
'></input>'
;
textElement
.
innerHTML
=
newInput
}
function
cleanInput
(
inputElement
)
{
if
(
inputElement
.
value
==
changeNameText
)
{
inputElement
.
value
=
''
}
}
function
refillInput
(
inputElement
)
{
if
(
inputElement
.
value
==
''
)
{
inputElement
.
value
=
changeNameText
}
}
// binding for the input submitting
function
checkEnterKey
(
e
,
callback
,
element
)
{
if
(
e
.
which
==
13
)
{
callback
(
element
)
}
}
function
submitName
(
inputElement
)
{
console
.
warn
(
"renaming: using coocId ="
,
coocId
)
var
newName
=
inputElement
.
value
// the element where we'll show the response
var
messagePopBox
=
document
.
getElementById
(
"handmade-popover"
)
var
messagePopTxt
=
document
.
getElementById
(
"handmade-popover-content"
)
messagePopBox
.
classList
.
remove
(
"hide"
)
messagePopTxt
.
innerHTML
=
"Submitting..."
var
myData
=
new
FormData
();
myData
.
append
(
"name"
,
newName
)
console
.
log
(
"myData.get('name')"
,
myData
.
get
(
'name'
))
$
.
ajax
({
url
:
'/api/nodes/'
+
coocId
,
type
:
'POST'
,
contentType
:
false
,
processData
:
false
,
data
:
myData
,
beforeSend
:
function
(
xhr
)
{
xhr
.
setRequestHeader
(
"X-CSRFToken"
,
getCookie
(
"csrftoken"
));
},
success
:
function
(
result
)
{
messagePopTxt
.
innerHTML
=
'<h5 style="margin:.3em 0 0 0">OK saved !</h5>'
showName
(
newName
,
graphNameBox
)
setTimeout
(
function
(){
messagePopBox
.
classList
+=
' hide'
},
2000
);
},
error
:
function
(
result
)
{
messagePopTxt
.
innerHTML
=
'<span style="color:red">Error:</span>'
messagePopTxt
.
innerHTML
+=
'<i>'
+
result
.
statusText
+
'</i>'
if
(
result
.
status
==
409
)
{
messagePopTxt
.
innerHTML
+=
'<br/>(name is already taken!)'
}
setTimeout
(
function
(){
messagePopBox
.
classList
+=
' hide'
},
2000
);
}
});
}
function
showName
(
nameStr
,
target
)
{
target
.
innerHTML
=
'"'
+
nameStr
+
'"'
}
static/lib/gargantext/menu.css
View file @
c74a8774
...
...
@@ -29,3 +29,25 @@
/* glyphicons are always rendered too high within bootstrap buttons */
vertical-align
:
middle
}
/* graph name => editable input => submitName() => minimsg */
.editable
{
color
:
grey
;
}
#graphname-edit
{
color
:
white
;
background-color
:
transparent
;
border
:
none
;
max-width
:
8em
;
}
.minimsg
{
font-size
:
.7em
;
padding
:
7
p0x
9px
;
}
.minimsg
*
{
line-height
:
100%
;
}
templates/pages/corpora/myGraphs.html
View file @
c74a8774
...
...
@@ -23,25 +23,26 @@
<div
id=
"graph_{{cooc.id}}"
>
<div
class=
"row"
>
<div
class=
"col-md-1 content"
></div>
<div
class=
"col-md-5 content"
>
<li>
<h5>
{{cooc.name}}
</h5>
{{cooc.date}}
{% for key, value in coocs_count.items %}
{% for key, value in coocs_count.items %}
{% if key == cooc.id %}
{% if value > 0 %}
<ul>
<!-- <li>{{cooc.id}}</li> --
!
>
<li>From: {% if not cooc.hyperdata.start %} begin of corpus {% else %} {{cooc.hyperdata.start}} {% endif %}
, To: {% if not cooc.hyperdata.end %} end of corpus {% else %} {{cooc.hyperdata.end}} {% endif %}
<!-- <li>{{cooc.id}}</li> -->
<li>
From: {% if not cooc.hyperdata.start %} begin of corpus {% else %} {{cooc.hyperdata.start}} {% endif %}
, To: {% if not cooc.hyperdata.end %} end of corpus {% else %} {{cooc.hyperdata.end}} {% endif %}
</li>
<li>
{{ value }} nodes with distances:
<ul>
<li>
<li>
<a
href=
"/projects/{{project.id}}/corpora/{{corpus.id}}/explorer?cooc_id={{cooc.id}}&distance=distributional&bridgeness=5"
>
<span
class=
"glyphicon glyphicon-eye-open"
aria-hidden=
"true"
></span>
Conditional
Conditional
</a>
(with bridgeness
<a
href=
"/projects/{{project.id}}/corpora/{{corpus.id}}/explorer?cooc_id={{cooc.id}}&distance=conditional&bridgeness=10"
>
10
</a>
...
...
@@ -49,10 +50,10 @@
or
<a
href=
"/projects/{{project.id}}/corpora/{{corpus.id}}/explorer?cooc_id={{cooc.id}}&distance=conditional&bridgeness=30"
>
30
</a>
)
</li>
<li>
<li>
<a
href=
"/projects/{{project.id}}/corpora/{{corpus.id}}/explorer?cooc_id={{cooc.id}}&distance=distributional&bridgeness=5"
>
<span
class=
"glyphicon glyphicon-eye-open"
aria-hidden=
"true"
></span>
Distributional
Distributional
</a>
(with bridgeness
<a
href=
"/projects/{{project.id}}/corpora/{{corpus.id}}/explorer?cooc_id={{cooc.id}}&distance=distributional&bridgeness=10"
>
10
</a>
...
...
@@ -62,13 +63,13 @@
</li>
</ul>
</ul>
{% else %}
<!--
<br> Processing (wait and reload the page)
!-->
<div
class=
"progress"
>
<div
class=
" progress-bar progress-bar-striped active"
<div
class=
" progress-bar progress-bar-striped active"
role=
"progressbar"
aria-valuenow=
"45"
aria-valuemin=
"0"
aria-valuemax=
"100"
style=
"width: 70%"
>
<span>
Processing (wait and reload the page)
...
...
templates/pages/menu.html
View file @
c74a8774
...
...
@@ -5,8 +5,10 @@
<script
type=
"text/javascript"
src=
"{% static "
lib
/
jquery
/
1
.
11
.
1
/
jquery
.
min
.
js
"
%}"
></script>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% static "
lib
/
bootstrap
/
3
.
0
.
2
/
bootstrap
.
css
"
%}"
>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% static "
lib
/
gargantext
/
menu
.
css
"%}"
/>
{% block css %}
{% endblock %}
</head>
<body>
...
...
@@ -45,8 +47,26 @@
</a>
</li>
{% endif %}
</ul>
{% if view == "graph" %}
<li
id=
"graph-rename"
style=
"padding:15"
>
<span
class=
"glyphicon glyphicon-edit"
aria-hidden=
"true"
></span>
<span
id=
"graph-name"
class=
"editable"
ondblclick=
"makeEditable(this)"
>
Name your graph
</span>
</li>
<li
style=
"padding:15"
>
<button
class=
"hide"
onclick=
"submitName(this)"
></button>
<!-- £TODO put styles in a separate css file -->
<div
id=
"handmade-popover"
class=
"hide popover right"
style=
"height: 42px; top:4px; min-width:100px; width:135px; display:block"
>
<div
class=
"arrow"
></div>
<div
id=
"handmade-popover-content"
class=
"minimsg popover-content"
>
Submitting...
</div>
</div>
</li>
{% endif %}
</ul>
<ul
class=
"nav pull-right"
>
<li
class=
"dropdown"
>
<a
href=
"#"
role=
"button"
class=
"dropdown-toggle navbar-text"
data-toggle=
"dropdown"
title=
"That is your username"
>
...
...
@@ -104,7 +124,7 @@
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</a>
</li>
--
!
>
-->
{% for state in corpus.hyperdata.statuses %}
{% if state.action == "Workflow" %}
...
...
@@ -151,7 +171,7 @@
<a
type=
"button"
class=
"btn btn-default {% if view == 'analytics' %} active {% endif %}"
onclick=
"javascript:location.href='/projects/{{project.id}}/corpora/{{ corpus.id }}/analytics'"
data-target=
'#'
href=
'#'
>
<span
class=
"glyphicon glyphicon-signal"
aria-hidden=
"true"
></span>
Analytics
</a>
...
...
@@ -298,6 +318,7 @@
<script
type=
"text/javascript"
src=
"{% static "
lib
/
bootstrap
/
3
.
2
.
0
/
bootstrap
.
min
.
js
"
%}"
></script>
<script
type=
"text/javascript"
>
// initializes the popover elements with jquery
$
(
function
()
{
$
(
"[data-toggle='popover']"
).
popover
({
html
:
true
,
title
:
function
()
{
...
...
@@ -346,8 +367,15 @@
{% if view == "graph" %}
<!-- garganrest could be used here to update node's names if we add POST -->
<script
type=
"text/javascript"
src=
"{% static "
lib
/
gargantext
/
garganrest
.
js
"
%}"
></script>
<!-- Graph renaming (load after garganrest)-->
<script
type=
"text/javascript"
src=
"{% static "
lib
/
gargantext
/
graph_renamer
.
js
"
%}"
></script>
{% endif %}
{% if debug == False %}
<!-- Piwik -->
<script
type=
"text/javascript"
>
var
_paq
=
_paq
||
[];
...
...
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