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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
erp5
Commits
95fa88f5
Commit
95fa88f5
authored
Apr 07, 2017
by
Eugene Shen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge identical replicate storages to reduce repair requests
parent
69670067
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
401 additions
and
66 deletions
+401
-66
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_chat_room_js.js
...hTemplateItem/web_page_module/gadget_erp5_chat_room_js.js
+15
-20
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_html.html
...eItem/web_page_module/gadget_erp5_page_chat_box_html.html
+3
-0
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_js.js
...plateItem/web_page_module/gadget_erp5_page_chat_box_js.js
+66
-46
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_html.html
...m/web_page_module/gadget_erp5_page_chat_storage_html.html
+14
-0
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_html.xml
...em/web_page_module/gadget_erp5_page_chat_storage_html.xml
+128
-0
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_js.js
...eItem/web_page_module/gadget_erp5_page_chat_storage_js.js
+51
-0
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_js.xml
...Item/web_page_module/gadget_erp5_page_chat_storage_js.xml
+124
-0
No files found.
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_chat_room_js.js
View file @
95fa88f5
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*global window, rJS,
jIO,
btoa */
/*global window, rJS, btoa */
(
function
(
window
,
rJS
,
jIO
,
btoa
)
{
(
function
(
window
,
rJS
,
btoa
)
{
"
use strict
"
;
"
use strict
"
;
...
@@ -8,9 +8,10 @@
...
@@ -8,9 +8,10 @@
// State is set in erp5_page_chat_box.
// State is set in erp5_page_chat_box.
// The following functions
is
acquired from erp5_page_chat_box.
// The following functions
are
acquired from erp5_page_chat_box.
.
declareAcquiredMethod
(
"
joinNewRoom
"
,
"
joinNewRoom
"
)
.
declareAcquiredMethod
(
"
joinNewRoom
"
,
"
joinNewRoom
"
)
.
declareAcquiredMethod
(
"
makeJioReplicate
"
,
"
makeJioReplicate
"
)
/* Render the gadget.
/* Render the gadget.
...
@@ -28,17 +29,16 @@
...
@@ -28,17 +29,16 @@
})
})
/*
Create a new
jIO replicate storage.
/*
Use the given remote configuration to get a
jIO replicate storage.
* Parameters:
* Parameters:
* - state: query, local_sub_storage
* - fields: the jIO configuration fields from the form,
* - fields: the jIO configuration fields from the form,
* identical to the ones used in the configurators
* identical to the ones used in the configurators
* Effects:
* Effects:
* -
create a new jIO replicate storage with the given
configuration
* -
get the jIO replicate storage with the given remote
configuration
* - change to the room corresponding to the new storage
* - change to the room corresponding to the new storage
*/
*/
.
declareMethod
(
"
createJioReplicate
"
,
function
()
{
.
declareMethod
(
"
getRemoteConfiguration
"
,
function
()
{
var
gadget
=
this
,
var
gadget
=
this
,
remote_sub_storage
,
remote_sub_storage
,
fields
=
gadget
.
element
.
querySelector
(
"
.connect-form
"
).
elements
;
fields
=
gadget
.
element
.
querySelector
(
"
.connect-form
"
).
elements
;
...
@@ -69,16 +69,11 @@
...
@@ -69,16 +69,11 @@
remote_sub_storage
=
JSON
.
parse
(
fields
.
custom_configuration
.
value
);
remote_sub_storage
=
JSON
.
parse
(
fields
.
custom_configuration
.
value
);
break
;
break
;
}
}
return
gadget
.
makeJioReplicate
(
remote_sub_storage
,
gadget
.
state
.
room
)
gadget
.
state
.
storage
=
jIO
.
createJIO
({
.
push
(
function
(
jio_storage
)
{
type
:
"
replicate
"
,
gadget
.
state
.
storage
=
jio_storage
;
use_remote_post
:
true
,
conflict_handling
:
2
,
query
:
gadget
.
state
.
query
,
local_sub_storage
:
gadget
.
state
.
local_sub_storage
,
remote_sub_storage
:
remote_sub_storage
});
return
gadget
.
joinNewRoom
(
gadget
.
state
.
room
);
return
gadget
.
joinNewRoom
(
gadget
.
state
.
room
);
});
})
})
...
@@ -103,13 +98,13 @@
...
@@ -103,13 +98,13 @@
})
})
// Call
createJioReplicate
when the form is submitted.
// Call
getRemoteConfiguration
when the form is submitted.
.
onEvent
(
"
submit
"
,
function
(
event
)
{
.
onEvent
(
"
submit
"
,
function
(
event
)
{
var
gadget
=
this
;
var
gadget
=
this
;
if
(
event
.
target
.
className
===
"
connect-form
"
)
{
if
(
event
.
target
.
className
===
"
connect-form
"
)
{
return
gadget
.
createJioReplicate
(
event
);
return
gadget
.
getRemoteConfiguration
(
event
);
}
}
});
});
}(
window
,
rJS
,
jIO
,
btoa
));
}(
window
,
rJS
,
btoa
));
\ No newline at end of file
\ No newline at end of file
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_html.html
View file @
95fa88f5
...
@@ -26,6 +26,9 @@
...
@@ -26,6 +26,9 @@
</script>
</script>
</head>
</head>
<body>
<body>
<div
data-gadget-url=
"gadget_erp5_page_chat_storage.html"
data-gadget-scope=
"storage_gadget"
data-gadget-sandbox=
"public"
></div>
<div
class=
"chat-box"
>
<div
class=
"chat-box"
>
<div
class=
"chat-left-panel"
>
<div
class=
"chat-left-panel"
>
<h3
class=
"center"
>
Contacts
</h3>
<h3
class=
"center"
>
Contacts
</h3>
...
...
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_box_js.js
View file @
95fa88f5
...
@@ -212,11 +212,12 @@
...
@@ -212,11 +212,12 @@
// i.e. {quiet_room: 3, busy_room: 429}
// i.e. {quiet_room: 3, busy_room: 429}
message_count_dict
:
{},
message_count_dict
:
{},
// a dict of room names to an object with keys corresponding to
// the index of the stored polling interval in POLL_DELAY_LIST
// their delayRefresh promise queues, i.e. queue: new RSVP.Queue()
delay_refresh_index
:
0
,
// their POLL_DELAY_LIST indices, i.e. index: 3, and
// the stored promise queue to run delayRefresh
// whether each is currently running refreshChat, i.e. lock: true
delay_refresh_queue
:
new
RSVP
.
Queue
(),
delay_refresh_dict
:
{},
// true if refreshChat is currently being executed, otherwise false
delay_refresh_lock
:
false
,
// true to use alert_icon_url, false to use default_icon_url
// true to use alert_icon_url, false to use default_icon_url
favicon_alert
:
false
,
favicon_alert
:
false
,
...
@@ -263,6 +264,46 @@
...
@@ -263,6 +264,46 @@
})
})
/* Wrap the call to make a jIO replicate storage.
* This function is acquired by gadget_erp5_chat_room.
* Parameters:
* - param_list[0]: the jIO parameters of the remote storage
* - param_list[1]: the name of the room that requested the storage
* Effects:
* - call storage_gadget.createJioReplicate()
* Returns:
* - the jIO replicate storage created with the given parameters
* regardless of whether it was previously or presently created
*/
.
allowPublicAcquisition
(
"
makeJioReplicate
"
,
function
(
param_list
)
{
var
gadget
=
this
;
return
gadget
.
getDeclaredGadget
(
"
storage_gadget
"
)
.
push
(
function
(
storage_gadget
)
{
// all_query makes only one replicate storage for one ERP5
var
all_query
=
'
portal_type: "Text Post"
'
,
// room_query makes one replicate storage for every room
// XXX store room in description because description is
// indexed in ERP5, and only indexed properties can be queried
room_query
=
'
portal_type: "Text Post" AND description: "
'
+
param_list
[
1
]
+
'
"
'
;
return
storage_gadget
.
createJioReplicate
(
gadget
.
state
.
local_sub_storage
,
param_list
[
0
],
{
query
:
all_query
,
limit
:
[
0
,
JIO_QUERY_MAX_LIMIT
],
select_list
:
[
"
content
"
],
sort_on
:
[
[
"
date_ms
"
,
"
ascending
"
],
[
"
content
"
,
"
ascending
"
]
]
}
);
});
})
/* Render everything again when the current state changes.
/* Render everything again when the current state changes.
* Parameters: all properties in gadget.state
* Parameters: all properties in gadget.state
* Effects:
* Effects:
...
@@ -464,21 +505,9 @@
...
@@ -464,21 +505,9 @@
.
appendChild
(
room_gadget
.
element
);
.
appendChild
(
room_gadget
.
element
);
return
room_gadget
.
changeState
({
return
room_gadget
.
changeState
({
room
:
room
,
room
:
room
,
local_sub_storage
:
gadget
.
state
.
local_sub_storage
,
default_jio_type
:
gadget
.
state
.
default_jio_type
,
default_jio_type
:
gadget
.
state
.
default_jio_type
,
default_erp5_url
:
gadget
.
state
.
default_erp5_url
,
default_erp5_url
:
gadget
.
state
.
default_erp5_url
,
default_dav_url
:
gadget
.
state
.
default_dav_url
,
default_dav_url
:
gadget
.
state
.
default_dav_url
// XXX store room in description because description is
// indexed in ERP5, and only indexed properties can be queried
query
:
{
query
:
'
portal_type: "Text Post" AND description: "
'
+
room
+
'
"
'
,
limit
:
[
0
,
JIO_QUERY_MAX_LIMIT
],
select_list
:
[
"
content
"
],
sort_on
:
[
[
"
date_ms
"
,
"
ascending
"
],
[
"
content
"
,
"
ascending
"
]
]
}
});
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
...
@@ -487,11 +516,6 @@
...
@@ -487,11 +516,6 @@
.
push
(
function
()
{
.
push
(
function
()
{
gadget
.
state
.
message_list_dict
[
room
]
=
[];
gadget
.
state
.
message_list_dict
[
room
]
=
[];
gadget
.
state
.
message_count_dict
[
room
]
=
0
;
gadget
.
state
.
message_count_dict
[
room
]
=
0
;
gadget
.
state
.
delay_refresh_dict
[
room
]
=
{
queue
:
new
RSVP
.
Queue
(),
index
:
0
,
lock
:
false
};
gadget
.
state
.
id_to_name
[
"
chat-contact-
"
+
nameToId
(
room
)]
=
room
;
gadget
.
state
.
id_to_name
[
"
chat-contact-
"
+
nameToId
(
room
)]
=
room
;
return
gadget
.
changeState
({
room
:
room
,
is_chat
:
false
});
return
gadget
.
changeState
({
room
:
room
,
is_chat
:
false
});
});
});
...
@@ -589,7 +613,8 @@
...
@@ -589,7 +613,8 @@
author
:
message
.
name
,
author
:
message
.
name
,
date_ms
:
getTime
(
message
),
date_ms
:
getTime
(
message
),
room
:
message
.
room
,
room
:
message
.
room
,
description
:
message
.
room
,
// XXX to index rooms using ERP5 queries, uncomment the following
// description: message.room,
content
:
JSON
.
stringify
(
message
)
content
:
JSON
.
stringify
(
message
)
}]);
}]);
});
});
...
@@ -602,7 +627,7 @@
...
@@ -602,7 +627,7 @@
* - poll_delay_index: the index in POLL_DELAY_LIST of
* - poll_delay_index: the index in POLL_DELAY_LIST of
* the time in milliseconds to wait before refreshing again
* the time in milliseconds to wait before refreshing again
* Requirements:
* Requirements:
* - gadget.state.delay_refresh_
dict[room].
queue has new RSVP.Queue() in it
* - gadget.state.delay_refresh_queue has new RSVP.Queue() in it
* Effects:
* Effects:
* - call refreshChat and wait a while before calling it again
* - call refreshChat and wait a while before calling it again
*/
*/
...
@@ -647,23 +672,18 @@
...
@@ -647,23 +672,18 @@
* - so, do nothing
* - so, do nothing
*/
*/
.
push
(
function
()
{
.
push
(
function
()
{
if
(
poll_delay_index
<
gadget
.
state
.
delay_refresh_
dict
[
room
].
index
if
(
poll_delay_index
<
gadget
.
state
.
delay_refresh_index
&&
!
gadget
.
state
.
delay_refresh_
dict
[
room
].
lock
)
{
&&
!
gadget
.
state
.
delay_refresh_lock
)
{
gadget
.
state
.
delay_refresh_
dict
[
room
].
queue
.
cancel
();
gadget
.
state
.
delay_refresh_queue
.
cancel
();
}
}
if
(
poll_delay_index
<=
gadget
.
state
.
delay_refresh_dict
[
room
].
index
)
{
if
(
poll_delay_index
<=
gadget
.
state
.
delay_refresh_index
)
{
gadget
.
state
.
delay_refresh_dict
[
room
]
=
{
// delayRefresh() is immediately called after this line
// delayRefresh() is immediately called after this line
// and can be cancelled to overwrite longer intervals
// and can be cancelled to overwrite longer intervals
queue
:
new
RSVP
.
Queue
()
gadget
.
state
.
delay_refresh_queue
=
new
RSVP
.
Queue
()
.
push
(
function
()
{
.
push
(
function
()
{
return
gadget
.
delayRefresh
(
room
,
poll_delay_index
+
1
);
return
gadget
.
delayRefresh
(
room
,
poll_delay_index
+
1
);
}),
});
// increase the polling interval over time
gadget
.
state
.
delay_refresh_index
=
poll_delay_index
+
1
;
index
:
poll_delay_index
+
1
,
// only refreshChat() should modify the locks
lock
:
gadget
.
state
.
delay_refresh_dict
[
room
].
lock
};
}
}
});
});
})
})
...
@@ -694,10 +714,10 @@
...
@@ -694,10 +714,10 @@
// multiple calls to repair() results in unmanageable duplication
// multiple calls to repair() results in unmanageable duplication
// atomic because JavaScript is single threaded,
// atomic because JavaScript is single threaded,
// so nothing else can run between the following four lines
// so nothing else can run between the following four lines
if
(
gadget
.
state
.
delay_refresh_
dict
[
room
].
lock
)
{
if
(
gadget
.
state
.
delay_refresh_lock
)
{
return
;
return
;
}
}
gadget
.
state
.
delay_refresh_
dict
[
room
].
lock
=
true
;
gadget
.
state
.
delay_refresh_lock
=
true
;
return
gadget
.
getDeclaredGadget
(
"
room-gadget-
"
+
room
)
return
gadget
.
getDeclaredGadget
(
"
room-gadget-
"
+
room
)
.
push
(
function
(
sub_gadget
)
{
.
push
(
function
(
sub_gadget
)
{
...
@@ -761,9 +781,9 @@
...
@@ -761,9 +781,9 @@
// release the lock no matter what errors occur
// release the lock no matter what errors occur
.
push
(
function
()
{
.
push
(
function
()
{
gadget
.
state
.
delay_refresh_
dict
[
room
].
lock
=
false
;
gadget
.
state
.
delay_refresh_lock
=
false
;
},
function
()
{
},
function
()
{
gadget
.
state
.
delay_refresh_
dict
[
room
].
lock
=
false
;
gadget
.
state
.
delay_refresh_lock
=
false
;
});
});
})
})
...
...
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_html.html
0 → 100644
View file @
95fa88f5
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1"
>
<title>
OfficeJS Chat Storage
</title>
<script
src=
"rsvp.js"
></script>
<script
src=
"renderjs.js"
></script>
<script
src=
"jiodev.js"
></script>
<script
src=
"gadget_erp5_page_chat_storage.js"
></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_html.xml
0 → 100644
View file @
95fa88f5
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Web Page"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Access_contents_information_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
<string>
Owner
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Change_local_roles_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Modify_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_View_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
<string>
Owner
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
classification/collaborative/team
</string>
<string>
contributor/person_module/1
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
content_md5
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
gadget_erp5_page_chat_storage.html
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
gadget_erp5_page_chat_storage_html
</string>
</value>
</item>
<item>
<key>
<string>
language
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Web Page
</string>
</value>
</item>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
OfficeJS Page Chat Storage
</string>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_js.js
0 → 100644
View file @
95fa88f5
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*global window, rJS, jIO */
(
function
(
window
,
rJS
,
jIO
)
{
"
use strict
"
;
rJS
(
window
)
// initialize dictionary of createJIO parameters to the resulting storages,
// i.e. {"{type: "replicate", local_sub_storage: ...}": JioProxyStorage}
.
setState
({
jio_storage_dict
:
[]
})
/* Create a jIO replicate storage.
* Parameters:
* - local: the jIO parameters of the local storage
* - remote: the jIO parameters of the remote storage
* - query: the jIO query of the replicate storage, optional
* Effects:
* - if it does not yet exist, create a new jIO replicate storage
* between the given local storage and the given remote storage
* Returns:
* - the jIO replicate storage created with the given parameters
* regardless of whether it was previously or presently created
*/
.
declareMethod
(
"
createJioReplicate
"
,
function
(
local
,
remote
,
query
)
{
var
gadget
=
this
,
param_string
,
param_dict
=
{
type
:
"
replicate
"
,
use_remote_post
:
true
,
conflict_handling
:
2
,
local_sub_storage
:
local
,
remote_sub_storage
:
remote
};
if
(
query
!==
undefined
)
{
param_dict
.
query
=
query
;
}
param_string
=
JSON
.
stringify
(
param_dict
);
if
(
!
gadget
.
state
.
jio_storage_dict
.
hasOwnProperty
(
param_string
))
{
gadget
.
state
.
jio_storage_dict
[
param_string
]
=
jIO
.
createJIO
(
param_dict
);
}
return
gadget
.
state
.
jio_storage_dict
[
param_string
];
});
}(
window
,
rJS
,
jIO
));
\ No newline at end of file
bt5/officejs_eyqs/PathTemplateItem/web_page_module/gadget_erp5_page_chat_storage_js.xml
0 → 100644
View file @
95fa88f5
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Web Script"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Access_contents_information_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
<string>
Owner
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Change_local_roles_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Modify_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_View_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
<string>
Owner
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
classification/collaborative/team
</string>
<string>
contributor/person_module/1
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
content_md5
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
gadget_erp5_page_chat_storage.js
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
gadget_erp5_page_chat_storage_js
</string>
</value>
</item>
<item>
<key>
<string>
language
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Web Script
</string>
</value>
</item>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
OfficeJS Page Chat Storage JS
</string>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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