Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
alecs_myu
erp5
Commits
8fdc1a15
Commit
8fdc1a15
authored
Jan 09, 2018
by
Tomáš Peterka
Committed by
Romain Courteaud
Jan 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[hal_json+renderjs] Implement "stat" line for ListBox
/reviewed-on
!528
parent
78bd5926
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
989 additions
and
202 deletions
+989
-202
bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
...rtal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
+68
-1
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statMethod.py
...ateItem/portal_skins/erp5_ui_test/FooModule_statMethod.py
+12
-0
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statMethod.xml
...teItem/portal_skins/erp5_ui_test/FooModule_statMethod.xml
+66
-0
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statQuantity.py
...eItem/portal_skins/erp5_ui_test/FooModule_statQuantity.py
+6
-0
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statQuantity.xml
...Item/portal_skins/erp5_ui_test/FooModule_statQuantity.xml
+66
-0
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.js
...athTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.js
+26
-20
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.xml
...thTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.xml
+2
-2
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_html.html
...ateItem/web_page_module/rjs_gadget_erp5_listbox_html.html
+40
-19
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_html.xml
...lateItem/web_page_module/rjs_gadget_erp5_listbox_html.xml
+2
-2
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_js.js
...emplateItem/web_page_module/rjs_gadget_erp5_listbox_js.js
+167
-95
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_js.xml
...mplateItem/web_page_module/rjs_gadget_erp5_listbox_js.xml
+2
-8
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_nojqm_css.css
...emplateItem/web_page_module/rjs_gadget_erp5_nojqm_css.css
+24
-14
bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui/erp5css.less.txt
...teItem/portal_skins/erp5_web_renderjs_ui/erp5css.less.txt
+28
-25
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.xml
...ts/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.xml
+58
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.zpt
...ts/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.zpt
+47
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testHideItem.zpt
...m/portal_tests/renderjs_ui_listbox_zuite/testHideItem.zpt
+0
-15
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatColumns.xml
...ortal_tests/renderjs_ui_listbox_zuite/testStatColumns.xml
+58
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatColumns.zpt
...ortal_tests/renderjs_ui_listbox_zuite/testStatColumns.zpt
+73
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMethod.xml
...portal_tests/renderjs_ui_listbox_zuite/testStatMethod.xml
+58
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMethod.zpt
...portal_tests/renderjs_ui_listbox_zuite/testStatMethod.zpt
+74
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMissing.xml
...ortal_tests/renderjs_ui_listbox_zuite/testStatMissing.xml
+58
-0
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMissing.zpt
...ortal_tests/renderjs_ui_listbox_zuite/testStatMissing.zpt
+53
-0
bt5/erp5_web_renderjs_ui_test/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui_test/Zuite_CommonTemplateForRenderjsUi.zpt
...eb_renderjs_ui_test/Zuite_CommonTemplateForRenderjsUi.zpt
+1
-1
No files found.
bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
View file @
8fdc1a15
...
...
@@ -47,10 +47,26 @@ MARKER = []
if
REQUEST
is
None
:
REQUEST
=
context
.
REQUEST
# raise Unauthorized
if
response
is
None
:
response
=
REQUEST
.
RESPONSE
def
toBasicTypes
(
obj
):
"""Ensure that obj contains only basic types."""
if
obj
is
None
:
return
obj
if
isinstance
(
obj
,
(
bool
,
int
,
float
,
long
,
str
,
unicode
)):
return
obj
if
isinstance
(
obj
,
(
tuple
,
list
)):
return
[
toBasicTypes
(
x
)
for
x
in
obj
]
try
:
return
{
toBasicTypes
(
key
):
toBasicTypes
(
obj
[
key
])
for
key
in
obj
}
except
:
log
(
'Cannot convert {!s} to basic types {!s}'
.
format
(
type
(
obj
),
obj
),
level
=
100
)
return
obj
# http://stackoverflow.com/a/13105359
def
byteify
(
string
):
if
isinstance
(
string
,
dict
):
...
...
@@ -684,6 +700,8 @@ def renderField(traversed_document, field, form, value=None, meta_type=None, key
"lines"
:
lines
,
"default_params"
:
default_params
,
"list_method"
:
list_method_name
,
"show_stat"
:
field
.
get_value
(
'stat_method'
)
!=
""
or
len
(
field
.
get_value
(
'stat_columns'
))
>
0
,
"show_count"
:
field
.
get_value
(
'count_method'
)
!=
""
,
"query"
:
url_template_dict
[
"jio_search_template"
]
%
{
"query"
:
make_query
({
"query"
:
sql_catalog
.
buildQuery
(
...
...
@@ -1478,6 +1496,55 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
contents_list
.
append
(
contents_item
)
result_dict
[
'_embedded'
][
'contents'
]
=
contents_list
# Compute statistics if the search issuer was ListBox
# or in future if the stats (SUM) are required by JIO call
source_field_meta_type
=
source_field
.
meta_type
if
source_field
is
not
None
else
""
if
source_field_meta_type
==
"ProxyField"
:
source_field_meta_type
=
source_field
.
getRecursiveTemplateField
().
meta_type
if
source_field
is
not
None
and
source_field_meta_type
==
"ListBox"
:
contents_stat_list
=
[]
# in case the search was issued by listbox we can provide results of
# stat_method and count_method back to the caller
# XXX: we should check whether they asked for it
stat_method
=
source_field
.
get_value
(
'stat_method'
)
stat_columns
=
source_field
.
get_value
(
'stat_columns'
)
# support only selection_name for stat methods because any `selection` is deprecated
# and should be removed
# Romain wants full backward compatibility so putting `selection` back in parameters
selection_name
=
source_field
.
get_value
(
'selection_name'
)
if
selection_name
and
'selection_name'
not
in
catalog_kw
:
catalog_kw
[
'selection_name'
]
=
selection_name
catalog_kw
[
'selection'
]
=
context
.
getPortalObject
().
portal_selections
.
getSelectionFor
(
selection_name
,
REQUEST
)
contents_stat
=
{}
if
len
(
stat_columns
)
>
0
:
# prefer stat per column (follow original ListBox.py implementation)
for
stat_name
,
stat_script
in
stat_columns
:
contents_stat
[
stat_name
]
=
getattr
(
traversed_document
,
stat_script
)(
REQUEST
=
REQUEST
,
**
catalog_kw
)
contents_stat_list
.
append
(
contents_stat
)
elif
stat_method
!=
""
and
stat_method
.
getMethodName
()
!=
list_method
:
# general stat_method is second in priority list - should return dictionary or list of dictionaries
# where all "fields" should be accessible by their "select" name (no "listbox_" prefix)
stat_method_result
=
getattr
(
traversed_document
,
stat_method
.
getMethodName
())(
REQUEST
=
REQUEST
,
**
catalog_kw
)
# stat method can return simple dictionary or subscriptable object thus we put it into one-item list
if
stat_method_result
is
not
None
and
not
isinstance
(
stat_method_result
,
(
list
,
tuple
)):
stat_method_result
=
[
stat_method_result
,
]
contents_stat_list
=
toBasicTypes
(
stat_method_result
)
or
[]
for
contents_stat
in
contents_stat_list
:
for
key
,
value
in
contents_stat
.
items
():
if
key
in
editable_field_dict
:
contents_stat
[
key
]
=
renderField
(
traversed_document
,
editable_field_dict
[
key
],
listbox_form
,
value
,
key
=
editable_field_dict
[
key
].
id
+
'__sum'
)
if
len
(
contents_stat_list
)
>
0
:
result_dict
[
'_embedded'
][
'sum'
]
=
contents_stat_list
# We should cleanup the selection if it exists in catalog params BUT
# we cannot because it requires escalated Permission.'modifyPortal' so
# the correct solution would be to ReportSection.popReport but unfortunately
# we don't have it anymore because we are asynchronous
return
result_dict
elif
mode
==
'form'
:
...
...
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statMethod.py
0 → 100644
View file @
8fdc1a15
"""Compute stats from actual Foo Lines on a Foo object"""
column_list
=
[
'getQuantity'
,
'id'
]
result
=
{
c
:
0.0
for
c
in
column_list
}
for
line
in
context
.
contentValues
(
portal_type
=
"Foo"
):
for
column
in
column_list
:
value
=
getattr
(
line
,
column
)
if
callable
(
value
):
value
=
value
()
result
[
column
]
=
result
[
column
]
+
float
(
value
)
return
[
result
,
]
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statMethod.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Python Script"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
Script_magic
</string>
</key>
<value>
<int>
3
</int>
</value>
</item>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
**kwargs
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
FooModule_statMethod
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Python Script
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statQuantity.py
0 → 100644
View file @
8fdc1a15
counter
=
0
for
value
in
context
.
contentValues
():
counter
=
counter
+
int
(
value
.
getQuantity
())
return
counter
bt5/erp5_ui_test/SkinTemplateItem/portal_skins/erp5_ui_test/FooModule_statQuantity.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Python Script"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
Script_magic
</string>
</key>
<value>
<int>
3
</int>
</value>
</item>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
selection, **kwargs
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
FooModule_statQuantity
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Python Script
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.js
View file @
8fdc1a15
...
...
@@ -178,27 +178,33 @@
]
)
.
push
(
function
(
catalog_json
)
{
var
data
=
catalog_json
.
_embedded
.
contents
,
count
=
data
.
length
,
k
,
uri
,
item
,
result
=
[];
for
(
k
=
0
;
k
<
count
;
k
+=
1
)
{
item
=
data
[
k
];
uri
=
new
URI
(
item
.
_links
.
self
.
href
);
delete
item
.
_links
;
result
.
push
({
id
:
uri
.
segment
(
2
),
doc
:
{},
value
:
item
});
}
var
data
=
catalog_json
.
_embedded
.
contents
||
[],
summary
=
catalog_json
.
_embedded
.
sum
||
[],
count
=
catalog_json
.
_embedded
.
count
;
return
{
data
:
{
rows
:
result
,
total_rows
:
result
.
length
}
"
data
"
:
{
"
rows
"
:
data
.
map
(
function
(
item
)
{
var
uri
=
new
URI
(
item
.
_links
.
self
.
href
);
delete
item
.
_links
;
return
{
"
id
"
:
uri
.
segment
(
2
),
"
doc
"
:
{},
"
value
"
:
item
};
}),
"
total_rows
"
:
data
.
length
},
"
sum
"
:
{
"
rows
"
:
summary
.
map
(
function
(
item
,
index
)
{
return
{
"
id
"
:
'
/#summary
'
+
index
,
// this is obviously wrong. @Romain help please!
"
doc
"
:
{},
"
value
"
:
item
};
}),
"
total_rows
"
:
summary
.
length
},
"
count
"
:
count
};
});
})
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_jio_js.xml
View file @
8fdc1a15
...
...
@@ -230,7 +230,7 @@
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
9
47.45414.13002.1005
2
</string>
</value>
<value>
<string>
9
63.59331.40212.5543
2
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
...
...
@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>
1
449753994.81
</float>
<float>
1
512454358.33
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_html.html
View file @
8fdc1a15
...
...
@@ -60,18 +60,18 @@
<
/thead
>
<
/table
>
</script>
<script
id=
"listbox-hidden-tbody-template"
type=
"text/x-handlebars-template"
>
<
table
>
<
tbody
class
=
"
tbody
"
>
{{
#
each
body_value
}}
{{
#
each
row_list
}}
<
tr
>
{{
#
if
..
/
show_anchor
}}
<
th
>
<
a
class
=
"
ui-link ui-btn ui-corner-all ui-icon-carat-r ui-btn-icon-notext
"
href
=
"
{{jump}}
"
><
/a
>
<
/th
>
{{
/
if
}}
{{
#
each
tr_value
}}
{{
#
each
cell_list
}}
<
td
>
{{
#
if
type
}}
{{
#
if
editable
}}
...
...
@@ -82,7 +82,7 @@
<
/a
>
{{
/
if
}}
{{
else
}}
<
a
href
=
"
{{href}}
"
class
=
"
ui-link
"
>
{{
tex
t
}}
<
/a
>
<
a
href
=
"
{{href}}
"
class
=
"
ui-link
"
>
{{
defaul
t
}}
<
/a
>
{{
/
if
}}
<
/td
>
{{
/
each
}}
...
...
@@ -101,7 +101,7 @@
<script
id=
"listbox-show-tbody-template"
type=
"text/x-handlebars-template"
>
<
table
>
<
tbody
class
=
"
tbody
"
>
{{
#
each
body_value
}}
{{
#
each
row_list
}}
<
tr
>
{{
#
if
..
/
show_anchor
}}
<
th
>
...
...
@@ -111,7 +111,7 @@
<
td
>
<
input
value
=
"
{{value}}
"
type
=
"
checkbox
"
checked
=
"
true
"
class
=
"
hide_element
"
>
<
/td
>
{{
#
each
tr_value
}}
{{
#
each
cell_list
}}
<
td
>
{{
#
if
type
}}
{{
#
if
editable
}}
...
...
@@ -122,7 +122,7 @@
<
/a
>
{{
/
if
}}
{{
else
}}
<
a
href
=
"
{{href}}
"
class
=
"
ui-link
"
>
{{
tex
t
}}
<
/a
>
<
a
href
=
"
{{href}}
"
class
=
"
ui-link
"
>
{{
defaul
t
}}
<
/a
>
{{
/
if
}}
<
/td
>
{{
/
each
}}
...
...
@@ -140,19 +140,40 @@
<script
id=
"listbox-tfoot-template"
type=
"text/x-handlebars-template"
>
<
table
>
<
tfoot
class
=
"
ui-bar-inherit tfoot
"
>
<
th
colspan
=
"
{{colspan}}
"
>
<
div
class
=
"
ui-controlgroup ui-controlgroup-horizontal ui-corner-all ui-paging-menu
"
>
<
div
class
=
"
ui-controlgroup-controls
"
>
<
a
class
=
"
{{previous_classname}}
"
data
-
i18n
=
"
Previous
"
href
=
"
{{previous_url}}
"
>
Previous
<
/a
>
<
a
class
=
"
{{next_classname}}
"
data
-
i18n
=
"
Next
"
href
=
"
{{next_url}}
"
>
Next
<
/a
>
<
span
class
=
"
ui-btn ui-disabled
"
data
-
i18n
=
"
{{record}}
"
>
{{
record
}}
<
/span
>
<
/div
>
<
/div
>
<
/th
>
{{
#
each
row_list
}}
<
tr
>
{{
#
if
..
/
show_anchor
}}
<
td
>
Total
<
/td
>
{{
/
if
}}
{{
#
each
cell_list
}}
<
td
>
{{
#
if
type
}}
<
div
class
=
"
editable_div
"
data
-
column
=
"
{{column}}
"
data
-
line
=
"
{{line}}
"
><
/div
>
{{
else
}}
{{
#
if
default
}}
{{
default
}}
{{
else
}}
{{
#
unless
..
/
..
/
show_anchor
}}
{{
#
if
@
first
}}
Total
{{
/if}
}
{{
/unless}
}
{{
/if}
}
{{
/if}
}
<
/td
>
{{
/each}
}
<
/tr
>
{{
/each}
}
<
/tfoot
>
<
/table
>
</script>
<script
id=
"listbox-nav-template"
type=
"text/x-handlebars-template"
>
<
a
class
=
"
{{previous_classname}}
"
data
-
i18n
=
"
Previous
"
href
=
"
{{previous_url}}
"
>
Previous
<
/a
>
<
a
class
=
"
{{next_classname}}
"
data
-
i18n
=
"
Next
"
href
=
"
{{next_url}}
"
>
Next
<
/a
>
<
span
class
=
"
ui-disabled ui-right
"
data
-
i18n
=
"
{{record}}
"
>
{{
record
}}
<
/span
>
</script>
<script
id=
"listbox-template"
type=
"text/x-handlebars-template"
>
<
div
class
=
"
ui-table-header ui-header ui-bar-c ui-corner-all
"
>
<
h1
data
-
i18n
=
"
{{title}}
"
class
=
"
ui-title ui-override-theme
"
>
{{
title
}}
<
span
>
<
span
class
=
"
listboxloader ui-icon-spinner ui-btn-icon-left
"
><
/span></
span
><
/h1
>
...
...
@@ -165,11 +186,11 @@
<
tbody
><
/tbody
>
<
tfoot
class
=
"
ui-bar-inherit tfoot
"
><
/tfoot
>
<
/table
>
<
nav
><
/nav
>
<
/div
>
</script>
<script
id=
"error-message-template"
type=
"text/x-handlebars-template"
>
<
div
class
=
"
ui-listbox-error
"
>
<
a
class
=
"
ui-btn ui-corner-all ui-btn-inline
"
href
=
"
{{reset_url}}
"
>
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_html.xml
View file @
8fdc1a15
...
...
@@ -234,7 +234,7 @@
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
964.
27340.60822.54681
</string>
</value>
<value>
<string>
964.
45882.29366.36147
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
...
...
@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>
151
4393372.0
</float>
<float>
151
5514305.55
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_js.js
View file @
8fdc1a15
...
...
@@ -28,6 +28,11 @@
.
innerHTML
,
listbox_tfoot_template
=
Handlebars
.
compile
(
listbox_tfoot_source
),
listbox_nav_source
=
gadget_klass
.
__template_element
.
getElementById
(
"
listbox-nav-template
"
)
.
innerHTML
,
listbox_nav_template
=
Handlebars
.
compile
(
listbox_nav_source
),
listbox_source
=
gadget_klass
.
__template_element
.
getElementById
(
"
listbox-template
"
)
.
innerHTML
,
...
...
@@ -41,88 +46,80 @@
loading_class_list
=
[
'
ui-icon-spinner
'
,
'
ui-btn-icon-left
'
],
disabled_class
=
'
ui-disabled
'
;
function
renderSubField
(
gadget
,
element
,
sub_field_json
)
{
sub_field_json
.
editable
=
sub_field_json
.
editable
&&
gadget
.
state
.
editable
;
return
gadget
.
declareGadget
(
'
gadget_erp5_label_field.html
'
,
{
element
:
element
,
scope
:
sub_field_json
.
key
}
)
.
push
(
function
(
cell_gadget
)
{
gadget
.
props
.
cell_gadget_list
.
push
(
cell_gadget
);
return
cell_gadget
.
render
({
field_type
:
sub_field_json
.
type
,
field_json
:
sub_field_json
,
label
:
false
});
});
}
function
renderEditableField
(
gadget
,
element
,
column_list
)
{
function
renderEditableField
(
gadget
,
element
,
column_list
,
field_table
)
{
var
i
,
promise_list
=
[],
uid_value_dict
=
{},
uid_value
,
column
,
line
,
element_list
=
element
.
querySelectorAll
(
"
.editable_div
"
);
gadget
.
props
.
listbox_uid_dict
=
{};
gadget
.
props
.
cell_gadget_list
=
[];
function
renderSubCell
(
element
,
sub_field_json
)
{
sub_field_json
.
editable
=
sub_field_json
.
editable
&&
gadget
.
state
.
editable
;
// XXX
return
gadget
.
declareGadget
(
'
gadget_erp5_label_field.html
'
,
{
element
:
element
,
scope
:
sub_field_json
.
key
})
.
push
(
function
(
cell_gadget
)
{
gadget
.
props
.
cell_gadget_list
.
push
(
cell_gadget
);
return
cell_gadget
.
render
({
field_type
:
sub_field_json
.
type
,
field_json
:
sub_field_json
,
label
:
false
});
});
}
for
(
i
=
0
;
i
<
element_list
.
length
;
i
+=
1
)
{
column
=
element_list
[
i
].
getAttribute
(
"
data-column
"
);
line
=
element_list
[
i
].
getAttribute
(
"
data-line
"
);
if
(
gadget
.
props
.
listbox_uid_dict
.
key
===
undefined
)
{
gadget
.
props
.
listbox_uid_dict
.
key
=
gadget
.
state
.
allDocs_result
.
data
.
rows
[
line
].
value
[
"
listbox_uid:list
"
].
key
;
gadget
.
props
.
listbox_uid_dict
.
value
=
[
gadget
.
state
.
allDocs_result
.
data
.
rows
[
line
].
value
[
"
listbox_uid:list
"
].
value
];
uid_value_dict
[
gadget
.
state
.
allDocs_result
.
data
.
rows
[
line
].
value
[
"
listbox_uid:list
"
].
value
]
=
null
;
}
else
{
uid_value
=
gadget
.
state
.
allDocs_result
.
data
.
rows
[
line
].
value
[
"
listbox_uid:list
"
].
value
;
if
(
!
uid_value_dict
.
hasOwnProperty
(
uid_value
))
{
uid_value_dict
[
uid_value
]
=
null
;
gadget
.
props
.
listbox_uid_dict
.
value
.
push
(
uid_value
);
}
}
promise_list
.
push
(
renderSubCell
(
element_list
[
i
],
gadget
.
state
.
allDocs_result
.
data
.
rows
[
line
].
value
[
column_list
[
column
][
0
]]
||
""
));
promise_list
.
push
(
renderSubField
(
gadget
,
element_list
[
i
],
field_table
[
line
].
cell_list
[
column
]
||
""
));
}
return
RSVP
.
all
(
promise_list
);
}
/**Put resulting `row_list` into `template` together with necessary gadget.state parameters.
function
renderListboxTbody
(
gadget
,
template
,
body_value
)
{
var
tmp
,
First, it removes all similar containers from within the table! Currently it is tricky
to have multiple tbody/thead/tfoot elements! Feel free to refactor.
Example call: renderTablePart(gadget, compiled_template, row_list, "tbody");
**/
function
renderTablePart
(
gadget
,
template
,
row_list
,
container_name
)
{
var
container
,
column_list
=
JSON
.
parse
(
gadget
.
state
.
column_list_json
);
return
gadget
.
translateHtml
(
template
(
{
"
body_value
"
:
body_value
,
"
row_list
"
:
row_list
,
"
show_anchor
"
:
gadget
.
state
.
show_anchor
,
"
column_list
"
:
column_list
}
))
.
push
(
function
(
my
_html
)
{
tmp
=
document
.
createElement
(
"
tbody
"
);
tmp
.
innerHTML
=
my
_html
;
return
renderEditableField
(
gadget
,
tmp
,
column
_list
);
.
push
(
function
(
table_part
_html
)
{
container
=
document
.
createElement
(
container_name
);
container
.
innerHTML
=
table_part
_html
;
return
renderEditableField
(
gadget
,
container
,
column_list
,
row
_list
);
})
.
push
(
function
()
{
var
table
=
gadget
.
element
.
querySelector
(
"
table
"
),
tbody
=
table
.
querySelector
(
"
tbody
"
);
table
.
removeChild
(
tbody
);
table
.
appendChild
(
tmp
);
old_container
=
table
.
querySelector
(
container_name
);
if
(
old_container
)
{
table
.
replaceChild
(
container
,
old_container
);
}
else
{
table
.
appendChild
(
container
);
}
return
table
;
});
}
function
renderListboxTfoot
(
gadget
,
foot
)
{
return
gadget
.
translateHtml
(
listbox_tfoot_template
(
{
"
colspan
"
:
foot
.
colspan
,
"
previous_classname
"
:
foot
.
previous_classname
,
"
previous_url
"
:
foot
.
previous_url
,
"
record
"
:
foot
.
record
,
"
next_classname
"
:
foot
.
next_classname
,
"
next_url
"
:
foot
.
next_url
}
));
}
/** Clojure to ease finding in lists of lists by the first item **/
function
hasSameFirstItem
(
a
)
{
return
function
(
b
)
{
...
...
@@ -137,7 +134,10 @@
// Init local properties
.
ready
(
function
()
{
this
.
props
=
{
// holds references to all editable sub-fields
cell_gadget_list
:
[],
// ERP5 needs listbox_uid:list with UIDs of editable sub-documents
// so it can search for them in REQUEST.form under <field.id>_<sub-document.uid>
listbox_uid_dict
:
{}
};
})
...
...
@@ -272,6 +272,9 @@
sort_list_json
:
JSON
.
stringify
(
result_list
[
1
]
||
field_json
.
sort
.
map
(
jioize_sort
)),
show_anchor
:
field_json
.
show_anchor
,
show_stat
:
field_json
.
show_stat
,
show_count
:
field_json
.
show_count
,
line_icon
:
field_json
.
line_icon
,
query
:
field_json
.
query
,
query_string
:
query_string
,
...
...
@@ -438,6 +441,8 @@
});
}
/* Function `fetchLineContent` calls changeState({"allDocs_result": JIO.allDocs()})
so this if gets re-evaluated later with allDocs_result defined. */
if
(
gadget
.
state
.
allDocs_result
===
undefined
)
{
// Trigger line content calculation
result_queue
...
...
@@ -453,7 +458,6 @@
}
else
if
((
modification_dict
.
hasOwnProperty
(
'
show_line_selector
'
))
||
(
modification_dict
.
hasOwnProperty
(
'
allDocs_result
'
)))
{
// Render the listbox content
result_queue
.
push
(
function
()
{
...
...
@@ -463,7 +467,7 @@
counter
;
column_list
=
JSON
.
parse
(
gadget
.
state
.
column_list_json
);
// for actual allDocs_result structure see ref:gadget_erp5_jio.js
if
(
lines
===
0
)
{
lines
=
allDocs_result
.
data
.
total_rows
;
counter
=
allDocs_result
.
data
.
total_rows
;
...
...
@@ -471,7 +475,7 @@
counter
=
Math
.
min
(
allDocs_result
.
data
.
total_rows
,
lines
);
}
sort_list
=
JSON
.
parse
(
gadget
.
state
.
sort_list_json
);
// Every line points to a sub-document so we need those links
for
(
i
=
0
;
i
<
counter
;
i
+=
1
)
{
promise_list
.
push
(
gadget
.
getUrlFor
({
...
...
@@ -492,31 +496,52 @@
return
RSVP
.
all
(
promise_list
);
})
.
push
(
function
(
result_list
)
{
var
value
,
body_value
=
[],
tr_value
=
[],
tmp_url
,
listbox_tbody_template
;
.
push
(
function
(
line_link_list
)
{
var
row_list
=
[],
value
,
cell_list
,
listbox_tbody_template
,
setNonEditable
=
function
(
cell
)
{
cell
.
editable
=
false
;
};
// reset list of UIDs of editable sub-documents
gadget
.
props
.
listbox_uid_dict
=
{
key
:
undefined
,
value
:
[]
};
// clear list of previous sub-gadgets
gadget
.
props
.
cell_gadget_list
=
[];
for
(
i
=
0
;
i
<
counter
;
i
+=
1
)
{
tmp_url
=
result_list
[
i
];
tr_value
=
[];
cell_list
=
[];
for
(
j
=
0
;
j
<
column_list
.
length
;
j
+=
1
)
{
value
=
allDocs_result
.
data
.
rows
[
i
].
value
[
column_list
[
j
][
0
]]
||
""
;
tr_value
.
push
({
"
type
"
:
value
.
type
,
"
editable
"
:
value
.
editable
&&
gadget
.
state
.
editable
,
"
href
"
:
tmp_url
,
"
text
"
:
value
,
"
line
"
:
i
,
"
column
"
:
j
});
// value can be simply just a value in case of non-editable field
// thus we construct "field_json" manually and insert the value in "default"
if
(
value
.
constructor
!==
Object
)
{
value
=
{
'
editable
'
:
0
,
'
default
'
:
value
};
}
value
.
href
=
line_link_list
[
i
];
value
.
editable
=
value
.
editable
&&
gadget
.
state
.
editable
;
value
.
line
=
i
;
value
.
column
=
j
;
cell_list
.
push
(
value
);
}
// note row's editable UID into gadget.props.listbox_uid_dict if exists to send it back to ERP5
// together with ListBox data. The listbox_uid_dict has quite surprising structure {key: <key>, value: <uid-array>}
if
(
allDocs_result
.
data
.
rows
[
i
].
value
[
'
listbox_uid:list
'
]
!==
undefined
)
{
gadget
.
props
.
listbox_uid_dict
.
key
=
allDocs_result
.
data
.
rows
[
i
].
value
[
'
listbox_uid:list
'
].
key
;
gadget
.
props
.
listbox_uid_dict
.
value
.
push
(
allDocs_result
.
data
.
rows
[
i
].
value
[
'
listbox_uid:list
'
].
value
);
// we could come up with better name than "value" for almost everything ^^
}
else
{
// if the document does not have listbox_uid:list then no gadget should be editable
cell_list
.
forEach
(
setNonEditable
);
}
body_value
.
push
({
"
value
"
:
allDocs_result
.
data
.
rows
[
i
].
value
.
uid
,
"
jump
"
:
tmp_url
,
"
tr_value
"
:
tr_value
,
row_list
.
push
({
"
uid
"
:
allDocs_result
.
data
.
rows
[
i
].
value
.
uid
,
"
jump
"
:
line_link_list
[
i
]
,
"
cell_list
"
:
cell_list
,
"
line_icon
"
:
gadget
.
state
.
line_icon
});
}
...
...
@@ -527,7 +552,7 @@
listbox_tbody_template
=
listbox_hidden_tbody_template
;
}
return
render
ListboxTbody
(
gadget
,
listbox_tbody_template
,
body_value
);
return
render
TablePart
(
gadget
,
listbox_tbody_template
,
row_list
,
"
tbody
"
);
})
.
push
(
function
()
{
var
prev_param
=
{},
...
...
@@ -551,31 +576,70 @@
})
.
push
(
function
(
url_list
)
{
var
foot
=
{};
foot
.
colspan
=
column_list
.
length
+
gadget
.
state
.
show_anchor
+
(
gadget
.
state
.
line_icon
?
1
:
0
)
+
gadget
.
state
.
show_line_selector
;
foot
.
previous_classname
=
"
ui-btn ui-icon-carat-l ui-btn-icon-left responsive ui-first-child
"
;
foot
.
previous_url
=
url_list
[
0
];
foot
.
next_classname
=
"
ui-btn ui-icon-carat-r ui-btn-icon-right responsive ui-last-child
"
;
foot
.
next_url
=
url_list
[
1
];
var
record
,
previous_url
=
url_list
[
0
],
next_url
=
url_list
[
1
],
previous_classname
=
"
ui-btn ui-icon-carat-l ui-btn-icon-left responsive ui-first-child
"
,
next_classname
=
"
ui-btn ui-icon-carat-r ui-btn-icon-right responsive ui-last-child
"
;
if
((
gadget
.
state
.
begin_from
===
0
)
&&
(
counter
===
0
))
{
foot
.
record
=
variable
.
translated_no_record
;
record
=
variable
.
translated_no_record
;
}
else
if
((
allDocs_result
.
data
.
rows
.
length
<=
lines
)
&&
(
gadget
.
state
.
begin_from
===
0
))
{
foot
.
record
=
counter
+
"
"
+
variable
.
translated_records
;
record
=
counter
+
"
"
+
variable
.
translated_records
;
}
else
{
foot
.
record
=
variable
.
translated_records
+
"
"
+
(((
gadget
.
state
.
begin_from
+
lines
)
/
lines
-
1
)
*
lines
+
1
)
+
"
-
"
+
(((
gadget
.
state
.
begin_from
+
lines
)
/
lines
-
1
)
*
lines
+
counter
);
record
=
variable
.
translated_records
+
"
"
+
(((
gadget
.
state
.
begin_from
+
lines
)
/
lines
-
1
)
*
lines
+
1
)
+
"
-
"
+
(((
gadget
.
state
.
begin_from
+
lines
)
/
lines
-
1
)
*
lines
+
counter
);
}
if
(
gadget
.
state
.
begin_from
===
0
)
{
foot
.
previous_classname
+=
"
ui-disabled
"
;
previous_classname
+=
"
ui-disabled
"
;
}
if
(
allDocs_result
.
data
.
rows
.
length
<=
lines
)
{
foot
.
next_classname
+=
"
ui-disabled
"
;
next_classname
+=
"
ui-disabled
"
;
}
return
renderListboxTfoot
(
gadget
,
foot
);
return
gadget
.
translateHtml
(
listbox_nav_template
({
"
previous_classname
"
:
previous_classname
,
"
previous_url
"
:
previous_url
,
"
record
"
:
record
,
"
next_classname
"
:
next_classname
,
"
next_url
"
:
next_url
})
)
.
push
(
function
(
listbox_nav_html
)
{
gadget
.
element
.
querySelector
(
'
nav
'
).
innerHTML
=
listbox_nav_html
;
});
})
.
push
(
function
(
my_html
)
{
gadget
.
element
.
querySelector
(
"
.tfoot
"
).
innerHTML
=
my_html
;
.
push
(
function
()
{
var
result_sum
=
(
gadget
.
state
.
allDocs_result
.
sum
||
{}).
rows
||
[],
// render summary footer if available
summary
=
result_sum
.
map
(
function
(
row
,
row_index
)
{
var
row_editability
=
row
[
'
listbox_uid:list
'
]
!==
undefined
;
return
{
"
uid
"
:
'
summary
'
+
row_index
,
"
cell_list
"
:
column_list
.
map
(
function
(
col_name
,
col_index
)
{
var
field_json
=
row
.
value
[
col_name
[
0
]]
||
""
;
if
(
field_json
.
constructor
!==
Object
)
{
field_json
=
{
'
default
'
:
field_json
,
'
editable
'
:
0
};
}
field_json
.
editable
=
field_json
.
editable
&&
row_editability
;
field_json
.
column
=
col_index
;
field_json
.
line
=
row_index
;
return
field_json
;
})
};
}),
element
;
if
(
counter
===
0
)
{
// do not render footer (summary) when no data in Listbox because it is ugly
element
=
gadget
.
element
.
querySelector
(
"
table tfoot tr
"
);
if
(
element
!==
null
)
{
element
.
remove
();
}
return
null
;
}
return
renderTablePart
(
gadget
,
listbox_tfoot_template
,
summary
,
"
tfoot
"
);
})
.
push
(
function
()
{
var
loading_element_classList
=
gadget
.
element
.
querySelector
(
"
.listboxloader
"
).
classList
;
loading_element_classList
.
remove
.
apply
(
loading_element_classList
,
loading_class_list
);
});
...
...
@@ -616,7 +680,8 @@
var
gadget
=
this
,
select_list
=
[],
limit_options
,
limit_options
=
[],
aggregation_option_list
=
[],
column_list
=
JSON
.
parse
(
gadget
.
state
.
column_list_json
),
i
;
...
...
@@ -631,6 +696,12 @@
limit_options
=
[
gadget
.
state
.
begin_from
,
gadget
.
state
.
lines
+
1
];
}
if
(
gadget
.
state
.
show_stat
===
true
)
{
aggregation_option_list
.
push
(
"
sum
"
);
}
if
(
gadget
.
state
.
show_count
===
true
)
{
aggregation_option_list
.
push
(
"
count
"
);
}
return
gadget
.
jio_allDocs
({
// XXX Not jIO compatible, but until a better api is found...
...
...
@@ -638,6 +709,7 @@
"
query
"
:
gadget
.
state
.
query_string
,
"
limit
"
:
limit_options
,
"
select_list
"
:
select_list
,
// "aggregation": aggregation_option_list
"
sort_on
"
:
JSON
.
parse
(
gadget
.
state
.
sort_list_json
)
})
.
push
(
function
(
result
)
{
...
...
@@ -647,7 +719,7 @@
},
function
(
error
)
{
// do not crash interface if allDocs fails
//this will catch all error, not only search criteria invalid error
//
this will catch all error, not only search criteria invalid error
if
(
error
instanceof
RSVP
.
CancellationError
)
{
throw
error
;
}
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_listbox_js.xml
View file @
8fdc1a15
...
...
@@ -75,12 +75,6 @@
<none/>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
gadget_erp5_field_listbox.js
</string>
</value>
...
...
@@ -242,7 +236,7 @@
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
964.
28739.16428.44868
</string>
</value>
<value>
<string>
964.
47502.56518.25890
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
...
...
@@ -260,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>
151
4478789.32
</float>
<float>
151
5602869.96
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_erp5_nojqm_css.css
View file @
8fdc1a15
...
...
@@ -1305,24 +1305,30 @@ div[data-gadget-scope='erp5_searchfield'] div.search_parsed_value button {
.document_table
table
{
width
:
100%
;
text-align
:
left
;
/* end-of tbody, tfoot*/
}
.document_table
table
th
,
.document_table
table
td
{
vertical-align
:
middle
;
padding
:
3pt
;
}
.document_table
table
thead
{
.document_table
table
thead
,
.document_table
table
tfoot
{
background-color
:
#0E81C2
;
color
:
#FFFFFF
;
}
.document_table
table
thead
a
{
.document_table
table
thead
a
,
.document_table
table
tfoot
a
{
color
:
#FFFFFF
;
text-decoration
:
underline
;
}
.document_table
table
thead
tr
th
{
.document_table
table
thead
tr
th
,
.document_table
table
tfoot
tr
th
{
padding
:
6pt
3pt
;
}
@media
not
screen
and
(
min-width
:
45em
)
{
.document_table
table
thead
{
.document_table
table
thead
,
.document_table
table
tfoot
{
display
:
none
;
}
}
...
...
@@ -1342,7 +1348,6 @@ div[data-gadget-scope='erp5_searchfield'] div.search_parsed_value button {
@media
not
screen
and
(
max-width
:
85em
),
only
screen
and
(
min-width
:
45em
)
and
(
max-width
:
85em
)
{
.document_table
table
tbody
a
{
display
:
block
;
padding
:
3pt
;
}
}
@media
not
screen
and
(
min-width
:
45em
)
{
...
...
@@ -1411,41 +1416,46 @@ div[data-gadget-scope='erp5_searchfield'] div.search_parsed_value button {
content
:
" ~ "
;
}
}
.document_table
table
tfoot
.ui-controlgroup-controls
{
.document_table
nav
{
display
:
flex
;
padding-top
:
6pt
;
border-top
:
2px
solid
rgba
(
0
,
0
,
0
,
0.14902
);
}
.document_table
table
tfoot
.ui-controlgroup-controls
span
{
.document_table
nav
span
{
opacity
:
.3
;
flex
:
2
;
text-align
:
right
;
float
:
right
;
}
.document_table
table
tfoot
.ui-controlgroup-controls
a
{
.document_table
nav
a
{
padding
:
6pt
;
border
:
1px
solid
rgba
(
0
,
0
,
0
,
0.14
);
border-radius
:
0.325em
;
margin-right
:
6pt
;
}
.document_table
table
tfoot
.ui-controlgroup-controls
a
::before
{
.document_table
nav
a
::before
{
margin-right
:
6pt
;
}
.document_table
table
tfoot
.ui-controlgroup-controls
a
:hover
,
.document_table
table
tfoot
.ui-controlgroup-controls
a
:active
{
.document_table
nav
a
:hover
,
.document_table
nav
a
:active
{
background-color
:
#e0e0e0
;
}
.document_table
table
tfoot
.ui-controlgroup-controls
a
:last-of-type
{
.document_table
nav
a
:last-of-type
{
margin-right
:
0
;
}
.document_table
nav
a
:hover
,
.document_table
nav
a
:active
{
background-color
:
#e0e0e0
;
}
@media
not
screen
and
(
min-width
:
45em
)
{
.document_table
table
tfoot
.ui-controlgroup-controls
a
{
.document_table
nav
a
{
overflow
:
hidden
;
text-indent
:
-9999px
;
white-space
:
nowrap
;
}
}
@media
not
screen
and
(
min-width
:
45em
)
{
.document_table
table
tfoot
.ui-controlgroup-controls
a
::before
{
.document_table
nav
a
::before
{
float
:
left
;
text-indent
:
6pt
;
}
...
...
bt5/erp5_web_renderjs_ui/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui/erp5css.less.txt
View file @
8fdc1a15
...
...
@@ -1523,9 +1523,10 @@ div[data-gadget-scope='erp5_searchfield'] {
th, td {
// line-height: 1.5em;
vertical-align: middle;
padding: @half-margin-size;
}
thead {
thead
, tfoot
{
background-color: @colorsubheaderbackground;
color: @white;
...
...
@@ -1565,7 +1566,6 @@ div[data-gadget-scope='erp5_searchfield'] {
@media @desktop, @tablet {
a {
display: block;
padding: @half-margin-size;
}
}
...
...
@@ -1646,40 +1646,43 @@ div[data-gadget-scope='erp5_searchfield'] {
}
}
}
}
nav {
display: flex;
padding-top: @margin-size;
border-top: 2px solid rgba(0, 0, 0, 0.14902);
tfoot .ui-controlgroup-controls {
display: flex;
padding-top: @margin-size;
border-top: 2px solid rgba(0, 0, 0, 0.14902);
span {
opacity: .3;
flex: 2;
text-align: right;
float: right;
}
a {
.button();
span {
opacity: .3;
flex: 2;
text-align: right;
margin-right: @margin-size;
&:last-of-type {
margin-right: 0;
}
a {
.button();
margin-right: @margin-size;
&:last-of-type {
margin-right: 0;
}
&:hover, &:active {
background-color: @colorblocklinkbackground;
}
@media @smartphone {
.hide_text(@width: initial);
}
@media @smartphone {
.hide_text(@width: initial);
}
&::before {
&::before {
@media @smartphone {
float: left;
text-indent: @margin-size;
}
@media @smartphone {
float: left;
text-indent: @margin-size;
}
}
}
}
}
...
...
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
testEmptyListboxWithStat
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testEmptyListboxWithStat.zpt
0 → 100644
View file @
8fdc1a15
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
xmlns:metal=
"http://xml.zope.org/namespaces/metal"
>
<!--
Ensure empty listbox does not show stat line even though it receives stat data.
-->
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>
Test RenderJS UI ListBox No Stat Line on No Data
</title>
</head>
<body>
<table
cellpadding=
"1"
cellspacing=
"1"
border=
"1"
>
<thead>
<tr><td
rowspan=
"1"
colspan=
"3"
>
Test RenderJS UI ListBox No Stat Line on No Data
</td></tr>
</thead><tbody>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/init"
/>
<!-- Clean Up -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/ListBoxZuite_reset
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Reset Successfully.
</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>
store
</td>
<td>
${base_url}/web_site_module/renderjs_runner
</td>
<td>
renderjs_url
</td></tr>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/wait_for_activities"
/>
<!-- Let's set up the default sort correctly: id | ASC -->
<tr><td>
open
</td>
<td>
${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_stat_method=FooModule_statMethod
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Set Successfully.
</td><td></td></tr>
<tr><td>
open
</td>
<td>
${renderjs_url}/#/foo_module
</td><td></td></tr>
<tr><td>
waitForElementPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="No records"]
</td><td></td></tr>
<tr><td>
assertElementNotPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table/tfoot/tr
</td>
<td></td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testHideItem.zpt
View file @
8fdc1a15
...
...
@@ -128,11 +128,6 @@
<td>
//thead/tr/th[3]
</td>
<td>
Quantity
</td>
</tr>
<tr>
<td>
assertElementPresent
</td>
<td>
//tfoot/tr/th[@colspan="3"]
</td>
<td></td>
</tr>
<tr>
...
...
@@ -169,11 +164,6 @@
<td>
//thead/tr/th[4]
</td>
<td>
Quantity
</td>
</tr>
<tr>
<td>
assertElementPresent
</td>
<td>
//tfoot/tr/th[@colspan="4"]
</td>
<td></td>
</tr>
<!-- Line checkbox -->
...
...
@@ -233,11 +223,6 @@
<td>
//thead/tr/th[3]
</td>
<td>
Quantity
</td>
</tr>
<tr>
<td>
assertElementPresent
</td>
<td>
//tfoot/tr/th[@colspan="3"]
</td>
<td></td>
</tr>
<!-- only one element present -->
<tr>
...
...
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatColumns.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
testStatColumns
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatColumns.zpt
0 → 100644
View file @
8fdc1a15
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
xmlns:metal=
"http://xml.zope.org/namespaces/metal"
>
<!--
Ensure Stat Column methods are executed correctly and result displayed in tfoot element of the listbox table.
- if anchor, then text "Total" is present
- columns which are not present in Stat Columns do not display any data
-->
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>
Test RenderJS ListBox Stat Columns
</title>
</head>
<body>
<table
cellpadding=
"1"
cellspacing=
"1"
border=
"1"
>
<thead>
<tr><td
rowspan=
"1"
colspan=
"3"
>
Test RenderJS ListBox Stat Columns
</td></tr>
</thead><tbody>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/init"
/>
<!-- Clean Up -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/ListBoxZuite_reset
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Reset Successfully.
</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>
store
</td>
<td>
${base_url}/web_site_module/renderjs_runner
</td>
<td>
renderjs_url
</td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/FooModule_createObjects?start:int=1
&
num:int=2
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Created Successfully.
</td><td></td></tr>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/wait_for_activities"
/>
<!-- Let's set up stat column property on listbox -->
<tr><td>
open
</td>
<td>
${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_stat_columns=getQuantity+%7C+FooModule_statQuantity+%0A+title+%7C+FooModule_statTitle
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Set Successfully.
</td><td></td></tr>
<tr><td>
open
</td>
<td>
${renderjs_url}/#/foo_module
</td><td></td></tr>
<tr><td>
waitForElementPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="2 Records"]
</td><td></td></tr>
<tr><td>
store
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table
</td>
<td>
listbox_table
</td></tr>
<!-- Default sort on ID column has to be ASCENDING -->
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tbody/tr[1]/td[3]/a
</td>
<td>
9
</td></tr>
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tbody/tr[2]/td[3]/a
</td>
<td>
8
</td></tr>
<tr><td>
assertText
</td>
<!-- This tests that "Total" appears when first column has no stat defined -->
<td>
${listbox_table}/tfoot/tr[1]/td[1]
</td>
<td>
Total
</td></tr>
<tr><td>
assertText
</td>
<!-- Test multiple Stat Columns -->
<td>
${listbox_table}/tfoot/tr[1]/td[2]
</td>
<td>
Foos
</td></tr>
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tfoot/tr[1]/td[3]
</td>
<td>
17
</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMethod.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
testStatMethod
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMethod.zpt
0 → 100644
View file @
8fdc1a15
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
xmlns:metal=
"http://xml.zope.org/namespaces/metal"
>
<!--
Ensure stat_method gets executed and result displayed in tfoot element of the listbox table.
- if anchor, then text "Total" is present
- columns for which stat_method does not return any data remain empty
-->
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>
Test RenderJS UI ListBox Stat Method
</title>
</head>
<body>
<table
cellpadding=
"1"
cellspacing=
"1"
border=
"1"
>
<thead>
<tr><td
rowspan=
"1"
colspan=
"3"
>
Test RenderJS UI ListBox Stat Method
</td></tr>
</thead><tbody>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/init"
/>
<!-- Clean Up -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/ListBoxZuite_reset
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Reset Successfully.
</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>
store
</td>
<td>
${base_url}/web_site_module/renderjs_runner
</td>
<td>
renderjs_url
</td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/FooModule_createObjects?start:int=1
&
num:int=3
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Created Successfully.
</td><td></td></tr>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/wait_for_activities"
/>
<!-- Let's set up the default sort correctly: id | ASC -->
<tr><td>
open
</td>
<td>
${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList?field_stat_method=FooModule_statMethod
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Set Successfully.
</td><td></td></tr>
<tr><td>
open
</td>
<td>
${renderjs_url}/#/foo_module
</td><td></td></tr>
<tr><td>
waitForElementPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="3 Records"]
</td><td></td></tr>
<tr><td>
store
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table
</td>
<td>
listbox_table
</td></tr>
<!-- Default sort on ID column has to be ASCENDING -->
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tbody/tr[1]/td[3]/a
</td>
<td>
9
</td></tr>
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tbody/tr[2]/td[3]/a
</td>
<td>
8
</td></tr>
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tbody/tr[3]/td[3]/a
</td>
<td>
7
</td></tr>
<tr><td>
assertFloat
</td>
<!-- This tests that "Total" does not appear when first column has stat defined -->
<td>
${listbox_table}/tfoot/tr[1]/td[1]
</td>
<td>
6
</td></tr>
<tr><td>
assertFloat
</td>
<td>
${listbox_table}/tfoot/tr[1]/td[3]
</td>
<td>
24
</td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMissing.xml
0 → 100644
View file @
8fdc1a15
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
testStatMissing
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_web_renderjs_ui_test/PathTemplateItem/portal_tests/renderjs_ui_listbox_zuite/testStatMissing.zpt
0 → 100644
View file @
8fdc1a15
<html
xmlns:tal=
"http://xml.zope.org/namespaces/tal"
xmlns:metal=
"http://xml.zope.org/namespaces/metal"
>
<!--
Ensure no stat line is displayed when no stat_method and no stat_columns are defined.
-->
<head>
<meta
http-equiv=
"Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>
Test RenderJS UI ListBox Stat Missing
</title>
</head>
<body>
<table
cellpadding=
"1"
cellspacing=
"1"
border=
"1"
>
<thead>
<tr><td
rowspan=
"1"
colspan=
"3"
>
Test RenderJS UI ListBox Stat Missing
</td></tr>
</thead><tbody>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/init"
/>
<!-- Clean Up -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/ListBoxZuite_reset
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Reset Successfully.
</td><td></td></tr>
<!-- Shortcut for full renderjs url -->
<tr><td>
store
</td>
<td>
${base_url}/web_site_module/renderjs_runner
</td>
<td>
renderjs_url
</td></tr>
<!-- Create Foo objects with IDs 0-9 -->
<tr><td>
open
</td>
<td>
${base_url}/foo_module/FooModule_createObjects?start:int=1
&
num:int=3
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Created Successfully.
</td><td></td></tr>
<tal:block
metal:use-macro=
"here/Zuite_CommonTemplate/macros/wait_for_activities"
/>
<!-- Let's set up the default sort correctly: id | ASC -->
<tr><td>
open
</td>
<td>
${base_url}/FooModule_viewFooList/listbox/ListBox_setPropertyList
</td><td></td></tr>
<tr><td>
assertTextPresent
</td>
<td>
Set Successfully.
</td><td></td></tr>
<tr><td>
open
</td>
<td>
${renderjs_url}/#/foo_module
</td><td></td></tr>
<tr><td>
waitForElementPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//nav/span[@data-i18n="3 Records"]
</td><td></td></tr>
<tr><td>
assertElementNotPresent
</td>
<td>
//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//table/tfoot/tr
</td>
<td></td></tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
bt5/erp5_web_renderjs_ui_test/SkinTemplateItem/portal_skins/erp5_web_renderjs_ui_test/Zuite_CommonTemplateForRenderjsUi.zpt
View file @
8fdc1a15
...
...
@@ -247,7 +247,7 @@
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//
tfoot
//span[contains(@data-i18n, "Records")]</td>
<td>//div[contains(@data-gadget-url, 'gadget_erp5_field_listbox.html')]//
nav
//span[contains(@data-i18n, "Records")]</td>
<td></td>
</tr>
<tr>
...
...
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