feat(DurationControl): Parse duration string input
This commit is contained in:
parent
c06a854ea8
commit
4dbcc12470
1 changed files with 56 additions and 2 deletions
|
|
@ -60,7 +60,7 @@ frappe.ui.form.ControlDuration = class ControlDuration extends frappe.ui.form.Co
|
|||
}
|
||||
|
||||
set_duration_picker_value(value) {
|
||||
let total_duration = frappe.utils.seconds_to_duration(value, this.duration_options);
|
||||
let total_duration = frappe.utils.seconds_to_duration(value || 0, this.duration_options);
|
||||
|
||||
if (this.$picker) {
|
||||
Object.keys(total_duration).forEach((duration) => {
|
||||
|
|
@ -108,6 +108,7 @@ frappe.ui.form.ControlDuration = class ControlDuration extends frappe.ui.form.Co
|
|||
// blur event was not due to duration inputs
|
||||
this.$picker.hide();
|
||||
}
|
||||
this.set_formatted_input(this.value);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +117,29 @@ frappe.ui.form.ControlDuration = class ControlDuration extends frappe.ui.form.Co
|
|||
}
|
||||
|
||||
parse(value) {
|
||||
return !value ? "" : value;
|
||||
if (!value) {
|
||||
return "";
|
||||
} else if (/^\s*\d+\s*$/.test(value)) {
|
||||
return parseInt(value);
|
||||
}
|
||||
|
||||
this.DURATION_PARSE_REGEX ??= makeDurationParseRegex();
|
||||
const match = String(value).trim().match(this.DURATION_PARSE_REGEX);
|
||||
|
||||
if (!match?.groups || !Object.values(match.groups).some((g) => !!g)) {
|
||||
return null; // At least one group is required
|
||||
}
|
||||
|
||||
let duration_in_seconds = 0;
|
||||
for (const [key, multiplier] of Object.entries(DURATION_MULTIPLIERS)) {
|
||||
duration_in_seconds += parseInt(match.groups?.[key] || 0) * multiplier;
|
||||
}
|
||||
return duration_in_seconds;
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
super.set_formatted_input(value);
|
||||
this.set_duration_picker_value(value);
|
||||
}
|
||||
|
||||
refresh_input() {
|
||||
|
|
@ -160,3 +183,34 @@ frappe.ui.form.ControlDuration = class ControlDuration extends frappe.ui.form.Co
|
|||
return is_set;
|
||||
}
|
||||
};
|
||||
|
||||
const DURATION_MULTIPLIERS = {
|
||||
weeks: 7 * 24 * 60 * 60,
|
||||
days: 24 * 60 * 60,
|
||||
hours: 60 * 60,
|
||||
minutes: 60,
|
||||
seconds: 1,
|
||||
};
|
||||
|
||||
function makeDurationParseRegex() {
|
||||
// Wrap in a function for translations to work
|
||||
// Matches strings like: 1d 2h 3m 4s, with optional parts
|
||||
|
||||
const _part = (key, seps) => {
|
||||
// Use named capture group for the key, then match the separator (h, m, s)
|
||||
const rCapture = `(?<${key}>\\d+)`;
|
||||
const rSep = "(?:" + seps.join("|") + ")";
|
||||
return "\\s*(?:" + rCapture + "\\s*" + rSep + ")?\\s*";
|
||||
};
|
||||
|
||||
return new RegExp(
|
||||
[
|
||||
_part("days", [__("d", null, "Days (Field: Duration)")]),
|
||||
_part("hours", [__("h", null, "Hours (Field: Duration)")]),
|
||||
_part("minutes", [__("m", null, "Minutes (Field: Duration)")]),
|
||||
_part("seconds", [__("s", null, "Seconds (Field: Duration)")]),
|
||||
".*", // Fallback to ignore unknown parts
|
||||
].join(""),
|
||||
"i"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue