todict: better support for callback
This commit is contained in:
parent
5ea35bf84e
commit
552cd3740d
6 changed files with 97 additions and 98 deletions
|
@ -14,7 +14,7 @@
|
||||||
"model": {},
|
"model": {},
|
||||||
"form": {
|
"form": {
|
||||||
"options.integer": {
|
"options.integer": {
|
||||||
"allowedpattern": "[0-9]",
|
"pattern": "^[0-9]+$",
|
||||||
"type": "input"
|
"type": "input"
|
||||||
},
|
},
|
||||||
"null": [
|
"null": [
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
},
|
},
|
||||||
"form": {
|
"form": {
|
||||||
"options.integer": {
|
"options.integer": {
|
||||||
"allowedpattern": "[0-9]",
|
"pattern": "^[0-9]+$",
|
||||||
"type": "input"
|
"type": "input"
|
||||||
},
|
},
|
||||||
"null": [
|
"null": [
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"form": {
|
"form": {
|
||||||
"options.integer": {
|
"options.integer": {
|
||||||
"clearable": true,
|
"clearable": true,
|
||||||
"allowedpattern": "[0-9]",
|
"pattern": "^[0-9]+$",
|
||||||
"type": "input"
|
"type": "input"
|
||||||
},
|
},
|
||||||
"null": [
|
"null": [
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"form": {
|
"form": {
|
||||||
"options.integer": {
|
"options.integer": {
|
||||||
"clearable": true,
|
"clearable": true,
|
||||||
"allowedpattern": "[0-9]",
|
"pattern": "^[0-9]+$",
|
||||||
"type": "input"
|
"type": "input"
|
||||||
},
|
},
|
||||||
"null": [
|
"null": [
|
||||||
|
|
|
@ -271,6 +271,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
||||||
if isinstance(option, RegexpOption):
|
if isinstance(option, RegexpOption):
|
||||||
return option._regexp.pattern
|
return option._regexp.pattern
|
||||||
if type == 'integer':
|
if type == 'integer':
|
||||||
|
# FIXME negative too!
|
||||||
return r'^[0-9]+$'
|
return r'^[0-9]+$'
|
||||||
if type == 'domainname':
|
if type == 'domainname':
|
||||||
return option.impl_get_extra('_domain_re').pattern
|
return option.impl_get_extra('_domain_re').pattern
|
||||||
|
@ -384,11 +385,11 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
"""Remove new property for an option"""
|
"""Remove new property for an option"""
|
||||||
option = self._option_bag.option
|
option = self._option_bag.option
|
||||||
props = self._settings.getproperties(self._option_bag,
|
props = self._settings.getproperties(self._option_bag,
|
||||||
apply_requires=False)
|
apply_requires=False)
|
||||||
self._settings.setproperties(self._option_bag.path,
|
self._settings.setproperties(self._option_bag.path,
|
||||||
props - {prop},
|
props - {prop},
|
||||||
self._option_bag,
|
self._option_bag,
|
||||||
self._option_bag.config_bag.context)
|
self._option_bag.config_bag.context)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset all personalised properties"""
|
"""Reset all personalised properties"""
|
||||||
|
|
|
@ -46,68 +46,54 @@ class Callbacks(object):
|
||||||
def add(self,
|
def add(self,
|
||||||
path,
|
path,
|
||||||
childapi,
|
childapi,
|
||||||
options,
|
|
||||||
schema,
|
schema,
|
||||||
force_store_value):
|
force_store_value):
|
||||||
self.callbacks.append((path, childapi, options, schema, force_store_value))
|
if self.remotable == 'all' or childapi.option.isoptiondescription():
|
||||||
|
return
|
||||||
|
callback, callback_params = childapi.option.callbacks()
|
||||||
|
if callback is None: # FIXME ? and force_store_value and self.clearable != 'all':
|
||||||
|
return
|
||||||
|
self.callbacks.append((callback, callback_params, path, childapi, schema, force_store_value))
|
||||||
|
|
||||||
def manage_callbacks(self,
|
def process_properties(self, form):
|
||||||
path,
|
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
|
||||||
childapi,
|
has_option = False
|
||||||
options,
|
if callback_params is not None:
|
||||||
callback,
|
for callback_param in callback_params.args:
|
||||||
callback_params,
|
if isinstance(callback_param, ParamContext):
|
||||||
form,
|
raise ValueError(_('context is not supported from now for {}').format(path))
|
||||||
schema):
|
if isinstance(callback_param, ParamOption):
|
||||||
if callback_params is not None:
|
has_option = True
|
||||||
remote = True
|
if callback.__name__ != 'tiramisu_copy' or 'expire' in childapi.option.properties():
|
||||||
for callback_param in callback_params.args:
|
if self.remotable == 'none':
|
||||||
if isinstance(callback_param, ParamContext):
|
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
|
||||||
raise ValueError(_('context is not supported from now for {}').format(path))
|
form[callback_param.option.impl_getpath()]['remote'] = True
|
||||||
if isinstance(callback_param, ParamOption):
|
remote = True
|
||||||
if callback.__name__ == 'tiramisu_copy':
|
if not has_option and form.get(path, {}).get('remote') == False:
|
||||||
if self.clearable == 'minimum':
|
if 'expire' in childapi.option.properties():
|
||||||
form.setdefault(path, {})['clearable'] = True
|
if self.remotable == 'none':
|
||||||
if form.get(path, {}).get('remote') is not True and form[options[callback_param.option]].get('remote', False) is not True:
|
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
|
||||||
form.setdefault(options[callback_param.option], {})
|
form.setdefault(path, {})['remote'] = True
|
||||||
form[options[callback_param.option]].setdefault('copy', []).append(path)
|
elif childapi.owner.isdefault():
|
||||||
remote = False
|
# get calculated value and set clearable
|
||||||
elif options.get(callback_param.option) is not None:
|
schema[path]['value'] = childapi.value.get()
|
||||||
#form.setdefault(options[callback_param.option], {})
|
if self.clearable == 'minimum':
|
||||||
form.setdefault(path, {})
|
form.setdefault(path, {})['clearable'] = True
|
||||||
form[path]['remote'] = True
|
|
||||||
#break
|
|
||||||
if remote:
|
|
||||||
if self.remotable == 'none':
|
|
||||||
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
|
|
||||||
form.setdefault(path, {})['remote'] = True
|
|
||||||
else:
|
|
||||||
if 'expire' not in childapi.property.get() and childapi.owner.isdefault():
|
|
||||||
schema[path]['value'] = childapi.value.get()
|
|
||||||
if self.clearable == 'minimum':
|
|
||||||
form.setdefault(path, {})['clearable'] = True
|
|
||||||
else:
|
|
||||||
if self.remotable == 'none':
|
|
||||||
raise ValueError(_('option {} only works when remotable is not "none"').format(path))
|
|
||||||
# FIXME is not default, show calculate
|
|
||||||
form.setdefault(path, {})['remote'] = True
|
|
||||||
|
|
||||||
|
def manage_callbacks(self, form):
|
||||||
|
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
|
||||||
|
if callback_params is not None:
|
||||||
|
for callback_param in callback_params.args:
|
||||||
|
if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
|
||||||
|
opt_path = callback_param.option.impl_getpath()
|
||||||
|
if form.get(opt_path, {}).get('remote') is not True:
|
||||||
|
form.setdefault(opt_path, {})
|
||||||
|
form[opt_path].setdefault('copy', []).append(path)
|
||||||
|
|
||||||
def process(self,
|
def process(self,
|
||||||
form):
|
form):
|
||||||
for path, childapi, options, schema, force_store_value in self.callbacks:
|
self.process_properties(form)
|
||||||
if not childapi.option.isoptiondescription():
|
self.manage_callbacks(form)
|
||||||
callback, callback_params = childapi.option.callbacks()
|
|
||||||
if callback is not None:
|
|
||||||
if force_store_value and self.clearable != 'all':
|
|
||||||
return
|
|
||||||
self.manage_callbacks(path,
|
|
||||||
childapi,
|
|
||||||
options,
|
|
||||||
callback,
|
|
||||||
callback_params,
|
|
||||||
form,
|
|
||||||
schema)
|
|
||||||
|
|
||||||
|
|
||||||
class Consistencies(object):
|
class Consistencies(object):
|
||||||
|
@ -158,7 +144,6 @@ class Requires(object):
|
||||||
self.remotable = tiramisu_web.remotable
|
self.remotable = tiramisu_web.remotable
|
||||||
|
|
||||||
def manage_requires(self,
|
def manage_requires(self,
|
||||||
require_obj,
|
|
||||||
childapi,
|
childapi,
|
||||||
path,
|
path,
|
||||||
form,
|
form,
|
||||||
|
@ -170,58 +155,63 @@ class Requires(object):
|
||||||
transitive, same_action, operator = require
|
transitive, same_action, operator = require
|
||||||
if transitive is False:
|
if transitive is False:
|
||||||
# transitive to "False" not supported yet for a requirement
|
# transitive to "False" not supported yet for a requirement
|
||||||
if require_obj.remotable == 'none':
|
if self.remotable == 'none':
|
||||||
raise ValueError('require set for {} but remotable is "none"'
|
raise ValueError('require set for {} but remotable is "none"'
|
||||||
''.format(path))
|
''.format(path))
|
||||||
form.setdefault(path, {'key': path})['remote'] = True
|
form.setdefault(path, {'key': path})['remote'] = True
|
||||||
return
|
return
|
||||||
if same_action is False:
|
if same_action is False:
|
||||||
# same_action to "False" not supported yet for a requirement
|
# same_action to "False" not supported yet for a requirement
|
||||||
if require_obj.remotable == 'none':
|
if self.remotable == 'none':
|
||||||
raise ValueError('require set for {} but remotable is "none"'
|
raise ValueError('require set for {} but remotable is "none"'
|
||||||
''.format(path))
|
''.format(path))
|
||||||
form.setdefault(path, {'key': path})['remote'] = True
|
form.setdefault(path, {'key': path})['remote'] = True
|
||||||
return
|
return
|
||||||
if operator == 'and':
|
if operator == 'and':
|
||||||
# operator "and" not supported yet for a requirement
|
# operator "and" not supported yet for a requirement
|
||||||
if require_obj.remotable == 'none':
|
if self.remotable == 'none':
|
||||||
raise ValueError('require set for {} but remotable is "none"'
|
raise ValueError('require set for {} but remotable is "none"'
|
||||||
''.format(path))
|
''.format(path))
|
||||||
form.setdefault(path, {'key': path})['remote'] = True
|
form.setdefault(path, {'key': path})['remote'] = True
|
||||||
return
|
return
|
||||||
for option, expected in options:
|
for option, expected in options:
|
||||||
option_path = require_obj.options.get(option)
|
option_path = self.options.get(option)
|
||||||
if option_path is not None and action in action_hide:
|
if option_path is not None and action in action_hide:
|
||||||
if current_action is None:
|
if current_action is None:
|
||||||
current_action = action
|
current_action = action
|
||||||
elif current_action != action:
|
elif current_action != action:
|
||||||
if require_obj.remotable == 'none':
|
if self.remotable == 'none':
|
||||||
raise ValueError('require set for {} but remotable is "none"'
|
raise ValueError('require set for {} but remotable is "none"'
|
||||||
''.format(path))
|
''.format(path))
|
||||||
form.setdefault(option_path, {'key': option_path})['remote'] = True
|
form.setdefault(option_path, {'key': option_path})['remote'] = True
|
||||||
|
if inverse:
|
||||||
|
act = 'show'
|
||||||
|
inv_act = 'hide'
|
||||||
|
else:
|
||||||
|
act = 'hide'
|
||||||
|
inv_act = 'show'
|
||||||
for exp in expected:
|
for exp in expected:
|
||||||
if inverse:
|
self.requires.setdefault(path,
|
||||||
act = 'show'
|
{'expected': {}}
|
||||||
inv_act = 'hide'
|
)['expected'].setdefault(exp,
|
||||||
else:
|
{}).setdefault(act,
|
||||||
act = 'hide'
|
[]).append(option_path)
|
||||||
inv_act = 'show'
|
if isinstance(option, ChoiceOption):
|
||||||
require_obj.requires.setdefault(path,
|
choice_obj = self.config.unrestraint.option(option_path)
|
||||||
{'expected': {}}
|
values = self.tiramisu_web.get_enum(choice_obj,
|
||||||
)['expected'].setdefault(exp,
|
choice_obj.option.ismulti(),
|
||||||
{}).setdefault(act,
|
option_path,
|
||||||
[]).append(option_path)
|
choice_obj.option.properties())
|
||||||
if isinstance(option, ChoiceOption):
|
for value in values:
|
||||||
for value in require_obj.config.unrestraint.option(option_path).value.list():
|
if value not in expected:
|
||||||
if value not in expected:
|
self.requires.setdefault(path,
|
||||||
require_obj.requires.setdefault(path,
|
{'expected': {}}
|
||||||
{'expected': {}}
|
)['expected'].setdefault(value,
|
||||||
)['expected'].setdefault(value,
|
{}).setdefault(inv_act,
|
||||||
{}).setdefault(inv_act,
|
[]).append(option_path)
|
||||||
[]).append(option_path)
|
self.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path)
|
||||||
require_obj.requires[path].setdefault('default', {}).setdefault(inv_act, []).append(option_path)
|
|
||||||
else:
|
else:
|
||||||
if require_obj.remotable == 'none':
|
if self.remotable == 'none':
|
||||||
raise ValueError('require set for {} but remotable est "none"'
|
raise ValueError('require set for {} but remotable est "none"'
|
||||||
''.format(path))
|
''.format(path))
|
||||||
form.setdefault(option_path, {'key': option_path})['remote'] = True
|
form.setdefault(option_path, {'key': option_path})['remote'] = True
|
||||||
|
@ -234,8 +224,7 @@ class Requires(object):
|
||||||
self.options[child] = path
|
self.options[child] = path
|
||||||
current_action = None
|
current_action = None
|
||||||
|
|
||||||
self.manage_requires(self,
|
self.manage_requires(childapi,
|
||||||
childapi,
|
|
||||||
path,
|
path,
|
||||||
form,
|
form,
|
||||||
ACTION_HIDE,
|
ACTION_HIDE,
|
||||||
|
@ -384,7 +373,6 @@ class TiramisuDict:
|
||||||
childapi)
|
childapi)
|
||||||
self.callbacks.add(path,
|
self.callbacks.add(path,
|
||||||
childapi,
|
childapi,
|
||||||
self.requires.options,
|
|
||||||
schema,
|
schema,
|
||||||
'force_store_value' in props_no_requires)
|
'force_store_value' in props_no_requires)
|
||||||
childapi_option = childapi.option
|
childapi_option = childapi.option
|
||||||
|
@ -503,12 +491,22 @@ class TiramisuDict:
|
||||||
schema[path]['autoFreeze'] = True
|
schema[path]['autoFreeze'] = True
|
||||||
|
|
||||||
if web_type == 'choice':
|
if web_type == 'choice':
|
||||||
schema[path]['enum'] = childapi.value.list()
|
schema[path]['enum'] = self.get_enum(childapi,
|
||||||
empty_is_required = not childapi.option.isfollower() and is_multi
|
is_multi,
|
||||||
if (empty_is_required and not 'empty' in props_no_requires) or \
|
path,
|
||||||
(not empty_is_required and not 'mandatory' in props_no_requires):
|
props_no_requires)
|
||||||
schema[path]['enum'] = [''] + list(schema[path]['enum'])
|
|
||||||
|
|
||||||
|
def get_enum(self,
|
||||||
|
childapi,
|
||||||
|
is_multi,
|
||||||
|
path,
|
||||||
|
props_no_requires):
|
||||||
|
values = childapi.value.list()
|
||||||
|
empty_is_required = not childapi.option.isfollower() and is_multi
|
||||||
|
if '' not in values and ((empty_is_required and not 'empty' in props_no_requires) or \
|
||||||
|
(not empty_is_required and not 'mandatory' in props_no_requires)):
|
||||||
|
values = [''] + list(values)
|
||||||
|
return values
|
||||||
|
|
||||||
def gen_form(self,
|
def gen_form(self,
|
||||||
form,
|
form,
|
||||||
|
|
Loading…
Reference in a new issue