.
This commit is contained in:
@@ -33,8 +33,33 @@ function _close_shift_modal_targets(){
|
|||||||
// Constraint type schemas: name -> fields metadata
|
// Constraint type schemas: name -> fields metadata
|
||||||
const SCHEMAS = {
|
const SCHEMAS = {
|
||||||
"night": {label: "Night constraint", fields: [ {name: "options", label: "Options (free JSON)", type: "json"} ]},
|
"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"} ]},
|
// PreShiftConstraint fields from rota_generator/shifts.py:
|
||||||
"post": {label: "Post-shift", fields: [ {name: "days", label: "Days (comma-separated)", type: "list"}, {name: "ignore_shifts", label: "Ignore shifts (comma-separated)", type: "list"} ]},
|
// 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"} ]},
|
"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"} ]},
|
"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"} ]},
|
"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);
|
fieldWrap.appendChild(label);
|
||||||
const control = document.createElement('div'); control.className='control';
|
const control = document.createElement('div'); control.className='control';
|
||||||
let input;
|
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';
|
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]:'');
|
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;
|
input.oninput = syncToData;
|
||||||
} else if(f.type==='json'){
|
} else if(f.type==='json'){
|
||||||
input = document.createElement('textarea'); input.className='textarea'; input.rows=3;
|
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]:'');
|
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); }
|
try{ input.value = JSON.stringify(cur); }catch(e){ input.value = String(cur); }
|
||||||
input.oninput = syncToData;
|
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 {
|
} else {
|
||||||
input = document.createElement('input'); input.className='input'; input.type='text'; input.oninput = syncToData;
|
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);
|
v = v===''?null:parseFloat(v);
|
||||||
} else if(f.type==='list'){
|
} else if(f.type==='list'){
|
||||||
v = v===''?[]:v.split(',').map(x=>x.trim()).filter(Boolean);
|
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'){
|
} else if(f.type==='json'){
|
||||||
try{ v = v===''?{}:JSON.parse(v); }catch(e){ v = input.value; }
|
try{ v = v===''?{}:JSON.parse(v); }catch(e){ v = input.value; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user