.
This commit is contained in:
@@ -33,8 +33,33 @@ function _close_shift_modal_targets(){
|
||||
// Constraint type schemas: name -> fields metadata
|
||||
const SCHEMAS = {
|
||||
"night": {label: "Night constraint", fields: [ {name: "options", label: "Options (free JSON)", type: "json"} ]},
|
||||
"pre": {label: "Pre-shift", fields: [ {name: "days", label: "Days (comma-separated)", type: "list"}, {name: "ignore_shifts", label: "Ignore shifts (comma-separated)", type: "list"} ]},
|
||||
"post": {label: "Post-shift", fields: [ {name: "days", label: "Days (comma-separated)", type: "list"}, {name: "ignore_shifts", label: "Ignore shifts (comma-separated)", type: "list"} ]},
|
||||
// PreShiftConstraint fields from rota_generator/shifts.py:
|
||||
// weeks: Optional[List[int]]
|
||||
// start_date: Optional[date]
|
||||
// end_date: Optional[date]
|
||||
// days: Optional[int]
|
||||
// ignore_shifts: List[str]
|
||||
// exclude_days: List[str]
|
||||
// allow_self: bool
|
||||
"pre": {label: "Pre-shift", fields: [
|
||||
{name: "weeks", label: "Weeks (comma-separated integers)", type: "list_int"},
|
||||
{name: "start_date", label: "Start date", type: "date"},
|
||||
{name: "end_date", label: "End date", type: "date"},
|
||||
{name: "days", label: "Days (integer)", type: "int"},
|
||||
{name: "ignore_shifts", label: "Ignore shifts (comma-separated)", type: "list"},
|
||||
{name: "exclude_days", label: "Exclude days (comma-separated)", type: "list"},
|
||||
{name: "allow_self", label: "Allow self", type: "bool"}
|
||||
]},
|
||||
// PostShiftConstraint same fields
|
||||
"post": {label: "Post-shift", fields: [
|
||||
{name: "weeks", label: "Weeks (comma-separated integers)", type: "list_int"},
|
||||
{name: "start_date", label: "Start date", type: "date"},
|
||||
{name: "end_date", label: "End date", type: "date"},
|
||||
{name: "days", label: "Days (integer)", type: "int"},
|
||||
{name: "ignore_shifts", label: "Ignore shifts (comma-separated)", type: "list"},
|
||||
{name: "exclude_days", label: "Exclude days (comma-separated)", type: "list"},
|
||||
{name: "allow_self", label: "Allow self", type: "bool"}
|
||||
]},
|
||||
"min_summed_grade_by_shifts_per_day": {label: "Min summed grade by shifts per day", fields: [ {name: "shifts", label: "Shifts (comma-separated)", type: "list"}, {name: "min_grade_sum", label: "Minimum grade sum", type: "int"}, {name: "days", label: "Days (comma-separated)", type: "list"} ]},
|
||||
"limit_grade_number": {label: "Limit grade number", fields: [ {name: "grade", label: "Grade", type: "int"}, {name: "max_number", label: "Max number", type: "int"} ]},
|
||||
"minimum_grade_number": {label: "Minimum grade number", fields: [ {name: "grade", label: "Grade", type: "int"}, {name: "min_number", label: "Min number", type: "int"} ]},
|
||||
@@ -105,16 +130,32 @@ function _close_shift_modal_targets(){
|
||||
fieldWrap.appendChild(label);
|
||||
const control = document.createElement('div'); control.className='control';
|
||||
let input;
|
||||
if(f.type==='text' || f.type==='int' || f.type==='float' || f.type==='list'){
|
||||
if(f.type==='text' || f.type==='int' || f.type==='float' || f.type==='list' || f.type==='list_int'){
|
||||
input = document.createElement('input'); input.className='input'; input.type='text';
|
||||
const cur = (c.options && c.options[f.name]!==undefined) ? c.options[f.name] : (c[f.name]!==undefined?c[f.name]:'');
|
||||
if(Array.isArray(cur) && f.type==='list') input.value = cur.join(','); else input.value = cur===null? '': String(cur);
|
||||
if(Array.isArray(cur) && (f.type==='list' || f.type==='list_int')) input.value = cur.join(','); else input.value = cur===null? '': String(cur);
|
||||
input.oninput = syncToData;
|
||||
} else if(f.type==='json'){
|
||||
input = document.createElement('textarea'); input.className='textarea'; input.rows=3;
|
||||
const cur = (c.options && c.options[f.name]!==undefined) ? c.options[f.name] : (c[f.name]!==undefined?c[f.name]:'');
|
||||
try{ input.value = JSON.stringify(cur); }catch(e){ input.value = String(cur); }
|
||||
input.oninput = syncToData;
|
||||
} else if(f.type==='bool'){
|
||||
// checkbox for boolean
|
||||
const cb = document.createElement('input'); cb.type='checkbox'; cb.className='checkbox';
|
||||
const curb = (c.options && c.options[f.name]!==undefined) ? c.options[f.name] : (c[f.name]!==undefined?c[f.name]:false);
|
||||
cb.checked = !!curb;
|
||||
cb.setAttribute('data-field-name', f.name);
|
||||
cb.onchange = syncToData;
|
||||
control.appendChild(cb);
|
||||
fieldWrap.appendChild(control);
|
||||
fieldsContainer.appendChild(fieldWrap);
|
||||
return; // already appended
|
||||
} else if(f.type==='date'){
|
||||
input = document.createElement('input'); input.className='input'; input.type='date';
|
||||
const curd = (c.options && c.options[f.name]!==undefined) ? c.options[f.name] : (c[f.name]!==undefined?c[f.name]:'');
|
||||
input.value = curd ? String(curd) : '';
|
||||
input.oninput = syncToData;
|
||||
} else {
|
||||
input = document.createElement('input'); input.className='input'; input.type='text'; input.oninput = syncToData;
|
||||
}
|
||||
@@ -141,6 +182,12 @@ function _close_shift_modal_targets(){
|
||||
v = v===''?null:parseFloat(v);
|
||||
} else if(f.type==='list'){
|
||||
v = v===''?[]:v.split(',').map(x=>x.trim()).filter(Boolean);
|
||||
} else if(f.type==='list_int'){
|
||||
v = v===''?[]:v.split(',').map(x=>parseInt(x.trim(),10)).filter(n=>!Number.isNaN(n));
|
||||
} else if(f.type==='bool'){
|
||||
const cb = fieldsContainer.querySelector('[data-field-name="'+f.name+'"]'); if(cb) v = !!cb.checked; else v = !!v;
|
||||
} else if(f.type==='date'){
|
||||
v = v===''?null:v; // keep as ISO date string
|
||||
} else if(f.type==='json'){
|
||||
try{ v = v===''?{}:JSON.parse(v); }catch(e){ v = input.value; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user