Commit 3d140d6e authored by Douglas's avatar Douglas Committed by Ivan Tyagov

wendelin: all business templates migrated to new format

@Tyagov all templates from the Wendelin repository migrated to new format using Portal Template's import/export tool. 

/reviewed-on !17
parent b8833063
from Products.ERP5Type.Utils import isValidTALESExpression
from Products.Formulator.Errors import ValidationError
if not value:
return True
valid, message = isValidTALESExpression("python: getindex[%s]" % value)
if valid:
return True
raise ValidationError('external_validator_failed', context, error_text=message)
...@@ -48,19 +48,6 @@ ...@@ -48,19 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Utils import isValidTALESExpression\n
from Products.Formulator.Errors import ValidationError\n
if not value:\n
return True\n
\n
valid, message = isValidTALESExpression("python: getindex[%s]" % value)\n
if valid:\n
return True\n
raise ValidationError(\'external_validator_failed\', context, error_text=message)\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>value, REQUEST</string> </value> <value> <string>value, REQUEST</string> </value>
......
# return columns from shape of axis 1 of ndarray
# never return more than the first 100 columns
array = context.getArray()
if array is None:
return []
else:
if len(context.getArrayShape()) < 2:
return [('index', 'Index'), ('1', '1')]
else:
return [('index', 'Index')] + [(str(i), str(i)) for i in range(min(context.getArrayShape()[1], 100))]
...@@ -48,26 +48,6 @@ ...@@ -48,26 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
# return columns from shape of axis 1 of ndarray\n
# never return more than the first 100 columns\n
array = context.getArray()\n
\n
if array is None:\n
return []\n
\n
else:\n
if len(context.getArrayShape()) < 2:\n
return [(\'index\', \'Index\'), (\'1\', \'1\')]\n
else:\n
return [(\'index\', \'Index\')] + [(str(i), str(i)) for i in range(min(context.getArrayShape()[1], 100))]\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
from Products.ERP5Type.Document import newTempBase
if context.getArray() is None:
return []
class SequenceSliceMap():
def __init__(self, sequence_slice, usual_slice_length, total_length):
self.sequence_slice = sequence_slice
self.length = usual_slice_length
self.total_length = total_length
def __repr__(self):
return repr(list(self))
def __len__(self):
return self.total_length
def __getitem__(self, index):
return self.sequence_slice[index % self.length]
def createTempBase(nr, row):
def getElementFromArray(array, index):
return array[index]
def getElementFromScalar(scalar, index=None):
return scalar
column_list = [col for col in context.DataArray_getArrayColumnList() if col[0] != 'index']
column_iterator = enumerate(column_list)
if len(column_list) == 1:
getElement = getElementFromScalar
else:
getElement = getElementFromArray
return newTempBase(context.getPortalObject(),
str(id(row)),
index = nr,
**{col[0]: str(getElement(row, i)) for i, col in column_iterator})
length = context.getArrayShape()[0]
# never access more than 1000 lines at once
list_lines = min(list_lines, limit, 1000)
list_end = list_start + list_lines
if list_end > length:
list_end = length
list_start = list_end - (list_end % list_lines)
if list_start == list_end:
array_slice = [context.getArrayIndex(list_start)]
else:
array_slice = context.getArraySlice(list_start, list_end)
temp_base_list = [createTempBase(nr + list_start, row) for nr, row in enumerate(array_slice)]
# return lazy sequence of temp objects
return SequenceSliceMap(temp_base_list, list_lines, length)
...@@ -48,72 +48,6 @@ ...@@ -48,72 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from Products.ERP5Type.Document import newTempBase\n
\n
if context.getArray() is None:\n
return []\n
\n
class SequenceSliceMap():\n
def __init__(self, sequence_slice, usual_slice_length, total_length):\n
self.sequence_slice = sequence_slice\n
self.length = usual_slice_length\n
self.total_length = total_length\n
\n
def __repr__(self):\n
return repr(list(self))\n
\n
def __len__(self):\n
return self.total_length\n
\n
def __getitem__(self, index):\n
return self.sequence_slice[index % self.length]\n
\n
def createTempBase(nr, row):\n
def getElementFromArray(array, index):\n
return array[index]\n
\n
def getElementFromScalar(scalar, index=None):\n
return scalar\n
\n
column_list = [col for col in context.DataArray_getArrayColumnList() if col[0] != \'index\']\n
column_iterator = enumerate(column_list)\n
if len(column_list) == 1:\n
getElement = getElementFromScalar\n
else:\n
getElement = getElementFromArray\n
return newTempBase(context.getPortalObject(),\n
str(id(row)),\n
index = nr,\n
**{col[0]: str(getElement(row, i)) for i, col in column_iterator})\n
\n
\n
length = context.getArrayShape()[0]\n
\n
# never access more than 1000 lines at once\n
list_lines = min(list_lines, limit, 1000)\n
list_end = list_start + list_lines\n
\n
if list_end > length:\n
list_end = length\n
list_start = list_end - (list_end % list_lines)\n
\n
if list_start == list_end:\n
array_slice = [context.getArrayIndex(list_start)]\n
else:\n
array_slice = context.getArraySlice(list_start, list_end)\n
\n
temp_base_list = [createTempBase(nr + list_start, row) for nr, row in enumerate(array_slice)]\n
\n
# return lazy sequence of temp objects\n
return SequenceSliceMap(temp_base_list, list_lines, length)\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>list_start=0, list_lines=15, limit=1000, **kw</string> </value> <value> <string>list_start=0, list_lines=15, limit=1000, **kw</string> </value>
......
"""
This script returns the list of items based on the preferred
resources for events. It is intended to be used
by ListField instances.
"""
return context.Ticket_getResourceItemList(portal_type='Data Event')
...@@ -48,16 +48,6 @@ ...@@ -48,16 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
This script returns the list of items based on the preferred\n
resources for events. It is intended to be used\n
by ListField instances.\n
"""\n
return context.Ticket_getResourceItemList(portal_type=\'Data Event\')\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
"""
Get a chunks of data from a Data Stream, convert it to numpy array
and return proper start and end for next record.
This script assumes stream has following format.
{dict1}{dict2}
{dict3}
And it's possible that last chunk in its last line is incomplete dictionary
thus correction needed.
"""
import json
chunk_text = ''.join(chunk_list)
#context.log('%s %s %s' %(start, end, len(chunk_text)))
# remove last line as it might be uncomplete and correct start and end offsets
line_list = chunk_text.split('\n')
last_line = line_list[-1]
line_list.pop(-1)
for line in line_list:
# must have proper format
assert line.endswith('}')
assert line.startswith('{')
# fix ' -> "
line = line.replace("'", '"')
if line.count('{') > 1:
# multiple concatenated dictionaries in one line, bad format ignore for now
pass
else:
d = json.loads(line)
# xxx: save this value as a Data Array identified by data_array_reference
# start and enf offsets may not match existing record structure in stream
# thus corrections in start and end offsets is needed thus we
# return transformed values which is just last line length
start -= len(last_line)
end -= len(last_line)
return start, end
...@@ -48,58 +48,6 @@ ...@@ -48,58 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Get a chunks of data from a Data Stream, convert it to numpy array\n
and return proper start and end for next record.\n
\n
This script assumes stream has following format.\n
{dict1}{dict2}\n
{dict3}\n
\n
And it\'s possible that last chunk in its last line is incomplete dictionary \n
thus correction needed.\n
\n
"""\n
import json\n
\n
chunk_text = \'\'.join(chunk_list)\n
#context.log(\'%s %s %s\' %(start, end, len(chunk_text)))\n
\n
# remove last line as it might be uncomplete and correct start and end offsets\n
line_list = chunk_text.split(\'\\n\')\n
last_line = line_list[-1]\n
line_list.pop(-1)\n
\n
for line in line_list:\n
# must have proper format\n
assert line.endswith(\'}\')\n
assert line.startswith(\'{\')\n
\n
# fix \' -> "\n
line = line.replace("\'", \'"\')\n
\n
if line.count(\'{\') > 1:\n
# multiple concatenated dictionaries in one line, bad format ignore for now\n
pass \n
else:\n
d = json.loads(line)\n
# xxx: save this value as a Data Array identified by data_array_reference\n
\n
# start and enf offsets may not match existing record structure in stream\n
# thus corrections in start and end offsets is needed thus we\n
# return transformed values which is just last line length\n
start -= len(last_line)\n
end -= len(last_line)\n
\n
return start, end\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>chunk_list, start, end, data_array_reference=None</string> </value> <value> <string>chunk_list, start, end, data_array_reference=None</string> </value>
......
"""
Simply a wrapper to real method.
"""
total_stream_length = context.getSize()
if start > total_stream_length:
# end reached
return
data_stream_chunk_list = context.readChunkList(start, end)
# do call transformation script
if transform_script_id is not None:
transform_script = getattr(context, transform_script_id, None)
if transform_script is not None:
start, end = transform_script(context, data_stream_chunk_list, \
start, \
end, \
data_array_reference, \
**kw)
# [warning] store current position offset in Data Stream, this can cause easily
# ConflictErrors and it spawns re-index activities on DataStream. Thus
# disable for now.
#context.setIntOffsetIndex(end)
# start another read in another activity
start += chunk_length
end += chunk_length
if end > total_stream_length:
# no read beyond end of stream
end = total_stream_length
if recursive:
# some bytes left ...
context.activate().DataStream_readChunkListAndTransform( \
start, \
end, \
chunk_length, \
transform_script_id,\
data_array_reference,\
recursive = recursive, \
**kw)
...@@ -48,59 +48,6 @@ ...@@ -48,59 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Simply a wrapper to real method.\n
"""\n
\n
total_stream_length = context.getSize()\n
\n
if start > total_stream_length:\n
# end reached\n
return\n
\n
data_stream_chunk_list = context.readChunkList(start, end)\n
\n
# do call transformation script\n
if transform_script_id is not None:\n
transform_script = getattr(context, transform_script_id, None)\n
if transform_script is not None:\n
start, end = transform_script(context, data_stream_chunk_list, \\\n
start, \\\n
end, \\\n
data_array_reference, \\\n
**kw)\n
\n
# [warning] store current position offset in Data Stream, this can cause easily \n
# ConflictErrors and it spawns re-index activities on DataStream. Thus \n
# disable for now.\n
#context.setIntOffsetIndex(end)\n
\n
# start another read in another activity\n
start += chunk_length\n
end += chunk_length\n
\n
if end > total_stream_length:\n
# no read beyond end of stream\n
end = total_stream_length\n
\n
if recursive:\n
# some bytes left ...\n
context.activate().DataStream_readChunkListAndTransform( \\\n
start, \\\n
end, \\\n
chunk_length, \\\n
transform_script_id,\\\n
data_array_reference,\\\n
recursive = recursive, \\\n
**kw)\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>start, end, chunk_length, transform_script_id=None, data_array_reference=None, recursive=1,**kw</string> </value> <value> <string>start, end, chunk_length, transform_script_id=None, data_array_reference=None, recursive=1,**kw</string> </value>
......
"""
Read entire stream using activities either in a sequence or in a oarallel mode.
Pass stream's data to handler script who can transform it.
Parameters:
* transform_script_id - the script which will transform data
* chunk_length - the length of a chunk
* data_array_reference - the reference of the output Data Array
* parallelize - try to transform in parallel or not, in this case
developer must carefully choose chunk_length to match record (s) size
"""
start = 0
end = chunk_length
if not parallelize:
# sequential case
context.activate().DataStream_readChunkListAndTransform( \
start, \
end, \
chunk_length, \
transform_script_id, \
data_array_reference,\
recursive =1, \
**kw)
else:
# parallel case
total_size = context.getSize()
while total_size > start:
start += chunk_length + 1
end += chunk_length +1
if end > total_size:
end = total_size
# call transformation in an activity
context.activate(activity='SQLQueue').DataStream_readChunkListAndTransform( \
start, \
end, \
chunk_length, \
transform_script_id, \
data_array_reference,\
recursive = 0, \
**kw)
...@@ -48,54 +48,6 @@ ...@@ -48,54 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
""" \n
Read entire stream using activities either in a sequence or in a oarallel mode.\n
Pass stream\'s data to handler script who can transform it.\n
Parameters:\n
* transform_script_id - the script which will transform data\n
* chunk_length - the length of a chunk\n
* data_array_reference - the reference of the output Data Array\n
* parallelize - try to transform in parallel or not, in this case\n
developer must carefully choose chunk_length to match record (s) size\n
"""\n
start = 0\n
end = chunk_length\n
if not parallelize:\n
# sequential case\n
context.activate().DataStream_readChunkListAndTransform( \\\n
start, \\\n
end, \\\n
chunk_length, \\\n
transform_script_id, \\\n
data_array_reference,\\\n
recursive =1, \\\n
**kw)\n
else:\n
# parallel case\n
total_size = context.getSize()\n
while total_size > start:\n
start += chunk_length + 1\n
end += chunk_length +1\n
if end > total_size:\n
end = total_size\n
\n
# call transformation in an activity\n
context.activate(activity=\'SQLQueue\').DataStream_readChunkListAndTransform( \\\n
start, \\\n
end, \\\n
chunk_length, \\\n
transform_script_id, \\\n
data_array_reference,\\\n
recursive = 0, \\\n
**kw)\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>chunk_length=1048576, transform_script_id=None, data_array_reference=None,parallelize=0, **kw</string> </value> <value> <string>chunk_length=1048576, transform_script_id=None, data_array_reference=None,parallelize=0, **kw</string> </value>
......
"""
Read tail of a Data Stream and aplly needed transformations.
This script is called every time we appendData to a Stream
using data_stream_interaction_workflow.
The idea is to provide close to real time data transformations.
As transformation is quite specific we leave this script empty so developers
can hook in and add needed transformations.
"""
assert start_offset < end_offset
...@@ -48,24 +48,6 @@ ...@@ -48,24 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Read tail of a Data Stream and aplly needed transformations.\n
This script is called every time we appendData to a Stream\n
using data_stream_interaction_workflow.\n
\n
The idea is to provide close to real time data transformations.\n
As transformation is quite specific we leave this script empty so developers\n
can hook in and add needed transformations.\n
"""\n
assert start_offset < end_offset\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>start_offset, end_offset</string> </value> <value> <string>start_offset, end_offset</string> </value>
......
"""
Example of ingesting data in ERP5 coming from fluentd.
Fluentd sends to us a JSON dictionary using msgpack protocol.
In this implementation we find respective Data Stream and simply
append data there. We save raw JSON dictionary as string.
Ingestion Policy -> Data Supply -> Data Supply Line -> Sensor
-> Data Stream
"""
from DateTime import DateTime
from zExceptions import NotFound
from Products.ZSQLCatalog.SQLCatalog import ComplexQuery
from Products.ZSQLCatalog.SQLCatalog import Query
now = DateTime()
request = context.REQUEST
portal_catalog = context.portal_catalog
reference = request.get('reference')
data_chunk = request.get('data_chunk')
if data_chunk is not None and reference is not None:
# here we rely that fluentd will pass to us its tag which we use
# as reference but we can extract it sometimes from sensor data
# it thus depends on sensor and the fluentd topography
query=ComplexQuery(Query(portal_type = 'Data Supply'),
Query(reference = reference),
Query(validation_state = 'validated'),
Query( **{'delivery.stop_date':now, 'range': 'min'}),
Query( **{'delivery.start_date':now, 'range': 'max'}),
operator="AND")
data_supply = portal_catalog.getResultValue(query=query)
#context.log(data_supply)
# we can have multiple lines for each sensor and we filter out by reference
# XXX: in future we will use Predicates to find already generated
# Data Ingestion (Movements)
if data_supply is not None:
for data_supply_line in data_supply.objectValues():
sensor = data_supply_line.getSourceValue()
if sensor is not None and sensor.getReference() == reference:
# Sensor is defined as destination
data_stream = data_supply_line.getDestinationValue()
break
#context.log(sensor)
#context.log(data_stream)
if data_stream is not None:
pretty_data_chunk_list = []
data_chunk_list = context.unpack(data_chunk)
for data_chunk in data_chunk_list:
pretty_data = str(data_chunk[1])
pretty_data_chunk_list.append(pretty_data)
data = ''.join(pretty_data_chunk_list)
# append data
data_stream.appendData(data)
#context.log("Appended %s bytes to %s (%s, %s, %s)"
# %(len(data), reference, data_supply, sensor, data_stream))
# XXX: open question -> we do not store the act of ingestion.
# one way is to have a business process for who's "ingestion"
# trade_phase / state we generate simulation movements and respective
# objects in data_ingestion_module. We can use same approach and same
# business process for analytics stage (just different trade_state / phase)?
# JP: we should use this approach at a later stage
# this approach can be hooked through interaction workflow on data stream
else:
raise NotFound('No data stream configuration found.')
else:
raise NotFound('No data supply configuration found.')
else:
raise NotFound('No data or any configuration found.')
...@@ -48,88 +48,6 @@ ...@@ -48,88 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Example of ingesting data in ERP5 coming from fluentd.\n
Fluentd sends to us a JSON dictionary using msgpack protocol.\n
In this implementation we find respective Data Stream and simply\n
append data there. We save raw JSON dictionary as string.\n
Ingestion Policy -> Data Supply -> Data Supply Line -> Sensor\n
-> Data Stream\n
"""\n
from DateTime import DateTime\n
from zExceptions import NotFound\n
from Products.ZSQLCatalog.SQLCatalog import ComplexQuery\n
from Products.ZSQLCatalog.SQLCatalog import Query\n
\n
\n
now = DateTime()\n
request = context.REQUEST\n
portal_catalog = context.portal_catalog\n
\n
reference = request.get(\'reference\')\n
data_chunk = request.get(\'data_chunk\')\n
\n
if data_chunk is not None and reference is not None:\n
# here we rely that fluentd will pass to us its tag which we use\n
# as reference but we can extract it sometimes from sensor data\n
# it thus depends on sensor and the fluentd topography\n
query=ComplexQuery(Query(portal_type = \'Data Supply\'),\n
Query(reference = reference),\n
Query(validation_state = \'validated\'),\n
Query( **{\'delivery.stop_date\':now, \'range\': \'min\'}),\n
Query( **{\'delivery.start_date\':now, \'range\': \'max\'}),\n
operator="AND")\n
data_supply = portal_catalog.getResultValue(query=query)\n
\n
#context.log(data_supply)\n
# we can have multiple lines for each sensor and we filter out by reference\n
# XXX: in future we will use Predicates to find already generated\n
# Data Ingestion (Movements)\n
if data_supply is not None:\n
for data_supply_line in data_supply.objectValues():\n
sensor = data_supply_line.getSourceValue()\n
if sensor is not None and sensor.getReference() == reference:\n
# Sensor is defined as destination\n
data_stream = data_supply_line.getDestinationValue()\n
break\n
\n
#context.log(sensor)\n
#context.log(data_stream)\n
if data_stream is not None:\n
pretty_data_chunk_list = []\n
data_chunk_list = context.unpack(data_chunk)\n
\n
for data_chunk in data_chunk_list:\n
pretty_data = str(data_chunk[1])\n
pretty_data_chunk_list.append(pretty_data)\n
data = \'\'.join(pretty_data_chunk_list)\n
\n
# append data\n
data_stream.appendData(data)\n
\n
#context.log("Appended %s bytes to %s (%s, %s, %s)" \n
# %(len(data), reference, data_supply, sensor, data_stream))\n
# XXX: open question -> we do not store the act of ingestion.\n
# one way is to have a business process for who\'s "ingestion" \n
# trade_phase / state we generate simulation movements and respective \n
# objects in data_ingestion_module. We can use same approach and same \n
# business process for analytics stage (just different trade_state / phase)?\n
# JP: we should use this approach at a later stage\n
# this approach can be hooked through interaction workflow on data stream\n
else:\n
raise NotFound(\'No data stream configuration found.\') \n
else:\n
raise NotFound(\'No data supply configuration found.\')\n
else:\n
raise NotFound(\'No data or any configuration found.\')\n
]]></string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
"""
Create all required types for proper ingestion.
"""
from DateTime import DateTime
now = DateTime()
ingestion_policy = context.newContent( \
id = reference,
portal_type ='Ingestion Policy',
reference = reference,
version = '001',
script_id = 'ERP5Site_handleDefaultFluentdIngestion')
ingestion_policy.validate()
# create sensor
sensor = context.sensor_module.newContent( \
portal_type='Sensor',
reference = reference)
sensor.validate()
# create new Data Stream
data_stream = context.data_stream_module.newContent( \
portal_type='Data Stream', \
version = '001', \
reference=reference)
data_stream.validate()
# create Data Supply
resource = context.restrictedTraverse('data_product_module/wendelin_4')
data_supply_kw = {'reference': reference,
'version': '001',
'start_date': now,
'stop_date': now + 365}
data_supply_line_kw = {'resource_value': resource,
'source_value': sensor,
'destination_value': data_stream}
data_supply = ingestion_policy.PortalIngestionPolicy_addDataSupply( \
data_supply_kw, \
data_supply_line_kw)
data_array = context.data_array_module.newContent(
portal_type='Data Array',
reference = reference,
version = '001')
data_array.validate()
if batch_mode:
return ingestion_policy, data_supply, data_stream, data_array
else:
# UI case
ingestion_policy.Base_redirect(\
form_id='view', \
keep_items={'portal_status_message': \
context.Base_translateString('Ingestion Policy added.')})
...@@ -48,64 +48,6 @@ ...@@ -48,64 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Create all required types for proper ingestion.\n
"""\n
from DateTime import DateTime\n
\n
now = DateTime()\n
ingestion_policy = context.newContent( \\\n
id = reference,\n
portal_type =\'Ingestion Policy\',\n
reference = reference,\n
version = \'001\',\n
script_id = \'ERP5Site_handleDefaultFluentdIngestion\')\n
ingestion_policy.validate()\n
\n
# create sensor\n
sensor = context.sensor_module.newContent( \\\n
portal_type=\'Sensor\', \n
reference = reference)\n
sensor.validate()\n
\n
# create new Data Stream\n
data_stream = context.data_stream_module.newContent( \\\n
portal_type=\'Data Stream\', \\\n
version = \'001\', \\\n
reference=reference)\n
data_stream.validate()\n
\n
# create Data Supply\n
resource = context.restrictedTraverse(\'data_product_module/wendelin_4\')\n
data_supply_kw = {\'reference\': reference,\n
\'version\': \'001\',\n
\'start_date\': now,\n
\'stop_date\': now + 365}\n
data_supply_line_kw = {\'resource_value\': resource,\n
\'source_value\': sensor,\n
\'destination_value\': data_stream}\n
data_supply = ingestion_policy.PortalIngestionPolicy_addDataSupply( \\\n
data_supply_kw, \\\n
data_supply_line_kw)\n
\n
data_array = context.data_array_module.newContent(\n
portal_type=\'Data Array\',\n
reference = reference,\n
version = \'001\')\n
data_array.validate()\n
\n
if batch_mode:\n
return ingestion_policy, data_supply, data_stream, data_array\n
else:\n
# UI case\n
ingestion_policy.Base_redirect(\\\n
form_id=\'view\', \\\n
keep_items={\'portal_status_message\': \\\n
context.Base_translateString(\'Ingestion Policy added.\')})\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>reference=None, batch_mode=0</string> </value> <value> <string>reference=None, batch_mode=0</string> </value>
......
"""
Add a data supply structure for a data ingestion on a portal ingestion policy.
"""
data_supply = context.data_supply_module.newContent( \
portal_type='Data Supply', **data_supply_kw)
data_supply.validate()
# add default line
data_supply_line = data_supply.newContent(portal_type='Data Supply Line', \
**data_supply_line_kw)
return data_supply
...@@ -48,22 +48,6 @@ ...@@ -48,22 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Add a data supply structure for a data ingestion on a portal ingestion policy.\n
"""\n
data_supply = context.data_supply_module.newContent( \\\n
portal_type=\'Data Supply\', **data_supply_kw)\n
data_supply.validate()\n
\n
# add default line\n
data_supply_line = data_supply.newContent(portal_type=\'Data Supply Line\', \\\n
**data_supply_line_kw)\n
\n
return data_supply\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>data_supply_kw, data_supply_line_kw</string> </value> <value> <string>data_supply_kw, data_supply_line_kw</string> </value>
......
"""
Handle appended data chunks.
"""
data_stream = state_change['object']
argument_list = state_change['kwargs']['workflow_method_args']
# call you own script to handle newly appended data which
# is not processed yet, pass data stream start end offset only
end_offset = data_stream.getSize()
packet_size = len(argument_list[0])
start_offset = end_offset - packet_size
data_stream.activate().DataStream_transformTail(start_offset, end_offset)
...@@ -48,22 +48,6 @@ ...@@ -48,22 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Handle appended data chunks.\n
"""\n
data_stream = state_change[\'object\']\n
argument_list = state_change[\'kwargs\'][\'workflow_method_args\']\n
\n
# call you own script to handle newly appended data which \n
# is not processed yet, pass data stream start end offset only\n
end_offset = data_stream.getSize()\n
packet_size = len(argument_list[0])\n
start_offset = end_offset - packet_size\n
data_stream.activate().DataStream_transformTail(start_offset, end_offset)\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change,**kw</string> </value> <value> <string>state_change,**kw</string> </value>
......
# This script returns an iterable of the paths to standard JavaScript objects.
# If you want to customize your own site, please override this script
# in your own skin folder. Note that the returned items must be
# relative URLs instead of absolute URLs, i.e. they must be traversable
# from the portal object. This is required for further processing of JavaScript
# data, e.g. compression.
#
# BBB: For the history, erp5_xhtml_appearance.js is included by default when
# js_list is not pre-defined before the global definitions.
js_list = ('jquery/core/jquery.min.js', 'jquery/ui/js/jquery-ui.min.js', 'erp5.js', 'erp5_knowledge_box.js', 'erp5_dhtml_style.js','live_test.js')
return js_list
...@@ -48,21 +48,6 @@ ...@@ -48,21 +48,6 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_body</string> </key>
<value> <string># This script returns an iterable of the paths to standard JavaScript objects.\n
# If you want to customize your own site, please override this script\n
# in your own skin folder. Note that the returned items must be\n
# relative URLs instead of absolute URLs, i.e. they must be traversable\n
# from the portal object. This is required for further processing of JavaScript\n
# data, e.g. compression.\n
#\n
# BBB: For the history, erp5_xhtml_appearance.js is included by default when\n
# js_list is not pre-defined before the global definitions.\n
js_list = (\'jquery/core/jquery.min.js\', \'jquery/ui/js/jquery-ui.min.js\', \'erp5.js\', \'erp5_knowledge_box.js\', \'erp5_dhtml_style.js\',\'live_test.js\')\n
return js_list\n
</string> </value>
</item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> Wendelin Visualisation Demo</title>
<link id="favicon" rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAERAAAAAAAAEQEAAAAAAAEQARAAAAAAARAAEQAAAAARAAARAAAAABAAAAEQAAAAAAAAABEAAAAAAAAAEQAAAAAAAAABEAAAAAAAAAARAAAAAAAAABEAAAAAAAAAAQAAAAAAAAAAD//wAA//8AAP7/AAD8fwAA+X8AAPM/AADznwAA558AAO/PAAD/5wAA/+cAAP/zAAD/+QAA//kAAP/9AAD//wAA">
<link rel="stylesheet" href="jquerymobile.css">
<script src="jquery.js"></script>
<script src="jquerymobile.js"></script>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="gadget_global.js" ></script>
<script src="gadget_wendelin.js"></script>
</head>
<body>
<div class="ui-hidden-accessible connection-gadget-container"></div>
<div data-role="page">
<div data-role="header" data-position="fixeppppppd" class="gadget-header" data-theme="b">
<h1>Wendelin Graph Visualisation</h1>
<a class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all uploadlink">Upload</a>
<a class="ui-btn-right ui-btn ui-btn-inline ui-mini ui-corner-all alldoclink">List Document</a>
</div>
<div role="main" class="ui-content gadget-content"></div>
</div>
<!-- Example of inline a global gadget, scope is mandatory -->
<div data-gadget-url="gadget_jio.html" data-gadget-scope="JIO"></div>
</body>
</html>
...@@ -99,55 +99,6 @@ ...@@ -99,55 +99,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!doctype html>\n
<html>\n
<head>\n
<meta charset="utf-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1">\n
\n
<title> Wendelin Visualisation Demo</title>\n
<link id="favicon" rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAERAAAAAAAAEQEAAAAAAAEQARAAAAAAARAAEQAAAAARAAARAAAAABAAAAEQAAAAAAAAABEAAAAAAAAAEQAAAAAAAAABEAAAAAAAAAARAAAAAAAAABEAAAAAAAAAAQAAAAAAAAAAD//wAA//8AAP7/AAD8fwAA+X8AAPM/AADznwAA558AAO/PAAD/5wAA/+cAAP/zAAD/+QAA//kAAP/9AAD//wAA">\n
\n
<link rel="stylesheet" href="jquerymobile.css">\n
\n
<script src="jquery.js"></script>\n
<script src="jquerymobile.js"></script>\n
<script src="rsvp.js"></script>\n
<script src="renderjs.js"></script>\n
<script src="handlebars.js"></script>\n
<script src="gadget_global.js" ></script>\n
<script src="gadget_wendelin.js"></script>\n
\n
</head>\n
\n
<body>\n
<div class="ui-hidden-accessible connection-gadget-container"></div>\n
\n
<div data-role="page">\n
\n
<div data-role="header" data-position="fixeppppppd" class="gadget-header" data-theme="b">\n
<h1>Wendelin Graph Visualisation</h1>\n
<a class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all uploadlink">Upload</a>\n
<a class="ui-btn-right ui-btn ui-btn-inline ui-mini ui-corner-all alldoclink">List Document</a>\n
</div>\n
\n
<div role="main" class="ui-content gadget-content"></div>\n
\n
</div>\n
\n
<!-- Example of inline a global gadget, scope is mandatory -->\n
<div data-gadget-url="gadget_jio.html" data-gadget-scope="JIO"></div>\n
\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Root Gadget</string> </value> <value> <string>Wendelin Root Gadget</string> </value>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*global window, rJS, console, RSVP, Dygraph, DataView, Float32Array,
document */
/*jslint indent: 2, maxerr: 3 */
(function (rJS) {
"use strict";
rJS(window)
.ready(function (gadget) {
gadget.property_dict = {};
})
.declareMethod('draw', function (data) {
/* a generic method to call which can draw a diagram */
var graph_gadget = this;
return graph_gadget.getElement()
.push(function (dom_element) {
var data_points_per_channel, total_channels, byte_len, i,
tmp_data, x_value, x_delta, make_shell, start_time, stop_time,
make_series, make_graph_struct, test_a;
// data parameters
x_value = "time"; // must be passed from header
x_delta = 0.00000025; // must be passed from header
data_points_per_channel = 4000; // must be passed from header
total_channels = 3; // must be passed from header
start_time = Date.now();
data = new DataView(data);
byte_len = data.byteLength;
tmp_data = new Float32Array(byte_len / Float32Array.BYTES_PER_ELEMENT);
// Incoming data is raw floating point values with little-endian byte ordering.
for (i = 0; i < tmp_data.length; i += 1) {
tmp_data[i] = data.getFloat32(i * Float32Array.BYTES_PER_ELEMENT, true);
}
// graph shell
make_shell = function (opts) {
var x, shell, shell_row;
shell = [];
for (x = 0; x < opts.points; x += 1) {
shell_row = [];
shell_row.push(opts.delta * x);
shell.push(shell_row);
}
return shell;
};
// graph data series
make_series = function (opts) {
var k, pos;
pos = opts.start;
for (k = 0; k < opts.points; k += 1) {
opts.shell[k].push(opts.float[k + pos]);
}
return opts.shell;
};
// build a row structure for dygraph with series needed
make_graph_struct = function (opts) {
var j, k, channel_len, struct, series;
for (j = 0, channel_len = opts.total_channels; j < channel_len; j += 1) {
for (k = 0; k < opts.display.length; k += 1) {
series = opts.display[k];
if (series[0] === j) {
struct = make_series({
"points": opts.points,
"float": opts.data,
"shell": make_shell({
"points": opts.points,
"delta": opts.delta
}),
"start": series[1]
});
}
}
}
return struct;
};
// dynagraph
test_a = new Dygraph(
dom_element.querySelector(".graph-a"),
make_graph_struct({
"display": [[0, 0]],
"total_channels": total_channels,
"points": data_points_per_channel,
"data": tmp_data,
"delta": x_delta
}),
{
"legend": 'always',
"title": 'Channel X',
"showRoller": true,
"rollPeriod": 50,
"labels": [ x_value, "A" ]
}
);
test_a = new Dygraph(
dom_element.querySelector(".graph-b"),
make_graph_struct({
"display": [[1, data_points_per_channel]],
"total_channels": total_channels,
"points": data_points_per_channel,
"data": tmp_data,
"delta": x_delta
}),
{
"legend": 'always',
"title": 'Channel Y',
"showRoller": true,
"rollPeriod": 50,
"labels": [ x_value, "B" ]
}
);
test_a = new Dygraph(
dom_element.querySelector(".graph-c"),
make_graph_struct({
"display": [[2, 2 * data_points_per_channel]],
"total_channels": total_channels,
"points": data_points_per_channel,
"data": tmp_data,
"delta": x_delta
}),
{
"legend": 'always',
"title": 'Channel Z',
"showRoller": true,
"rollPeriod": 50,
"labels": [ x_value, "C" ]
}
);
stop_time = Date.now();
console.log(stop_time - start_time);
});
});
}(rJS));
\ No newline at end of file
...@@ -97,162 +97,6 @@ ...@@ -97,162 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*global window, rJS, console, RSVP, Dygraph, DataView, Float32Array,\n
document */\n
/*jslint indent: 2, maxerr: 3 */\n
\n
(function (rJS) {\n
"use strict";\n
\n
rJS(window)\n
\n
.ready(function (gadget) {\n
gadget.property_dict = {};\n
})\n
\n
.declareMethod(\'draw\', function (data) {\n
/* a generic method to call which can draw a diagram */\n
var graph_gadget = this;\n
return graph_gadget.getElement()\n
.push(function (dom_element) {\n
\n
var data_points_per_channel, total_channels, byte_len, i,\n
tmp_data, x_value, x_delta, make_shell, start_time, stop_time,\n
make_series, make_graph_struct, test_a;\n
\n
// data parameters\n
x_value = "time"; // must be passed from header\n
x_delta = 0.00000025; // must be passed from header\n
data_points_per_channel = 4000; // must be passed from header\n
total_channels = 3; // must be passed from header\n
\n
start_time = Date.now();\n
\n
data = new DataView(data);\n
\n
byte_len = data.byteLength;\n
\n
tmp_data = new Float32Array(byte_len / Float32Array.BYTES_PER_ELEMENT);\n
\n
// Incoming data is raw floating point values with little-endian byte ordering.\n
for (i = 0; i < tmp_data.length; i += 1) {\n
tmp_data[i] = data.getFloat32(i * Float32Array.BYTES_PER_ELEMENT, true);\n
}\n
\n
// graph shell\n
make_shell = function (opts) {\n
var x, shell, shell_row;\n
\n
shell = [];\n
for (x = 0; x < opts.points; x += 1) {\n
shell_row = [];\n
shell_row.push(opts.delta * x);\n
shell.push(shell_row);\n
}\n
return shell;\n
};\n
\n
// graph data series\n
make_series = function (opts) {\n
var k, pos;\n
\n
pos = opts.start;\n
for (k = 0; k < opts.points; k += 1) {\n
opts.shell[k].push(opts.float[k + pos]);\n
}\n
return opts.shell;\n
};\n
\n
// build a row structure for dygraph with series needed\n
make_graph_struct = function (opts) {\n
var j, k, channel_len, struct, series;\n
\n
for (j = 0, channel_len = opts.total_channels; j < channel_len; j += 1) {\n
for (k = 0; k < opts.display.length; k += 1) {\n
series = opts.display[k];\n
if (series[0] === j) {\n
struct = make_series({\n
"points": opts.points,\n
"float": opts.data,\n
"shell": make_shell({\n
"points": opts.points,\n
"delta": opts.delta\n
}),\n
"start": series[1]\n
});\n
}\n
}\n
}\n
return struct;\n
};\n
\n
// dynagraph\n
test_a = new Dygraph(\n
dom_element.querySelector(".graph-a"),\n
make_graph_struct({\n
"display": [[0, 0]],\n
"total_channels": total_channels,\n
"points": data_points_per_channel,\n
"data": tmp_data,\n
"delta": x_delta\n
}),\n
{\n
"legend": \'always\',\n
"title": \'Channel X\',\n
"showRoller": true,\n
"rollPeriod": 50,\n
"labels": [ x_value, "A" ]\n
}\n
);\n
\n
test_a = new Dygraph(\n
dom_element.querySelector(".graph-b"),\n
make_graph_struct({\n
"display": [[1, data_points_per_channel]],\n
"total_channels": total_channels,\n
"points": data_points_per_channel,\n
"data": tmp_data,\n
"delta": x_delta\n
}),\n
{\n
"legend": \'always\',\n
"title": \'Channel Y\',\n
"showRoller": true,\n
"rollPeriod": 50,\n
"labels": [ x_value, "B" ]\n
}\n
);\n
\n
test_a = new Dygraph(\n
dom_element.querySelector(".graph-c"),\n
make_graph_struct({\n
"display": [[2, 2 * data_points_per_channel]],\n
"total_channels": total_channels,\n
"points": data_points_per_channel,\n
"data": tmp_data,\n
"delta": x_delta\n
}),\n
{\n
"legend": \'always\',\n
"title": \'Channel Z\',\n
"showRoller": true,\n
"rollPeriod": 50,\n
"labels": [ x_value, "C" ]\n
}\n
);\n
\n
stop_time = Date.now();\n
console.log(stop_time - start_time);\n
});\n
});\n
}(rJS));
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin gadget_erp5_graph.js</string> </value> <value> <string>Wendelin gadget_erp5_graph.js</string> </value>
......
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Graph</title>
<!-- custom css -->
<link href="gadget_erp5_graph.css" type="text/css" rel="stylesheet" />
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="dygraph.js" type="text/javascript"></script>
<script src="gadget_erp5_graph.js" type="text/javascript"></script>
</head>
<body>
<div class="custom-grid-wrap">
<div class="custom-grid ui-corner-all ui-body-inherit ui-shadow ui-corner-all"></div>
<div class="gadget-graph-content">Loading diagram ...</div>
<div class="graph-a"></div>
<div class="graph-b"></div>
<div class="graph-c"></div>
</div>
</body>
</html>
...@@ -126,45 +126,6 @@ ...@@ -126,45 +126,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!DOCTYPE html>\n
<html>\n
<head>\n
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n
<meta name="viewport" content="width=device-width, user-scalable=no" />\n
<title>ERP5 Graph</title>\n
\n
<!-- custom css -->\n
<link href="gadget_erp5_graph.css" type="text/css" rel="stylesheet" />\n
\n
<!-- renderjs -->\n
<script src="rsvp.js" type="text/javascript"></script>\n
<script src="renderjs.js" type="text/javascript"></script>\n
\n
<!-- custom script -->\n
<script src="dygraph.js" type="text/javascript"></script>\n
<script src="gadget_erp5_graph.js" type="text/javascript"></script>\n
\n
</head>\n
<body>\n
<div class="custom-grid-wrap">\n
<div class="custom-grid ui-corner-all ui-body-inherit ui-shadow ui-corner-all"></div>\n
<div class="gadget-graph-content">Loading diagram ...</div>\n
\n
<div class="graph-a"></div>\n
<div class="graph-b"></div>\n
<div class="graph-c"></div>\n
\n
</div>\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Graph Gadget</string> </value> <value> <string>Wendelin Graph Gadget</string> </value>
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Listbox Gadget</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="gadget_wendelin_listbox.js"></script>
<script id="contact-list-template" class="contact-list-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<ul data-role="listview" data-inset="true">
{{#each url_list}}
<li>
<a href="{{url}}">
{{id}}
</a>
</li>
{{/each}}
</ul>
</div>
<div class="ui-block-c"></div>
</div>
</script>
</head>
<body>
<h1>Listbox gadget</h1>
<div role="main" class="ui-content gadget-content"></div>
</body>
</html>
...@@ -99,55 +99,6 @@ ...@@ -99,55 +99,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!doctype html>\n
<html>\n
<head>\n
<meta charset="utf-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1">\n
\n
<title>Listbox Gadget</title>\n
\n
<script src="rsvp.js"></script>\n
<script src="renderjs.js"></script>\n
<script src="handlebars.js"></script>\n
<script src="gadget_wendelin_listbox.js"></script>\n
\n
<script id="contact-list-template" class="contact-list-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<ul data-role="listview" data-inset="true">\n
{{#each url_list}}\n
<li>\n
<a href="{{url}}">\n
{{id}}\n
</a>\n
</li>\n
{{/each}}\n
</ul>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
</head>\n
\n
<body>\n
\n
<h1>Listbox gadget</h1>\n
\n
<div role="main" class="ui-content gadget-content"></div>\n
\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Listbox Gadget</string> </value> <value> <string>Wendelin Listbox Gadget</string> </value>
......
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,
loopEventListener, jQuery, console, jIO*/
/*jslint indent: 2, maxerr: 30, nomen:true */
(function () {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.getElementById("contact-list-template")
.innerHTML,
table_template = Handlebars.compile(source);
// Ivan: we extend gadget API like so:
rJS(window).declareMethod('render', function () {
var gadget = this,
html;
return gadget.aq_allDocs()
.push(function (result) {
var promise_list = [],
len = result.data.rows.length,
i;
for (i = 0; i < len; i += 1) {
promise_list.push(result.data.rows[i].id);
}
return RSVP.all(promise_list);
})
.push(function (rows) {
// posts contains an array of results for the given promises
var new_url_list = [],
len = rows.length,
i;
for (i = 0; i < len; i += 1) {
// XXX: renderjs generate URL ?
new_url_list.push({'url': '#page=show&id=' + rows[i],
'id': rows[i]});
}
html = table_template({'url_list': new_url_list});
return gadget.getElement();
})
.push(function (element) {
// append produced HTML
element.innerHTML = html;
});
})
// ivan: decalre we want to use JIO functionality as an alias (aq_post)
.declareAcquiredMethod("aq_allDocs", "jio_allDocs");
}());
\ No newline at end of file
...@@ -97,67 +97,6 @@ ...@@ -97,67 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
loopEventListener, jQuery, console, jIO*/\n
/*jslint indent: 2, maxerr: 30, nomen:true */\n
(function () {\n
"use strict";\n
\n
/////////////////////////////////////////////////////////////////\n
// Handlebars\n
/////////////////////////////////////////////////////////////////\n
// Precompile the templates while loading the first gadget instance\n
var gadget_klass = rJS(window),\n
source = gadget_klass.__template_element\n
.getElementById("contact-list-template")\n
.innerHTML,\n
table_template = Handlebars.compile(source);\n
\n
// Ivan: we extend gadget API like so:\n
rJS(window).declareMethod(\'render\', function () {\n
var gadget = this,\n
html;\n
return gadget.aq_allDocs()\n
.push(function (result) {\n
var promise_list = [],\n
len = result.data.rows.length,\n
i;\n
for (i = 0; i < len; i += 1) {\n
promise_list.push(result.data.rows[i].id);\n
}\n
return RSVP.all(promise_list);\n
})\n
.push(function (rows) {\n
// posts contains an array of results for the given promises\n
var new_url_list = [],\n
len = rows.length,\n
i;\n
for (i = 0; i < len; i += 1) {\n
// XXX: renderjs generate URL ?\n
new_url_list.push({\'url\': \'#page=show&id=\' + rows[i],\n
\'id\': rows[i]});\n
}\n
html = table_template({\'url_list\': new_url_list});\n
return gadget.getElement();\n
})\n
.push(function (element) {\n
// append produced HTML\n
element.innerHTML = html;\n
});\n
\n
})\n
\n
// ivan: decalre we want to use JIO functionality as an alias (aq_post)\n
.declareAcquiredMethod("aq_allDocs", "jio_allDocs");\n
\n
}());
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Listbox Gadget JS</string> </value> <value> <string>Wendelin Listbox Gadget JS</string> </value>
......
<!doctype html>
<html manifest="gadget_eexpense.appcache">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ERP5</title>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="jquerymobile.css">
<link rel="stylesheet" href="gadget_erp5.css">
<script src="jquery.js"></script>
<script src="jquerymobile.js"></script>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="gadget_global.js" ></script>
<script src="gadget_eexpense.js"></script>
<script class="document-list-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<ul data-role="listview" data-inset="true">
{{#each document_list}}
<li><a href="{{url}}">
{{title}} || {{reference}} || {{description}}
</a>
</li>
{{else}}
<li><p>Empty</p></li>
{{/each}}
</ul>
<a href="{{sync_url}}" class="ui-btn ui-btn-inline ui-mini ui-corner-all" data-theme="b">Sync</a>
</div>
JSON Dict:
<div class="ui-block-b">{{json_dict}}</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="new-expense-report-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<form class="new-expense-report-form">
<div class="ui-field-contain">
<label>Title</label>
<input type="text" name="title" value="Title" required>
</div>
<div class="ui-field-contain">
<label>Reference</label>
<input type="text" name="reference" value="{{reference}}" required>
</div>
<div class="ui-field-contain">
<label>Description or reference</label>
<textarea name="description" value="" required></textarea>
</div>
<input data-inline="true" type="submit" value="Add" data-theme="b">
</form>
</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="view-expense-report-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<form class="view-expense-report-form">
<div class="ui-field-contain">
<label>Title</label>
<input type="text" name="title" value="{{title}}" required>
</div>
<div class="ui-field-contain">
<label>Reference</label>
<input type="text" name="reference" value="{{reference}}" required>
</div>
<div class="ui-field-contain">
<label>Description or reference</label>
<textarea name="description" required>{{description}}</textarea>
</div>
</form>
</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="edit-template" type="text/x-handlebars-template">
<h1 class="ui-title">{{title}}</h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<form class="edit-form">
<button type="submit" class="responsive ui-btn ui-first-child ui-last-child ">{{right_url}}</button>
</form>
</div>
</div>
</script>
<script class="synchro-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<form class="synchro-form">
<input data-inline="true" type="submit" value="Launch" data-theme="b">
</form>
</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="login-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<form class="login-form">
<div class="ui-field-contain">
<label>Login</label>
<input type="text" name="jid" placeholder="Ex: john" value="" required>
</div>
<div class="ui-field-contain">
<label>Password</label>
<input type="password" name="passwd" placeholder="Ex: A1bcF$99" value="" required>
</div>
<input data-inline="true" type="submit" value="Log In" data-theme="b">
</form>
</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="logout-template" type="text/x-handlebars-template">
<div class="ui-grid-b ui-responsive">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<form class="logout-form">
<input data-inline="true" type="submit" value="Confirm" data-theme="b">
</form>
</div>
<div class="ui-block-c"></div>
</div>
</script>
<script class="header-template" type="text/x-handlebars-template">
<h1 class="ui-title">{{title}}</h1>
{{#if right_url}}
<a href="{{right_url}}" class="ui-btn-right ui-btn ui-btn-inline ui-mini ui-corner-all">{{right_title}}</a>
{{/if}}
</script>
<script class="sync-loader-template" type="text/x-handlebars-template">
<h1 class="ui-title">{{title}}</h1>
<a role="button" data-i18n="Loading" href="" class="responsive ui-btn ui-btn-right ui-icon-spinner ui-btn-icon-left ui-first-child ui-last-child ui-disabled ui-icon-spin">Syncing</a>
</script>
</head>
<body>
<div class="ui-hidden-accessible connection-gadget-container"></div>
<div data-role="page">
<div data-role="panel" id="mypanel" data-position="left" data-display="push" data-theme="d">
<div class="ui-content">
<ul data-role="listview" class="ui-listview" data-enhanced="true">
<li><a href="#page=list">Data Streams</a></li>
<li><a href="" class="ui-disabled">Inventory</a></li>
<li><a href="" class="ui-disabled">Production</a></li>
<li><a href="" class="ui-disabled">Sales</a></li>
<li class="ui-last-child"><a href="#page=logout">Logout</a></li>
</ul>
</div>
</div>
<div data-role="header" class="gadget-header" data-theme="a">
<a href="#mypanel" class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all">Menu</a>
<div></div>
</div>
<div data-gadget-url="gadget_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
<div role="main" class="ui-content gadget-content"></div>
</div>
</body>
</html>
...@@ -98,202 +98,6 @@ ...@@ -98,202 +98,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!doctype html>\n
<html manifest="gadget_eexpense.appcache">\n
<head>\n
<meta charset="utf-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1">\n
\n
<title>ERP5</title>\n
\n
<link href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />\n
<link rel="stylesheet" href="jquerymobile.css">\n
<link rel="stylesheet" href="gadget_erp5.css">\n
\n
<script src="jquery.js"></script>\n
<script src="jquerymobile.js"></script>\n
<script src="rsvp.js"></script>\n
<script src="renderjs.js"></script>\n
<script src="handlebars.js"></script>\n
<script src="gadget_global.js" ></script>\n
<script src="gadget_eexpense.js"></script>\n
\n
<script class="document-list-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<ul data-role="listview" data-inset="true">\n
{{#each document_list}}\n
<li><a href="{{url}}">\n
{{title}} || {{reference}} || {{description}}\n
</a>\n
</li>\n
{{else}}\n
<li><p>Empty</p></li>\n
{{/each}}\n
</ul>\n
<a href="{{sync_url}}" class="ui-btn ui-btn-inline ui-mini ui-corner-all" data-theme="b">Sync</a>\n
</div>\n
JSON Dict:\n
<div class="ui-block-b">{{json_dict}}</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="new-expense-report-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<form class="new-expense-report-form">\n
<div class="ui-field-contain">\n
<label>Title</label>\n
<input type="text" name="title" value="Title" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>Reference</label>\n
<input type="text" name="reference" value="{{reference}}" required>\n
</div> \n
<div class="ui-field-contain">\n
<label>Description or reference</label>\n
<textarea name="description" value="" required></textarea>\n
</div>\n
<input data-inline="true" type="submit" value="Add" data-theme="b">\n
</form>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="view-expense-report-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<form class="view-expense-report-form">\n
<div class="ui-field-contain">\n
<label>Title</label>\n
<input type="text" name="title" value="{{title}}" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>Reference</label>\n
<input type="text" name="reference" value="{{reference}}" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>Description or reference</label>\n
<textarea name="description" required>{{description}}</textarea>\n
</div>\n
</form>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="edit-template" type="text/x-handlebars-template">\n
<h1 class="ui-title">{{title}}</h1>\n
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">\n
<div class="ui-controlgroup-controls">\n
<form class="edit-form">\n
<button type="submit" class="responsive ui-btn ui-first-child ui-last-child ">{{right_url}}</button>\n
</form>\n
</div>\n
</div>\n
</script>\n
\n
<script class="synchro-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<form class="synchro-form">\n
<input data-inline="true" type="submit" value="Launch" data-theme="b">\n
</form>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="login-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<form class="login-form">\n
<div class="ui-field-contain">\n
<label>Login</label>\n
<input type="text" name="jid" placeholder="Ex: john" value="" required>\n
</div>\n
<div class="ui-field-contain">\n
<label>Password</label>\n
<input type="password" name="passwd" placeholder="Ex: A1bcF$99" value="" required>\n
</div>\n
<input data-inline="true" type="submit" value="Log In" data-theme="b">\n
</form>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="logout-template" type="text/x-handlebars-template">\n
<div class="ui-grid-b ui-responsive">\n
<div class="ui-block-a"></div>\n
<div class="ui-block-b">\n
<form class="logout-form">\n
<input data-inline="true" type="submit" value="Confirm" data-theme="b">\n
</form>\n
</div>\n
<div class="ui-block-c"></div>\n
</div>\n
</script>\n
\n
<script class="header-template" type="text/x-handlebars-template">\n
<h1 class="ui-title">{{title}}</h1>\n
{{#if right_url}}\n
<a href="{{right_url}}" class="ui-btn-right ui-btn ui-btn-inline ui-mini ui-corner-all">{{right_title}}</a>\n
{{/if}}\n
</script>\n
\n
<script class="sync-loader-template" type="text/x-handlebars-template">\n
<h1 class="ui-title">{{title}}</h1>\n
<a role="button" data-i18n="Loading" href="" class="responsive ui-btn ui-btn-right ui-icon-spinner ui-btn-icon-left ui-first-child ui-last-child ui-disabled ui-icon-spin">Syncing</a>\n
</script>\n
\n
</head>\n
\n
<body>\n
<div class="ui-hidden-accessible connection-gadget-container"></div>\n
\n
<div data-role="page">\n
\n
<div data-role="panel" id="mypanel" data-position="left" data-display="push" data-theme="d">\n
<div class="ui-content">\n
<ul data-role="listview" class="ui-listview" data-enhanced="true">\n
<li><a href="#page=list">Data Streams</a></li>\n
<li><a href="" class="ui-disabled">Inventory</a></li>\n
<li><a href="" class="ui-disabled">Production</a></li>\n
<li><a href="" class="ui-disabled">Sales</a></li>\n
<li class="ui-last-child"><a href="#page=logout">Logout</a></li>\n
</ul>\n
</div>\n
</div>\n
\n
<div data-role="header" class="gadget-header" data-theme="a">\n
<a href="#mypanel" class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all">Menu</a>\n
<div></div>\n
</div>\n
<div data-gadget-url="gadget_jio.html"\n
data-gadget-scope="jio_gadget"\n
data-gadget-sandbox="public"></div>\n
\n
<div role="main" class="ui-content gadget-content"></div>\n
</div>\n
\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Synchro Example</string> </value> <value> <string>Synchro Example</string> </value>
......
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,
loopEventListener, jQuery*/
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS, $) {
"use strict";
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
var DEFAULT_PAGE = "upload",
GADGET_SCOPE = "connection";
function redirectToDefaultPage(gadget) {
// Redirect to expected page by default
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})
.push(gadget.pleaseRedirectMyHash.bind(gadget));
}
function renderShowPage(gadget) {
// we create a new show gadget here
return gadget.declareGadget('gadget_wendelin_show.html', {
scope: GADGET_SCOPE, // is ok a gadget share same scope as another one ?
element: gadget.props.connection_element
})
// Ivan: when promises of creating a sub gadget is done we call callback in .push
// we use .push rather than .then due to cancel of RSVP written by romain
.push(function (sub_gadget) {
// we call render method which we defined on the gadget in a promise way
// options already saved in gadgets' Ram representation
var options = gadget.props.options;
return sub_gadget.render(options);
});
}
function renderUploadPage(gadget) {
// we create a new Upload gadget here
return gadget.declareGadget('gadget_wendelin_upload.html', {
scope: GADGET_SCOPE,
element: gadget.props.connection_element
})
.push(function (sub_gadget) {
// we call render method which we defined on the gadget in a promise way
return sub_gadget.render();
});
}
function renderListboxPage(gadget) {
// we create a new listbox gadget here
return gadget.declareGadget('gadget_wendelin_listbox.html', {
scope: GADGET_SCOPE,
element: gadget.props.connection_element
})
.push(function (sub_gadget) {
// we call render method which we defined on the gadget in a promise way
return sub_gadget.render();
});
}
rJS(window)
.ready(function (g) {
g.props = {};
// g.getElement() is a promise but we need result of it
return g.getElement()
.push(function (result) {
g.props.connection_element = result.querySelector(".gadget-content");
g.props.link_element = result.querySelector(".alldoclink");
g.props.upload_link_element = result.querySelector(".uploadlink");
});
})
// Configure jIO to use localstorage
.ready(function (g) {
return g.getDeclaredGadget("JIO")
.push(function (gadget) {
return gadget.createJio({
type: "query",
sub_storage: {
type: "indexeddb",
document_id: "/",
database: "test_ivan"
}
});
});
})
.ready(function (g) {
return g.aq_pleasePublishMyState({page: 'listbox'})
.push(function (url) {
g.props.link_element.href = url;
})
.push (function() {
return g.aq_pleasePublishMyState({page: 'upload'})
})
.push(function (url) {
g.props.upload_link_element.href = url;
});
})
//////////////////////////////////////////
// Acquired method
//////////////////////////////////////////
.declareAcquiredMethod('pleaseRedirectMyHash', 'pleaseRedirectMyHash')
.allowPublicAcquisition("goAndSaveToHistory", function (param_list) {
window.location = param_list[0];
})
.allowPublicAcquisition("jio_allDocs", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.allDocs.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_post", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.post.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_put", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.put.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("aq_putAttachment", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.putAttachment.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_get", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.get.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("aq_getAttachment", function (param_list) {
return this.getDeclaredGadget("JIO")
.push(function (jio_gadget) {
return jio_gadget.getAttachment.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("whoWantsToDisplayThisDocument",
function (param_list) {
// Hey, I want to display some jIO document
var kw = {
page: param_list[1] || "upload"
};
if (param_list[0] !== undefined) {
kw.id = param_list[0];
}
return this.aq_pleasePublishMyState(kw);
})
//////////////////////////////////////////
// Declare method (methods of the gadget!)
//////////////////////////////////////////
.declareMethod('render', function (options) {
var result,
gadget = this,
element = gadget.props.connection_element;
gadget.props.options = options;
// do clean up old DOM element's contents
while (element.firstChild) {
element.removeChild(element.firstChild);
}
// based on page parameter show respective sub gadget inside same page
if (options.page === undefined) {
result = redirectToDefaultPage(this);
} else if (options.page === 'upload') {
// show an upload page
result = renderUploadPage(gadget);
} else if (options.page === 'listbox') {
// show an upload page
result = renderListboxPage(this);
} else if (options.page === 'show') {
// show an upload page (ivan)
result = renderShowPage(this);
} else {
throw new Error(options.page);
}
return result
// Let JQM know it has to render this
.push(function () {
$(gadget.props.element).trigger("create");
})
.push(undefined, function (error) {
// XXX Improve renderJS error class
if ((error instanceof Error) &&
(error.message === "Gadget scope '" +
GADGET_SCOPE +
"' is not known.")) {
// redirec to default page
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})
.push(gadget.pleaseRedirectMyHash.bind(gadget));
}
throw error;
});
});
}(window, rJS, jQuery));
\ No newline at end of file
...@@ -97,217 +97,6 @@ ...@@ -97,217 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
loopEventListener, jQuery*/\n
/*jslint indent: 2, maxerr: 3 */\n
(function (window, rJS, $) {\n
"use strict";\n
\n
$.mobile.ajaxEnabled = false;\n
$.mobile.linkBindingEnabled = false;\n
$.mobile.hashListeningEnabled = false;\n
$.mobile.pushStateEnabled = false;\n
\n
var DEFAULT_PAGE = "upload",\n
GADGET_SCOPE = "connection";\n
\n
function redirectToDefaultPage(gadget) {\n
// Redirect to expected page by default\n
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})\n
.push(gadget.pleaseRedirectMyHash.bind(gadget));\n
}\n
\n
function renderShowPage(gadget) {\n
// we create a new show gadget here \n
return gadget.declareGadget(\'gadget_wendelin_show.html\', {\n
scope: GADGET_SCOPE, // is ok a gadget share same scope as another one ?\n
element: gadget.props.connection_element\n
})\n
// Ivan: when promises of creating a sub gadget is done we call callback in .push\n
// we use .push rather than .then due to cancel of RSVP written by romain\n
.push(function (sub_gadget) {\n
// we call render method which we defined on the gadget in a promise way\n
// options already saved in gadgets\' Ram representation\n
var options = gadget.props.options;\n
return sub_gadget.render(options);\n
});\n
}\n
\n
function renderUploadPage(gadget) {\n
// we create a new Upload gadget here \n
return gadget.declareGadget(\'gadget_wendelin_upload.html\', {\n
scope: GADGET_SCOPE,\n
element: gadget.props.connection_element\n
})\n
.push(function (sub_gadget) {\n
// we call render method which we defined on the gadget in a promise way\n
return sub_gadget.render();\n
});\n
}\n
\n
function renderListboxPage(gadget) {\n
// we create a new listbox gadget here \n
return gadget.declareGadget(\'gadget_wendelin_listbox.html\', {\n
scope: GADGET_SCOPE,\n
element: gadget.props.connection_element\n
})\n
.push(function (sub_gadget) {\n
// we call render method which we defined on the gadget in a promise way\n
return sub_gadget.render();\n
});\n
}\n
\n
rJS(window)\n
.ready(function (g) {\n
g.props = {};\n
// g.getElement() is a promise but we need result of it\n
return g.getElement()\n
.push(function (result) {\n
g.props.connection_element = result.querySelector(".gadget-content");\n
g.props.link_element = result.querySelector(".alldoclink");\n
g.props.upload_link_element = result.querySelector(".uploadlink");\n
});\n
})\n
// Configure jIO to use localstorage\n
.ready(function (g) {\n
return g.getDeclaredGadget("JIO")\n
.push(function (gadget) {\n
return gadget.createJio({\n
type: "query",\n
sub_storage: {\n
type: "indexeddb",\n
document_id: "/",\n
database: "test_ivan"\n
}\n
});\n
});\n
})\n
.ready(function (g) {\n
return g.aq_pleasePublishMyState({page: \'listbox\'})\n
.push(function (url) {\n
g.props.link_element.href = url;\n
})\n
.push (function() {\n
return g.aq_pleasePublishMyState({page: \'upload\'})\n
})\n
.push(function (url) {\n
g.props.upload_link_element.href = url;\n
});\n
})\n
\n
//////////////////////////////////////////\n
// Acquired method\n
//////////////////////////////////////////\n
.declareAcquiredMethod(\'pleaseRedirectMyHash\', \'pleaseRedirectMyHash\')\n
.allowPublicAcquisition("goAndSaveToHistory", function (param_list) {\n
window.location = param_list[0];\n
})\n
.allowPublicAcquisition("jio_allDocs", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.allDocs.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("jio_post", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.post.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("jio_put", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.put.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("aq_putAttachment", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.putAttachment.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("jio_get", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.get.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("aq_getAttachment", function (param_list) {\n
return this.getDeclaredGadget("JIO")\n
.push(function (jio_gadget) {\n
return jio_gadget.getAttachment.apply(jio_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("whoWantsToDisplayThisDocument",\n
function (param_list) {\n
// Hey, I want to display some jIO document\n
var kw = {\n
page: param_list[1] || "upload"\n
};\n
if (param_list[0] !== undefined) {\n
kw.id = param_list[0];\n
}\n
return this.aq_pleasePublishMyState(kw);\n
})\n
\n
//////////////////////////////////////////\n
// Declare method (methods of the gadget!)\n
//////////////////////////////////////////\n
.declareMethod(\'render\', function (options) {\n
var result,\n
gadget = this,\n
element = gadget.props.connection_element;\n
\n
gadget.props.options = options;\n
\n
// do clean up old DOM element\'s contents\n
while (element.firstChild) {\n
element.removeChild(element.firstChild);\n
}\n
\n
// based on page parameter show respective sub gadget inside same page\n
if (options.page === undefined) {\n
result = redirectToDefaultPage(this);\n
} else if (options.page === \'upload\') {\n
// show an upload page\n
result = renderUploadPage(gadget);\n
} else if (options.page === \'listbox\') {\n
// show an upload page\n
result = renderListboxPage(this);\n
} else if (options.page === \'show\') {\n
// show an upload page (ivan)\n
result = renderShowPage(this);\n
} else {\n
throw new Error(options.page);\n
}\n
\n
return result\n
// Let JQM know it has to render this\n
.push(function () {\n
$(gadget.props.element).trigger("create");\n
})\n
.push(undefined, function (error) {\n
// XXX Improve renderJS error class\n
if ((error instanceof Error) &&\n
(error.message === "Gadget scope \'" +\n
GADGET_SCOPE +\n
"\' is not known.")) {\n
// redirec to default page\n
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})\n
.push(gadget.pleaseRedirectMyHash.bind(gadget));\n
}\n
throw error;\n
});\n
});\n
\n
}(window, rJS, jQuery));
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Root Gadget\'s JS</string> </value> <value> <string>Wendelin Root Gadget\'s JS</string> </value>
......
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,
loopEventListener, jQuery, URI, location, console*/
/*jslint indent: 2*/
(function (window, document, RSVP, rJS, Handlebars, promiseEventListener,
$) {
"use strict";
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
var hateoas_url = "hateoas/",
PAGE_LIST = "list",
PAGE_NEW_EXPENSE_REPORT = "new_expense_report",
PAGE_CONNECTION = "connect",
PAGE_LOGOUT = "logout",
PAGE_SYNC = "sync",
PAGE_VIEW_EXPENSE_REPORT = "view",
DEFAULT_PAGE = PAGE_LIST,
query = 'portal_type:"Data Stream" OR portal_type:"Data Set" OR \
portal_type:"Data Supply" OR portal_type:"Data Acquisition Unit" OR \
portal_type:"Data Aggregation Unit" OR portal_type:"Data Analysis" OR \
portal_type:"Data Array" OR portal_type:"Data Ingestion" OR \
portal_type:"Data License" OR portal_type:"Data Operation" OR \
portal_type:"Data Product" OR portal_type:"Data Release" OR \
portal_type:"Data Set" OR portal_type:"Ingestion Policy" OR \
portal_type:"Sensor"';
//////////////////////////////////////////
// History Support with Jio
//////////////////////////////////////////
function createJio(gadget) {
return gadget.getDeclaredGadget("jio_gadget")
.push(function (jio_gadget) {
return jio_gadget.createJio({
type: "replicate",
query: {query: query, limit: [0, 1234567890]},
use_remote_post: true,
local_sub_storage: {
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: "erp5js_test60"
}
}
},
remote_sub_storage: {
type: "erp5",
url: (new URI(hateoas_url)).absoluteTo(location.href).toString(),
default_view_reference: "view"
}
});
});
}
//////////////////////////////////////////
// Page rendering
//////////////////////////////////////////
function redirectToDefaultPage(gadget) {
// Redirect to expected page by default
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})
.push(gadget.pleaseRedirectMyHash.bind(gadget));
}
function renderSynchroPage(gadget) {
return new RSVP.Queue()
.push(function () {
return gadget.aq_pleasePublishMyState({page: PAGE_LOGOUT});
})
.push(function (url) {
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Synchronize"
});
gadget.props.content_element.innerHTML =
gadget.props.synchro_template({});
$(gadget.props.element).trigger("create");
return promiseEventListener(
gadget.props.content_element.querySelector('form.synchro-form'),
'submit',
false
);
})
.push(function () {
gadget.props.content_element.querySelector("input[type=submit]")
.disabled = true;
return gadget.getDeclaredGadget("jio_gadget");
})
.push(function (jio_gadget) {
// XXX improve later
gadget.props.header_element.innerHTML = gadget.props.sync_loader_template({
title: "Synchronize"
});
// ivan dump to json dict
//jio_gadget.allDocs(query = query).push(function (response) {
// console.log(response.data.total_rows);
// for (i = 0; i < response.data.total_rows; i += 1) {
// console.log(response.data.rows[i].value.description);
// }
//});
// eof ivan
return jio_gadget.repair()
.push(function () {
return redirectToDefaultPage(gadget);
}, function (error) {
// XXX improve later
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Synchronize"
});
if (error.target !== undefined) {
if (error.target.status === 401) {
// Redirect to the login view
return gadget.aq_pleasePublishMyState({page: PAGE_CONNECTION})
.push(gadget.pleaseRedirectMyHash.bind(gadget));
}
if (error.target.status === 0) {
// No network?
gadget.props.content_element.innerHTML = "Can not sync";
$(gadget.props.element).trigger("create");
return;
}
}
throw error;
});
})
.push(function () {
// XXX improve later
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Synchronize"
});
});
}
function renderDocumentListPage(gadget) {
var documentlist = [];
return gadget.getDeclaredGadget("jio_gadget")
.push(function (jio) {
return RSVP.all([
gadget.aq_pleasePublishMyState({page: PAGE_SYNC}),
gadget.aq_pleasePublishMyState({page: PAGE_NEW_EXPENSE_REPORT}),
jio.allDocs({query: query,
sort_on: [["reference", "ascending"]],
select_list: ["reference", "description", "title",
"portal_type"],
limit: [0, 10000000]})
]);
})
.push(function (result_list) {
var i,
promise_list = [],
result = result_list[2];
for (i = 0; i < result.data.total_rows; i += 1) {
documentlist.push({
description: result.data.rows[i].value.description,
reference: result.data.rows[i].value.reference,
title: result.data.rows[i].value.title,
portal_type: result.data.rows[i].value.portal_type
});
if (!result.data.rows[i].value.reference) {
delete documentlist[documentlist.length - 1].reference;
}
promise_list.push(
gadget.aq_pleasePublishMyState({page: PAGE_VIEW_EXPENSE_REPORT, key: result.data.rows[i].id})
);
}
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Data Stream",
right_url: result_list[1],
right_title: "New"
});
return RSVP.all(promise_list);
})
.push(function (result_list) {
var i, json_dict = [];
//console.log(documentlist);
for (i = 0; i < result_list.length; i += 1) {
documentlist[i].url = result_list[i];
//add to json_dict
json_dict[i] = JSON.stringify(
{'title': documentlist[i].title,
'relative_url': documentlist[i].relative_url,
'portal_type': documentlist[i].portal_type,
'description': documentlist[i].description});
}
gadget.props.content_element.innerHTML =
gadget.props.document_list_template({
document_list: documentlist,
json_dict: json_dict,
// XXX Hardcoded
sync_url: "#page=sync"
});
$(gadget.props.element).trigger("create");
});
}
function renderConnectPage(gadget) {
return new RSVP.Queue()
.push(function () {
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Connect"
});
gadget.props.content_element.innerHTML =
gadget.props.login_template({});
$(gadget.props.element).trigger("create");
gadget.props.content_element.querySelector("input[type=text]")
.focus();
gadget.props.content_element.querySelector("input[type=text]")
.select();
return promiseEventListener(
gadget.props.content_element.querySelector('form.login-form'),
'submit',
false
);
})
.push(function (evt) {
gadget.props.content_element.querySelector("input[type=submit]")
.disabled = true;
var login = evt.target.elements[0].value,
passwd = evt.target.elements[1].value;
document.cookie = "__ac=" + window.btoa(login + ":" + passwd) + "; path=/";
return redirectToDefaultPage(gadget);
});
}
function renderLogoutPage(gadget) {
return new RSVP.Queue()
.push(function () {
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "Logout"
});
gadget.props.content_element.innerHTML =
gadget.props.logout_template({});
$(gadget.props.element).trigger("create");
return promiseEventListener(
gadget.props.content_element.querySelector('form.logout-form'),
'submit',
false
);
})
.push(function () {
gadget.props.content_element.querySelector("input[type=submit]")
.disabled = true;
document.cookie = "__ac=; path=/";
return redirectToDefaultPage(gadget);
});
}
function renderNewExpenseReportPage(gadget) {
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "New Data Stream"
});
gadget.props.content_element.innerHTML =
gadget.props.new_expense_report_template({});
$(gadget.props.element).trigger("create");
gadget.props.content_element.querySelector("input[type=text]")
.focus();
gadget.props.content_element.querySelector("input[type=text]")
.select();
return new RSVP.Queue()
.push(function () {
return RSVP.all([
promiseEventListener(
gadget.props.content_element.querySelector('form.new-expense-report-form'),
'submit',
false
),
gadget.getDeclaredGadget("jio_gadget")
]);
})
.push(function (result_list) {
var submit_event = result_list[0],
jio_gadget = result_list[1],
i,
doc = {
// XXX Hardcoded
parent_relative_url: "data_stream_module",
portal_type: "Data Stream"
}
gadget.props.content_element.querySelector("input[type=submit]")
.disabled = true;
for (i = 0; i < submit_event.target.length; i += 1) {
// XXX Should check input type instead
if (submit_event.target[i].name) {
doc[submit_event.target[i].name] = submit_event.target[i].value;
}
}
return jio_gadget.post(doc);
})
.push(function () {
return redirectToDefaultPage(gadget);
});
}
function renderViewExpenseReportPage(gadget, key) {
gadget.props.header_element.innerHTML = gadget.props.header_template({
title: "View Data Stream"
});
return gadget.getDeclaredGadget("jio_gadget")
.push(function (jio) {
return jio.get(key);
})
.push(function (doc) {
gadget.props.content_element.innerHTML =
gadget.props.view_expense_report_template(doc);
$(gadget.props.element).trigger("create");
// XXX JP asked to edit documents before sync
// Ivan: to have full example replace "!doc.reference" -> 1==1
if (1==1) {
gadget.props.header_element.innerHTML = gadget.props.edit_template({
title: "Edit Data Stream",
right_url: "Save"
});
return new RSVP.Queue()
.push(function () {
return RSVP.all([
promiseEventListener(
gadget.props.header_element.querySelector('form.edit-form'),
'submit',
false
),
gadget.getDeclaredGadget("jio_gadget")
]);
})
.push(function (result_list) {
var submit_form = gadget.props.content_element
.querySelector('.view-expense-report-form'),
jio_gadget = result_list[1],
i,
doc = {
// XXX Hardcoded
parent_relative_url: "data_stream_module",
portal_type: "Data Stream"
};
for (i = 0; i < submit_form.length; i += 1) {
if (submit_form[i].name) {
doc[submit_form[i].name] = submit_form[i].value;
}
}
return jio_gadget.put(key, doc);
})
.push(function () {
return redirectToDefaultPage(gadget);
});
}
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
$(element).trigger("create");
g.props.element = element;
g.props.header_element = element.querySelector('.gadget-header').querySelector('div');
g.props.content_element = element.querySelector('.gadget-content');
g.props.view_expense_report_template = Handlebars.compile(
document.querySelector(".view-expense-report-template").innerHTML
);
g.props.new_expense_report_template = Handlebars.compile(
document.querySelector(".new-expense-report-template").innerHTML
);
g.props.login_template = Handlebars.compile(
document.querySelector(".login-template").innerHTML
);
g.props.logout_template = Handlebars.compile(
document.querySelector(".logout-template").innerHTML
);
g.props.synchro_template = Handlebars.compile(
document.querySelector(".synchro-template").innerHTML
);
g.props.edit_template = Handlebars.compile(
document.querySelector(".edit-template").innerHTML
);
g.props.document_list_template = Handlebars.compile(
document.querySelector(".document-list-template").innerHTML
);
g.props.header_template = Handlebars.compile(
document.querySelector(".header-template").innerHTML
);
g.props.sync_loader_template = Handlebars.compile(
document.querySelector(".sync-loader-template").innerHTML
);
});
})
// Configure jIO storage
.ready(function (g) {
return createJio(g);
})
//////////////////////////////////////////
// Acquired method
//////////////////////////////////////////
.declareAcquiredMethod('pleaseRedirectMyHash', 'pleaseRedirectMyHash')
//////////////////////////////////////////
// Declare method
//////////////////////////////////////////
.declareMethod('render', function (options) {
var result,
gadget = this;
gadget.props.options = options;
if (options.page === undefined) {
result = redirectToDefaultPage(this);
} else if (options.page === PAGE_CONNECTION) {
result = renderConnectPage(this);
} else if (options.page === PAGE_LIST) {
result = renderDocumentListPage(this);
} else if (options.page === PAGE_SYNC) {
result = renderSynchroPage(this);
} else if (options.page === PAGE_NEW_EXPENSE_REPORT) {
result = renderNewExpenseReportPage(this);
} else if (options.page === PAGE_VIEW_EXPENSE_REPORT) {
result = renderViewExpenseReportPage(this, options.key);
} else if (options.page === PAGE_LOGOUT) {
result = renderLogoutPage(this);
} else {
throw new Error("not implemented page " + options.page);
}
return result;
});
}(window, document, RSVP, rJS, Handlebars, promiseEventListener, jQuery));
\ No newline at end of file
...@@ -94,450 +94,6 @@ ...@@ -94,450 +94,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
loopEventListener, jQuery, URI, location, console*/\n
/*jslint indent: 2*/\n
(function (window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
$) {\n
"use strict";\n
\n
$.mobile.ajaxEnabled = false;\n
$.mobile.linkBindingEnabled = false;\n
$.mobile.hashListeningEnabled = false;\n
$.mobile.pushStateEnabled = false;\n
\n
var hateoas_url = "hateoas/",\n
PAGE_LIST = "list",\n
PAGE_NEW_EXPENSE_REPORT = "new_expense_report",\n
PAGE_CONNECTION = "connect",\n
PAGE_LOGOUT = "logout",\n
PAGE_SYNC = "sync",\n
PAGE_VIEW_EXPENSE_REPORT = "view",\n
DEFAULT_PAGE = PAGE_LIST,\n
query = \'portal_type:"Data Stream" OR portal_type:"Data Set" OR \\\n
portal_type:"Data Supply" OR portal_type:"Data Acquisition Unit" OR \\\n
portal_type:"Data Aggregation Unit" OR portal_type:"Data Analysis" OR \\\n
portal_type:"Data Array" OR portal_type:"Data Ingestion" OR \\\n
portal_type:"Data License" OR portal_type:"Data Operation" OR \\\n
portal_type:"Data Product" OR portal_type:"Data Release" OR \\\n
portal_type:"Data Set" OR portal_type:"Ingestion Policy" OR \\\n
portal_type:"Sensor"\';\n
\n
//////////////////////////////////////////\n
// History Support with Jio\n
//////////////////////////////////////////\n
function createJio(gadget) {\n
return gadget.getDeclaredGadget("jio_gadget")\n
.push(function (jio_gadget) {\n
return jio_gadget.createJio({\n
type: "replicate",\n
query: {query: query, limit: [0, 1234567890]},\n
use_remote_post: true,\n
local_sub_storage: {\n
type: "query",\n
sub_storage: {\n
type: "uuid",\n
sub_storage: {\n
type: "indexeddb",\n
database: "erp5js_test60"\n
}\n
}\n
},\n
remote_sub_storage: {\n
type: "erp5",\n
url: (new URI(hateoas_url)).absoluteTo(location.href).toString(),\n
default_view_reference: "view"\n
}\n
});\n
\n
});\n
}\n
\n
//////////////////////////////////////////\n
// Page rendering\n
//////////////////////////////////////////\n
function redirectToDefaultPage(gadget) {\n
// Redirect to expected page by default\n
return gadget.aq_pleasePublishMyState({page: DEFAULT_PAGE})\n
.push(gadget.pleaseRedirectMyHash.bind(gadget));\n
}\n
\n
function renderSynchroPage(gadget) {\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.aq_pleasePublishMyState({page: PAGE_LOGOUT});\n
})\n
.push(function (url) {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Synchronize"\n
});\n
gadget.props.content_element.innerHTML =\n
gadget.props.synchro_template({});\n
$(gadget.props.element).trigger("create");\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.synchro-form\'),\n
\'submit\',\n
false\n
);\n
})\n
.push(function () {\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = true;\n
return gadget.getDeclaredGadget("jio_gadget");\n
})\n
.push(function (jio_gadget) {\n
// XXX improve later\n
gadget.props.header_element.innerHTML = gadget.props.sync_loader_template({\n
title: "Synchronize"\n
});\n
\n
// ivan dump to json dict\n
//jio_gadget.allDocs(query = query).push(function (response) {\n
// console.log(response.data.total_rows);\n
// for (i = 0; i < response.data.total_rows; i += 1) {\n
// console.log(response.data.rows[i].value.description);\n
// }\n
//});\n
// eof ivan\n
\n
return jio_gadget.repair()\n
.push(function () {\n
return redirectToDefaultPage(gadget);\n
}, function (error) {\n
// XXX improve later\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Synchronize"\n
});\n
if (error.target !== undefined) {\n
if (error.target.status === 401) {\n
// Redirect to the login view\n
return gadget.aq_pleasePublishMyState({page: PAGE_CONNECTION})\n
.push(gadget.pleaseRedirectMyHash.bind(gadget));\n
}\n
if (error.target.status === 0) {\n
// No network?\n
gadget.props.content_element.innerHTML = "Can not sync";\n
$(gadget.props.element).trigger("create");\n
return;\n
}\n
}\n
throw error;\n
});\n
})\n
.push(function () {\n
// XXX improve later\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Synchronize"\n
});\n
});\n
}\n
\n
function renderDocumentListPage(gadget) {\n
var documentlist = [];\n
return gadget.getDeclaredGadget("jio_gadget")\n
.push(function (jio) {\n
return RSVP.all([\n
gadget.aq_pleasePublishMyState({page: PAGE_SYNC}),\n
gadget.aq_pleasePublishMyState({page: PAGE_NEW_EXPENSE_REPORT}),\n
jio.allDocs({query: query, \n
sort_on: [["reference", "ascending"]], \n
select_list: ["reference", "description", "title", \n
"portal_type"], \n
limit: [0, 10000000]})\n
]);\n
})\n
.push(function (result_list) {\n
var i,\n
promise_list = [],\n
result = result_list[2];\n
for (i = 0; i < result.data.total_rows; i += 1) {\n
documentlist.push({\n
description: result.data.rows[i].value.description,\n
reference: result.data.rows[i].value.reference,\n
title: result.data.rows[i].value.title,\n
portal_type: result.data.rows[i].value.portal_type\n
});\n
if (!result.data.rows[i].value.reference) {\n
delete documentlist[documentlist.length - 1].reference;\n
}\n
promise_list.push(\n
gadget.aq_pleasePublishMyState({page: PAGE_VIEW_EXPENSE_REPORT, key: result.data.rows[i].id})\n
);\n
}\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Data Stream",\n
right_url: result_list[1],\n
right_title: "New"\n
});\n
return RSVP.all(promise_list);\n
})\n
.push(function (result_list) {\n
var i, json_dict = [];\n
//console.log(documentlist);\n
for (i = 0; i < result_list.length; i += 1) {\n
documentlist[i].url = result_list[i];\n
//add to json_dict\n
json_dict[i] = JSON.stringify(\n
{\'title\': documentlist[i].title,\n
\'relative_url\': documentlist[i].relative_url,\n
\'portal_type\': documentlist[i].portal_type,\n
\'description\': documentlist[i].description});\n
}\n
gadget.props.content_element.innerHTML =\n
gadget.props.document_list_template({\n
document_list: documentlist,\n
json_dict: json_dict,\n
// XXX Hardcoded\n
sync_url: "#page=sync"\n
});\n
$(gadget.props.element).trigger("create");\n
});\n
}\n
\n
function renderConnectPage(gadget) {\n
return new RSVP.Queue()\n
.push(function () {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Connect"\n
});\n
gadget.props.content_element.innerHTML =\n
gadget.props.login_template({});\n
$(gadget.props.element).trigger("create");\n
gadget.props.content_element.querySelector("input[type=text]")\n
.focus();\n
gadget.props.content_element.querySelector("input[type=text]")\n
.select();\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.login-form\'),\n
\'submit\',\n
false\n
);\n
})\n
.push(function (evt) {\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = true;\n
var login = evt.target.elements[0].value,\n
passwd = evt.target.elements[1].value;\n
document.cookie = "__ac=" + window.btoa(login + ":" + passwd) + "; path=/";\n
return redirectToDefaultPage(gadget);\n
});\n
}\n
\n
function renderLogoutPage(gadget) {\n
return new RSVP.Queue()\n
.push(function () {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "Logout"\n
});\n
gadget.props.content_element.innerHTML =\n
gadget.props.logout_template({});\n
$(gadget.props.element).trigger("create");\n
return promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.logout-form\'),\n
\'submit\',\n
false\n
);\n
})\n
.push(function () {\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = true;\n
document.cookie = "__ac=; path=/";\n
return redirectToDefaultPage(gadget);\n
});\n
}\n
\n
function renderNewExpenseReportPage(gadget) {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "New Data Stream"\n
});\n
gadget.props.content_element.innerHTML =\n
gadget.props.new_expense_report_template({});\n
$(gadget.props.element).trigger("create");\n
\n
gadget.props.content_element.querySelector("input[type=text]")\n
.focus();\n
gadget.props.content_element.querySelector("input[type=text]")\n
.select();\n
return new RSVP.Queue()\n
.push(function () {\n
return RSVP.all([\n
promiseEventListener(\n
gadget.props.content_element.querySelector(\'form.new-expense-report-form\'),\n
\'submit\',\n
false\n
),\n
gadget.getDeclaredGadget("jio_gadget")\n
]);\n
})\n
.push(function (result_list) {\n
var submit_event = result_list[0],\n
jio_gadget = result_list[1],\n
i,\n
doc = {\n
// XXX Hardcoded\n
parent_relative_url: "data_stream_module",\n
portal_type: "Data Stream"\n
}\n
gadget.props.content_element.querySelector("input[type=submit]")\n
.disabled = true;\n
\n
for (i = 0; i < submit_event.target.length; i += 1) {\n
// XXX Should check input type instead\n
if (submit_event.target[i].name) {\n
doc[submit_event.target[i].name] = submit_event.target[i].value;\n
}\n
}\n
\n
return jio_gadget.post(doc);\n
})\n
.push(function () {\n
return redirectToDefaultPage(gadget);\n
});\n
}\n
\n
\n
function renderViewExpenseReportPage(gadget, key) {\n
gadget.props.header_element.innerHTML = gadget.props.header_template({\n
title: "View Data Stream"\n
});\n
return gadget.getDeclaredGadget("jio_gadget")\n
.push(function (jio) {\n
return jio.get(key);\n
})\n
.push(function (doc) {\n
gadget.props.content_element.innerHTML =\n
gadget.props.view_expense_report_template(doc);\n
$(gadget.props.element).trigger("create");\n
\n
// XXX JP asked to edit documents before sync\n
// Ivan: to have full example replace "!doc.reference" -> 1==1\n
if (1==1) {\n
gadget.props.header_element.innerHTML = gadget.props.edit_template({\n
title: "Edit Data Stream",\n
right_url: "Save"\n
});\n
\n
return new RSVP.Queue()\n
.push(function () {\n
return RSVP.all([\n
promiseEventListener(\n
gadget.props.header_element.querySelector(\'form.edit-form\'),\n
\'submit\',\n
false\n
),\n
gadget.getDeclaredGadget("jio_gadget")\n
]);\n
})\n
.push(function (result_list) {\n
var submit_form = gadget.props.content_element\n
.querySelector(\'.view-expense-report-form\'),\n
jio_gadget = result_list[1],\n
i,\n
doc = {\n
// XXX Hardcoded\n
parent_relative_url: "data_stream_module",\n
portal_type: "Data Stream"\n
};\n
for (i = 0; i < submit_form.length; i += 1) {\n
if (submit_form[i].name) {\n
doc[submit_form[i].name] = submit_form[i].value;\n
}\n
}\n
return jio_gadget.put(key, doc);\n
})\n
.push(function () {\n
return redirectToDefaultPage(gadget);\n
});\n
}\n
});\n
}\n
\n
\n
rJS(window)\n
.ready(function (g) {\n
g.props = {};\n
return g.getElement()\n
.push(function (element) {\n
$(element).trigger("create");\n
g.props.element = element;\n
g.props.header_element = element.querySelector(\'.gadget-header\').querySelector(\'div\');\n
g.props.content_element = element.querySelector(\'.gadget-content\');\n
\n
g.props.view_expense_report_template = Handlebars.compile(\n
document.querySelector(".view-expense-report-template").innerHTML\n
);\n
g.props.new_expense_report_template = Handlebars.compile(\n
document.querySelector(".new-expense-report-template").innerHTML\n
);\n
g.props.login_template = Handlebars.compile(\n
document.querySelector(".login-template").innerHTML\n
);\n
g.props.logout_template = Handlebars.compile(\n
document.querySelector(".logout-template").innerHTML\n
);\n
g.props.synchro_template = Handlebars.compile(\n
document.querySelector(".synchro-template").innerHTML\n
);\n
g.props.edit_template = Handlebars.compile(\n
document.querySelector(".edit-template").innerHTML\n
);\n
g.props.document_list_template = Handlebars.compile(\n
document.querySelector(".document-list-template").innerHTML\n
);\n
g.props.header_template = Handlebars.compile(\n
document.querySelector(".header-template").innerHTML\n
);\n
g.props.sync_loader_template = Handlebars.compile(\n
document.querySelector(".sync-loader-template").innerHTML\n
);\n
});\n
})\n
// Configure jIO storage\n
.ready(function (g) {\n
return createJio(g);\n
})\n
\n
//////////////////////////////////////////\n
// Acquired method\n
//////////////////////////////////////////\n
.declareAcquiredMethod(\'pleaseRedirectMyHash\', \'pleaseRedirectMyHash\')\n
\n
//////////////////////////////////////////\n
// Declare method\n
//////////////////////////////////////////\n
.declareMethod(\'render\', function (options) {\n
var result,\n
gadget = this;\n
gadget.props.options = options;\n
\n
if (options.page === undefined) {\n
result = redirectToDefaultPage(this);\n
} else if (options.page === PAGE_CONNECTION) {\n
result = renderConnectPage(this);\n
} else if (options.page === PAGE_LIST) {\n
result = renderDocumentListPage(this);\n
} else if (options.page === PAGE_SYNC) {\n
result = renderSynchroPage(this);\n
} else if (options.page === PAGE_NEW_EXPENSE_REPORT) {\n
result = renderNewExpenseReportPage(this);\n
} else if (options.page === PAGE_VIEW_EXPENSE_REPORT) {\n
result = renderViewExpenseReportPage(this, options.key);\n
} else if (options.page === PAGE_LOGOUT) {\n
result = renderLogoutPage(this);\n
} else {\n
throw new Error("not implemented page " + options.page);\n
}\n
return result;\n
});\n
\n
}(window, document, RSVP, rJS, Handlebars, promiseEventListener, jQuery));
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>RenderJS Gadget Eexpense JS</string> </value> <value> <string>RenderJS Gadget Eexpense JS</string> </value>
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Upload page</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_wendelin_upload.js"></script>
</head>
<body>
<h1>Upload dialog (saves upload to IndexedDB)</h1>
<form class="import_form">
<input id="dream_import" class="ui-btn ui-btn-b ui-btn-inline" type="file" required name="dream_import"></input>
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline ui-icon-plus ui-btn-icon-right">Import</button>
</form>
</body>
</html>
...@@ -99,39 +99,6 @@ ...@@ -99,39 +99,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!doctype html>\n
<html>\n
<head>\n
<meta charset="utf-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1">\n
\n
<title>Upload page</title>\n
\n
<script src="rsvp.js"></script>\n
<script src="renderjs.js"></script>\n
<script src="gadget_wendelin_upload.js"></script>\n
\n
</head>\n
\n
<body>\n
\n
<h1>Upload dialog (saves upload to IndexedDB)</h1>\n
\n
<form class="import_form">\n
<input id="dream_import" class="ui-btn ui-btn-b ui-btn-inline" type="file" required name="dream_import"></input>\n
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline ui-icon-plus ui-btn-icon-right">Import</button>\n
</form>\n
\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Upload Gadget</string> </value> <value> <string>Wendelin Upload Gadget</string> </value>
......
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,
loopEventListener, jQuery, promiseReadAsText*/
/*jslint indent: 2, maxerr: 3 */
(function () {
"use strict";
function randomString(length) {
var i,
str = '',
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');
if (!length) {
length = Math.floor(Math.random() * chars.length);
}
for (i = 0; i < length; i = i + 1) {
str += chars[Math.floor(Math.random() * chars.length)];
}
return str;
}
function waitForImport(gadget) {
var name,
upload_file;
return new RSVP.Queue()
.push(function () {
return gadget.getElement();
})
.push(function (element) {
return promiseEventListener(
element.getElementsByClassName("import_form")[0],
'submit',
false
);
})
.push(function (evt) {
// Prevent double click
var now = new Date();
evt.target
.getElementsByClassName("ui-btn")[0].disabled = true;
upload_file = evt.target.dream_import.files[0];
name = upload_file.name;
// Create jIO document
//XX: fail here!!!!
return gadget.aq_put({
_id: randomString(12),
title: name,
type: "Dream",
format: "application/json",
modified: now.toUTCString(),
date: now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate()
});
})
.push(function (id) {
gadget.foo_id = id;
// Add JSON as attachment
return gadget.aq_putAttachment({
"_id": id,
"_attachment": "body.json",
"_data": upload_file,
"_mimetype": "application/json"
});
});
}
// Ivan: we extend gadget API like so:
rJS(window).declareMethod('render', function () {
return 'this is render method in a subgadget';
})
// ivan: decalre we want to use JIO functionality as an alias (aq_post)
.declareAcquiredMethod("aq_post", "jio_post")
.declareAcquiredMethod("aq_put", "jio_put")
.declareAcquiredMethod("aq_putAttachment", "aq_putAttachment")
.declareAcquiredMethod("whoWantsToDisplayThisDocument", "whoWantsToDisplayThisDocument")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
.declareAcquiredMethod("goAndSaveToHistory", "goAndSaveToHistory")
// catch form submission
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
// wait for user input of upload file.
return waitForImport(gadget);
})
.push(function () {
// ask RenderJs create an URL for us which represents the current "state" of the application
return gadget.whoWantsToDisplayThisDocument(gadget.foo_id, 'show');
})
.push(function (url) {
// redirect to url produced from previous call
return gadget.goAndSaveToHistory(url);
});
});
}());
\ No newline at end of file
...@@ -97,113 +97,6 @@ ...@@ -97,113 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
loopEventListener, jQuery, promiseReadAsText*/\n
/*jslint indent: 2, maxerr: 3 */\n
\n
(function () {\n
"use strict";\n
\n
function randomString(length) {\n
var i,\n
str = \'\',\n
chars = \'0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\'.split(\'\');\n
\n
if (!length) {\n
length = Math.floor(Math.random() * chars.length);\n
}\n
\n
for (i = 0; i < length; i = i + 1) {\n
str += chars[Math.floor(Math.random() * chars.length)];\n
}\n
return str;\n
}\n
\n
function waitForImport(gadget) {\n
var name,\n
upload_file;\n
\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.getElement();\n
})\n
.push(function (element) {\n
return promiseEventListener(\n
element.getElementsByClassName("import_form")[0],\n
\'submit\',\n
false\n
);\n
})\n
.push(function (evt) {\n
// Prevent double click\n
var now = new Date();\n
evt.target\n
.getElementsByClassName("ui-btn")[0].disabled = true;\n
\n
upload_file = evt.target.dream_import.files[0];\n
name = upload_file.name;\n
\n
// Create jIO document\n
//XX: fail here!!!!\n
return gadget.aq_put({\n
_id: randomString(12),\n
title: name,\n
type: "Dream",\n
format: "application/json",\n
modified: now.toUTCString(),\n
date: now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate()\n
});\n
})\n
.push(function (id) {\n
gadget.foo_id = id;\n
// Add JSON as attachment\n
return gadget.aq_putAttachment({\n
"_id": id,\n
"_attachment": "body.json",\n
"_data": upload_file,\n
"_mimetype": "application/json"\n
});\n
});\n
}\n
// Ivan: we extend gadget API like so:\n
rJS(window).declareMethod(\'render\', function () {\n
return \'this is render method in a subgadget\';\n
})\n
\n
// ivan: decalre we want to use JIO functionality as an alias (aq_post)\n
.declareAcquiredMethod("aq_post", "jio_post")\n
.declareAcquiredMethod("aq_put", "jio_put")\n
.declareAcquiredMethod("aq_putAttachment", "aq_putAttachment")\n
.declareAcquiredMethod("whoWantsToDisplayThisDocument", "whoWantsToDisplayThisDocument")\n
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")\n
.declareAcquiredMethod("goAndSaveToHistory", "goAndSaveToHistory")\n
\n
// catch form submission\n
.declareService(function () {\n
var gadget = this;\n
\n
return new RSVP.Queue()\n
.push(function () {\n
// wait for user input of upload file.\n
return waitForImport(gadget);\n
})\n
.push(function () {\n
// ask RenderJs create an URL for us which represents the current "state" of the application\n
return gadget.whoWantsToDisplayThisDocument(gadget.foo_id, \'show\');\n
})\n
.push(function (url) {\n
// redirect to url produced from previous call\n
return gadget.goAndSaveToHistory(url);\n
});\n
});\n
}());
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Upload Gadget JS</string> </value> <value> <string>Wendelin Upload Gadget JS</string> </value>
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Visualisation Gadget</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_wendelin_show.js"></script>
</head>
<body>
<h1>Diagram gadget</h1>
<div data-gadget-url="gadget_wendelin_graph.html" data-gadget-scope="Visualise"></div>
</body>
</html>
...@@ -99,36 +99,6 @@ ...@@ -99,36 +99,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<!doctype html>\n
<html>\n
<head>\n
<meta charset="utf-8">\n
<meta name="viewport" content="width=device-width, initial-scale=1">\n
\n
<title>Visualisation Gadget</title>\n
\n
<script src="rsvp.js"></script>\n
<script src="renderjs.js"></script>\n
<script src="gadget_wendelin_show.js"></script>\n
\n
</head>\n
\n
<body>\n
\n
<h1>Diagram gadget</h1>\n
\n
<div data-gadget-url="gadget_wendelin_graph.html" data-gadget-scope="Visualise"></div>\n
\n
</body>\n
</html>\n
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Show Gadget</string> </value> <value> <string>Wendelin Show Gadget</string> </value>
......
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,
loopEventListener, jQuery, console, jIO*/
/*jslint indent: 2, maxerr: 3 */
(function () {
"use strict";
// Ivan: we extend gadget API like so:
rJS(window).declareMethod('render', function (options) {
var gadget = this;
return gadget.aq_getAttachment({
"_id": options.id,
"_attachment": "body.json"
})
.push(function (result) {
// XXX: not nice use directly jio!
//return jIO.util.readBlobAsText(result.data); -> old way
return jIO.util.readBlobAsArrayBuffer(result.data);
})
.push(function (event) {
gadget.data = event.target.result;
// getDeclaredGadget uses scope to get a sub gadget, which is a promise
return gadget.getDeclaredGadget('Visualise');
})
.push(function (sub_gadget) {
sub_gadget.draw(gadget.data);
});
})
// ivan: decalre we want to use JIO functionality as an alias (aq_post)
.declareAcquiredMethod("aq_get", "jio_get")
.declareAcquiredMethod("aq_getAttachment", "aq_getAttachment");
}());
\ No newline at end of file
...@@ -97,47 +97,6 @@ ...@@ -97,47 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*globals window, document, RSVP, rJS, Handlebars, promiseEventListener,\n
loopEventListener, jQuery, console, jIO*/\n
/*jslint indent: 2, maxerr: 3 */\n
(function () {\n
"use strict";\n
\n
// Ivan: we extend gadget API like so:\n
rJS(window).declareMethod(\'render\', function (options) {\n
var gadget = this;\n
\n
return gadget.aq_getAttachment({\n
"_id": options.id,\n
"_attachment": "body.json"\n
})\n
.push(function (result) {\n
// XXX: not nice use directly jio!\n
//return jIO.util.readBlobAsText(result.data); -> old way\n
return jIO.util.readBlobAsArrayBuffer(result.data);\n
})\n
.push(function (event) {\n
gadget.data = event.target.result;\n
// getDeclaredGadget uses scope to get a sub gadget, which is a promise\n
return gadget.getDeclaredGadget(\'Visualise\');\n
})\n
.push(function (sub_gadget) {\n
sub_gadget.draw(gadget.data);\n
});\n
})\n
\n
// ivan: decalre we want to use JIO functionality as an alias (aq_post)\n
.declareAcquiredMethod("aq_get", "jio_get")\n
.declareAcquiredMethod("aq_getAttachment", "aq_getAttachment");\n
\n
}());
]]></string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin Show Gadget JS</string> </value> <value> <string>Wendelin Show Gadget JS</string> </value>
......
/* ======================= DYGRAPH CSS FORMATTING ========================== */
.dygraph-title,
.dygraph-label,
.dygraph-axis-label {
color: gray;
font-family: Helvetica,Arial,sans-serif;
font-weight: normal;
padding: 0.1em;
}
.dygraph-title {
font-size: 75%;
}
\ No newline at end of file
...@@ -97,21 +97,6 @@ ...@@ -97,21 +97,6 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content</string> </key>
<value> <string>/* ======================= DYGRAPH CSS FORMATTING ========================== */\n
.dygraph-title,\n
.dygraph-label,\n
.dygraph-axis-label {\n
color: gray;\n
font-family: Helvetica,Arial,sans-serif;\n
font-weight: normal;\n
padding: 0.1em;\n
}\n
.dygraph-title {\n
font-size: 75%;\n
}</string> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Wendelin: DYGRAPH CSS FORMATTING</string> </value> <value> <string>Wendelin: DYGRAPH CSS FORMATTING</string> </value>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment