- we aim at GHC 7.4.1 compatibility;
- snap-0.8 is required;
- Backbone 0.9.1 is included with backported patch from upstream;
- bootstrap-typeahead is custom (source is a dictionary entry (see below), source annotation is eval’d, show on click)
- bootstrap-datepicker is custom (data API, optional autoshow)
`meta` bag of every field contains client-only annotations.
Supported annotations:
- `dictionaryName`: set name of dictionary when field type is `dictionary` (see section below)
- `dictionaryParent`: set parent dictionary for dependent dictionary (see section below)
- `mainToo`: when specified in member of group, field is rendered in main pane, too (in addition to rendering in view of group)
- `mainOnly`: render member of group in main section only. When specified for first member of group, no link to central pane is rendered.
- `readonly`: render field as readonly. To really set permissions, use canRead/canWrite
- `widget`: override template used for field (can specify `radio` for dictionary fields here to use `radio-dictionary-field-template` instead of `dictionary-field-template`. See also pickTemplate @ metamodel.js)
- `required`: highlight field with red outline and show it in rightmost pane when it’s empty
- `default`: set default value for field
- `invisible`: do not show field at all
- `infoText`: extra tip for field to show in hover bubble
Non-meta field annotations are described in snaplet-redson docs.
`dictionaries.json` holds a list of dictionary records.
Flat syntax for dictionary record:
"Transmission": {
"entries": [
{
"value": "auto",
"label": "Автоматическая"
},
{
"value": "mech",
"label": "Механическая"
},
{
"value": "robot",
"label": "Роботизированная"
}
]
},
Each entry contains `label` which is readable value and `value` which is actual fields contents stored on server.
If `dictionaryParent` is set in meta description of model field, only a fraction of dictionary entries will be shown, depending on value of field marked as parent.
In this case, `entries` is a hash where `key` is the value of parent field required to show dictionary items:
"CarModels": {
"entries": {
"vw": [
{
"value": "passat",
"label": "VW Passat"
},
{
"value": "touareg",
"label": "VW Touareg"
},
{
"value": "tig",
"label": "VW Tiguan"
},
{
"value": "jetta",
"label": "VW Jetta"
}
],
"chevy": [
{
"value": "aveo",
"label": "Chevrolet Aveo"
},
{
"value": "blazer",
"label": "Chevrolet Blazer"
},
{
"value": "cruze",
"label": "Chevrolet Cruze"
},
{
"value": "epica",
"label": "Chevrolet Epica"
},
{
"value": "lacetti",
"label": "Chevrolet Lacetti"
}
]
}
}
Labels and values must not overlap in different categories.
If no value specified, then label is used instead.
Our Typeahead allows for dictionary record to be passed as `data-source` attribute:
data-source="global.dictionaries['{{meta.dictionaryName}}']"
data-bind="value: {{ name }},
valueUpdate: 'afterkeydown'
{{# meta.dictionaryParent }},
attr: { 'data-parent': {{ meta.dictionaryParent }} }
{{/ meta.dictionaryParent }}"
data-provide="typeahead"
If `data-parent` attribute is set (which is the case when `dictionaryParent` is specified in field meta), then respective entry of dictionary is used for list of typeahead items.
Typeahead is recreated on every focus if parent value is changed.
Currently `transparent-mode` is `true` due to lack of ways to set field permissions on group fields.
Sample user db is included under `resources/private/users.json`.
Available accounts:
- admin @ <empty password> (roles “front”, “back”, “parguy”, “head”);
- frontuser @ <empty password> (role “front”)
- backuser @ <empty password> (role “back”)
- parguyuser @ <empty password> (role “parguy”)
- headuser @ <empty password> (role “head”)
User management is available via snap-auth-cli.
- [X] techType — dictionary
- [ ] techContractor — references
- [X] towerType & towType — dictionaries
- [ ] towDealer & towContractor — references
With proper field index annotations for redson search API.
- [ ] templates;
- [ ] models;
Some settings need to be served to client code (to use in JS):
- serverSyncThrottle;
- serverSyncDelay;
- timelineUpdateInterval;