mirror of
https://github.com/bringout/oca-ocb-vertical-industry.git
synced 2026-04-21 23:52:02 +02:00
19.0 vanilla
This commit is contained in:
parent
4607ccbd2e
commit
825ff6514e
487 changed files with 184979 additions and 195262 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 2.6 KiB |
|
|
@ -1 +1 @@
|
|||
<svg width="70" height="70" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>maintenance/static/description/icon</title><defs><path d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z" id="a"/><linearGradient x1="100%" y1="0%" x2="0%" y2="98.616%" id="c"><stop stop-color="#797C79" offset="0%"/><stop stop-color="#545554" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z" fill="#FFF" fill-opacity=".383"/><path d="M42.863 70H4c-2 0-4-.149-4-4.17V42.7L22 21l35 33.362L42.863 70z" fill="#393939" opacity=".324"/><path d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z" fill="#000" fill-opacity=".383"/><path d="M34.821 40.185l-9.488-9.488-3.163 3.163h-3.162c-1.487 1.054-3.02 2.372-4.602 3.953-1.02 1.53-1.81 2.88-2.372 4.05-.622-2.173-.173-4.424 1.346-6.755 1.116-1.36 2.465-3.093 4.046-5.202v-2.372l7.907-7.906c2.635.527 3.69-.528 3.163-3.163l3.162-3.163 6.326 5.535A38.251 38.251 0 0 1 34.82 22c-2.636-.528-3.953.527-3.953 3.162l-2.372 2.372 8.697 9.488 3.953-.79L56.96 52.045v3.163l-4.744 4.744h-3.163L34.03 44.138v-2.372l.791-1.58z" fill="#000" opacity=".3"/><path d="M34.821 38.185l-9.488-9.488-3.163 3.163h-3.162c-1.487 1.054-3.02 2.372-4.602 3.953-1.02 1.53-1.81 2.88-2.372 4.05-.622-2.173-.173-4.424 1.346-6.755 1.116-1.36 2.465-3.093 4.046-5.202v-2.372l7.907-7.906c2.635.527 3.69-.528 3.163-3.163l3.162-3.163 6.326 5.535A38.251 38.251 0 0 1 34.82 20c-2.636-.528-3.953.527-3.953 3.162l-2.372 2.372 8.697 9.488 3.953-.79L56.96 50.045v3.163l-4.744 4.744h-3.163L34.03 42.138v-2.372l.791-1.58z" fill="#FFF"/></g></g></svg>
|
||||
<svg width="50" height="50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><path d="M12.172 24.193s6.121-2.586 7.778-4.243c1.657-1.657 4.243-7.778 4.243-7.778l13.435 13.435s-6.099 2.563-7.779 4.242c-1.68 1.68-4.242 7.779-4.242 7.779L12.172 24.193Z" fill="#2EBCFA"/><path fill-rule="evenodd" clip-rule="evenodd" d="M42.577 22.778c4.296-4.296 4.296-11.26 0-15.556-4.296-4.296-11.26-4.296-15.556 0-4.296 4.296-4.296 11.26 0 15.556 4.295 4.296 11.26 4.296 15.556 0Zm-4.243-4.242a5 5 0 1 0-7.07-7.072 5 5 0 0 0 7.07 7.071ZM22.778 42.577c4.296-4.296 4.296-11.26 0-15.556-4.296-4.296-11.26-4.296-15.556 0-4.296 4.295-4.296 11.26 0 15.556 4.296 4.296 11.26 4.296 15.556 0Zm-4.242-4.243a5 5 0 1 0-7.071-7.07 5 5 0 0 0 7.07 7.07Z" fill="#088BF5"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 752 B |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,3 +1,3 @@
|
|||
.o_kanban_renderer.o_maintenance_team_kanban {
|
||||
.o_maintenance_team_kanban .o_kanban_renderer {
|
||||
--KanbanRecord-width: 420px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import { CalendarCommonPopover } from "@web/views/calendar/calendar_common/calendar_common_popover";
|
||||
|
||||
export class CalendarWithRecurrenceCommonPopover extends CalendarCommonPopover {
|
||||
onEditEvent() {
|
||||
this.props.record.id = this.props.record.rawRecord.id;
|
||||
super.onEditEvent();
|
||||
}
|
||||
onDeleteEvent() {
|
||||
this.props.record.id = this.props.record.rawRecord.id;
|
||||
super.onDeleteEvent();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { CalendarCommonRenderer } from "@web/views/calendar/calendar_common/calendar_common_renderer";
|
||||
import { CalendarWithRecurrenceCommonPopover } from "./calendar_with_recurrence_common_popover";
|
||||
|
||||
export class CalendarWithRecurrenceCommonRenderer extends CalendarCommonRenderer {
|
||||
static components = {
|
||||
...CalendarCommonRenderer.components,
|
||||
Popover: CalendarWithRecurrenceCommonPopover,
|
||||
};
|
||||
|
||||
onDblClick(info) {
|
||||
const record = this.props.model.records[info.event.id];
|
||||
this.props.editRecord({ ...record, id: record.rawRecord.id });
|
||||
}
|
||||
|
||||
fcEventToRecord(event) {
|
||||
const record = super.fcEventToRecord(event);
|
||||
if (record.id) {
|
||||
record.id = this.props.model.records[record.id].rawRecord.id;
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
convertRecordToEvent(record) {
|
||||
const event = super.convertRecordToEvent(record);
|
||||
// https://fullcalendar.io/docs/editable
|
||||
// this is used to disable the 'drag and drop' and 'resizing' for recurring events
|
||||
event.editable = !record.isRecurrent;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { deserializeDateTime, serializeDateTime } from "@web/core/l10n/dates";
|
||||
import { CalendarModel } from '@web/views/calendar/calendar_model';
|
||||
|
||||
export class CalendarWithRecurrenceModel extends CalendarModel {
|
||||
async loadRecords(data) {
|
||||
const rawRecords = await this.fetchRecords(data);
|
||||
const records = {};
|
||||
let recordsCounter = 1;
|
||||
for (const rawRecord of rawRecords) {
|
||||
records[recordsCounter] = {
|
||||
...this.normalizeRecord(rawRecord),
|
||||
id: recordsCounter,
|
||||
};
|
||||
recordsCounter++;
|
||||
if (rawRecord.recurring_maintenance && !rawRecord.done && !rawRecord.archive) {
|
||||
let { start, end } = data.range;
|
||||
if (rawRecord.repeat_type == 'until') {
|
||||
end = luxon.DateTime.min(end, deserializeDateTime(rawRecord.repeat_until)).endOf('day');
|
||||
}
|
||||
const duration = rawRecord.duration || 1;
|
||||
const [unit, interval] = [rawRecord.repeat_unit + "s", rawRecord.repeat_interval]
|
||||
let date = deserializeDateTime(rawRecord.schedule_date);
|
||||
date = this._getNextDate(date, unit, interval);
|
||||
let counter = 1;
|
||||
while (date <= end) {
|
||||
if (date > start) {
|
||||
const endDate = date.plus({ hours: duration });
|
||||
const rawRecordCopy = { ...rawRecord };
|
||||
rawRecordCopy.display_name = rawRecord.display_name + " (+" + counter + ")";
|
||||
rawRecordCopy.schedule_date = serializeDateTime(date);
|
||||
rawRecordCopy.schedule_end = serializeDateTime(endDate);
|
||||
records[recordsCounter] = {
|
||||
...this.normalizeRecord(rawRecordCopy),
|
||||
id: recordsCounter,
|
||||
isRecurrent: true,
|
||||
};
|
||||
recordsCounter++;
|
||||
}
|
||||
date = this._getNextDate(date, unit, interval);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return records;
|
||||
}
|
||||
_getNextDate(date, unit, interval) {
|
||||
return date.plus({ [unit]: interval });
|
||||
}
|
||||
computeRangeDomain(data) {
|
||||
// Override to fix recurrence: show records even if end is before next range start.
|
||||
const formattedEnd = serializeDateTime(data.range.end);
|
||||
const domain = [[this.meta.fieldMapping.date_start, "<=", formattedEnd]];
|
||||
return domain;
|
||||
}
|
||||
normalizeRecord(rawRecord) {
|
||||
// Override to set end = start + 1h if schedule_end is False.
|
||||
const record = super.normalizeRecord(rawRecord);
|
||||
const { duration, start, end } = record;
|
||||
if (!end.isValid && duration) {
|
||||
record.end = start.plus({ hours: duration });
|
||||
record.isTimeHidden = false;
|
||||
}
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { CalendarRenderer } from "@web/views/calendar/calendar_renderer";
|
||||
import { CalendarWithRecurrenceCommonRenderer } from './calendar_with_recurrence_common_renderer';
|
||||
import { CalendarWithRecurrenceYearRenderer } from './calendar_with_recurrence_year_renderer';
|
||||
|
||||
export class CalendarWithRecurrenceRenderer extends CalendarRenderer {
|
||||
static components = {
|
||||
...CalendarRenderer.components,
|
||||
day: CalendarWithRecurrenceCommonRenderer,
|
||||
week: CalendarWithRecurrenceCommonRenderer,
|
||||
month: CalendarWithRecurrenceCommonRenderer,
|
||||
year: CalendarWithRecurrenceYearRenderer,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { calendarView } from '@web/views/calendar/calendar_view';
|
||||
import { CalendarWithRecurrenceModel } from './calendar_with_recurrence_model';
|
||||
import { CalendarWithRecurrenceRenderer } from './calendar_with_recurrence_renderer';
|
||||
import { registry } from '@web/core/registry';
|
||||
|
||||
const CalendarWithRecurrenceView = {
|
||||
...calendarView,
|
||||
Model: CalendarWithRecurrenceModel,
|
||||
Renderer: CalendarWithRecurrenceRenderer,
|
||||
};
|
||||
|
||||
registry.category('views').add('calendar_with_recurrence', CalendarWithRecurrenceView);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { CalendarYearPopover } from "@web/views/calendar/calendar_year/calendar_year_popover";
|
||||
|
||||
export class CalendarWithRecurrenceYearPopover extends CalendarYearPopover {
|
||||
onRecordClick(record) {
|
||||
record.id = record.rawRecord.id;
|
||||
super.onRecordClick(record);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { CalendarWithRecurrenceYearPopover } from "./calendar_with_recurrence_year_popover";
|
||||
import { CalendarYearRenderer } from "@web/views/calendar/calendar_year/calendar_year_renderer";
|
||||
|
||||
export class CalendarWithRecurrenceYearRenderer extends CalendarYearRenderer {
|
||||
static components = {
|
||||
...CalendarYearRenderer.components,
|
||||
Popover: CalendarWithRecurrenceYearPopover,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import { registry } from "@web/core/registry";
|
||||
|
||||
registry.category("web_tour.tours").add("test_dblclick_event_from_calendar", {
|
||||
steps: () => [
|
||||
{
|
||||
content: "Enter event form",
|
||||
trigger: 'a[data-event-id="1"]',
|
||||
run: "dblclick",
|
||||
},
|
||||
{
|
||||
content: "Change the name of the form",
|
||||
trigger: "input#name_0",
|
||||
run: "edit make your bed",
|
||||
},
|
||||
{
|
||||
content: "Save name change",
|
||||
trigger: 'button[data-hotkey="s"]',
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Return to calendar",
|
||||
trigger: ".o_back_button",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Move to next week",
|
||||
trigger: ".o_calendar_button_next",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Access occurrence",
|
||||
trigger: 'a[data-event-id="2"]',
|
||||
run: "dblclick",
|
||||
},
|
||||
{
|
||||
content: "Change Scheduled End",
|
||||
trigger: "button#schedule_end_0",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: "input#schedule_end_0",
|
||||
async run({ edit, anchor }) {
|
||||
const value = luxon.DateTime.fromFormat(anchor.value, "MM/dd/yyyy hh:mm:ss a")
|
||||
.plus({ hours: 1 })
|
||||
.toFormat("MM/dd/yyyy hh:mm:ss a");
|
||||
await edit(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
content: "Return to calendar",
|
||||
trigger: ".o_back_button",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
trigger: 'a[data-event-id="2"]',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
registry.category("web_tour.tours").add("test_drag_and_drop_event_in_calendar", {
|
||||
steps: () => [
|
||||
{
|
||||
content: "Open calendar display selector",
|
||||
trigger: ".scale_button_selection",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Select monthly display",
|
||||
trigger: ".o_scale_button_month",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: 'Wait for monthly view to load',
|
||||
trigger: '.fc-dayGridMonth-view',
|
||||
},
|
||||
{
|
||||
content: "Move event to 15th of the month",
|
||||
trigger: 'a[data-event-id="1"]',
|
||||
run: 'drag_and_drop .fc-daygrid-day[data-date$="15"] .fc-daygrid-day-events',
|
||||
},
|
||||
{
|
||||
content: "Move occurrence to 20th of the month (nothing should happen)",
|
||||
trigger: 'a[data-event-id="2"]',
|
||||
run: 'drag_and_drop .fc-daygrid-day[data-date$="20"] .fc-daygrid-day-events',
|
||||
},
|
||||
],
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue