Initial commit: Technical packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:51 +02:00
commit 3473fa71a0
873 changed files with 297766 additions and 0 deletions

View file

@ -0,0 +1,26 @@
/** @odoo-module **/
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model';
import '@mail/components/activity_menu_view/activity_menu_view'; // ensure components are registered beforehand.
import { getMessagingComponent } from "@mail/utils/messaging_component";
import { DatePicker } from '@web/core/datepicker/datepicker';
import { patch } from 'web.utils';
const ActivityMenuView = getMessagingComponent('ActivityMenuView');
patch(ActivityMenuView.prototype, 'note', {
/**
* @override
*/
setup() {
this._super();
useRefToModel({ fieldName: 'noteInputRef', refName: 'noteInput', });
useUpdateToModel({ methodName: 'onComponentUpdate' });
},
});
Object.assign(ActivityMenuView.components, {
DatePicker,
});

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="mail.ActivityMenuView" t-inherit-mode="extension">
<xpath expr="//*[@name='activityGroupLoop']" position="after">
<div t-if="!activityMenuView.isAddingNote" class="o_note_show d-grid" t-on-click="activityMenuView.onClickAddNote">
<a role="button" class="btn text-center">Add new note</a>
</div>
<div t-if="activityMenuView.isAddingNote" class="o_note o_ActivityMenuView_activityGroup">
<div class="o_ActivityMenuView_activityGroupIconContainer">
<img src="/note/static/description/icon.svg" alt="Channel"/>
</div>
<div class="o_ActivityMenuView_activityGroupInfo">
<div class="o_ActivityMenuView_activityGroupTitle">
<span class="o_ActivityMenuView_activityGroupName"><strong>Add a note</strong></span>
<DatePicker
date="activityMenuView.addingNoteDate"
onDateTimeChanged="activityMenuView.onDateTimeChanged"
placeholder="activityMenuView.addingNoteDatePlaceholder"
/>
</div>
<div class="o_note_input_box">
<p><input class="o_note_input bg-transparent" type="text" placeholder="Remember..." t-on-keydown="activityMenuView.onKeydownNoteInput" t-ref="noteInput"/></p>
<span class="ml8 mr4">
<a class="o_note_save" t-on-click="activityMenuView.onClickSaveNote">SAVE</a>
</span>
</div>
</div>
</div>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,15 @@
/** @odoo-module **/
import { registerPatch } from '@mail/model/model_core';
import { attr } from '@mail/model/model_field';
registerPatch({
name: 'ActivityGroup',
fields: {
isNote: attr({
compute() {
return this.irModel.model === 'note.note';
},
}),
},
});

View file

@ -0,0 +1,106 @@
/** @odoo-module **/
import { registerPatch } from '@mail/model/model_core';
import { attr } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
const { DateTime } = luxon;
const urlRegExp = /http(s)?:\/\/(www\.)?[a-zA-Z0-9@:%_+~#=~#?&/=\-;!.]{3,2000}/g;
registerPatch({
name: 'ActivityMenuView',
recordMethods: {
/**
* @override
*/
close() {
this.update({
addingNoteDoFocus: clear(),
isAddingNote: false,
});
this._super();
},
/**
* @param {MouseEvent} ev
*/
onClickAddNote(ev) {
this.update({
addingNoteDoFocus: true,
isAddingNote: true,
});
},
/**
* @param {MouseEvent} ev
*/
onClickSaveNote(ev) {
this.saveNote();
},
onComponentUpdate() {
if (this.addingNoteDoFocus && this.noteInputRef.el) {
this.noteInputRef.el.focus();
this.update({ addingNoteDoFocus: clear() });
}
},
/**
* @param {DateTime|string} date
*/
onDateTimeChanged(date) {
this.update({ addingNoteDate: date ? date : clear() });
},
/**
* @param {KeyboardEvent} ev
*/
onKeydownNoteInput(ev) {
if (ev.key === 'Enter') {
this.saveNote();
}
},
async saveNote() {
const note = this.noteInputRef.el.value.replace(urlRegExp, '<a href="$&">$&</a>').trim();
if (!note) {
return;
}
this.update({ isAddingNote: false });
await this.messaging.rpc({
route: '/note/new',
params: {
'note': note,
'date_deadline': this.addingNoteDate ? this.addingNoteDate : new DateTime.local(),
},
});
this.fetchData();
},
/**
* @override
*/
_onClickCaptureGlobal(ev) {
if (ev.target.closest('.bootstrap-datetimepicker-widget')) {
return;
}
this._super(ev);
},
},
fields: {
activityGroups: {
sort() {
return [
['truthy-first', 'isNote'],
...this._super,
];
},
},
addingNoteDate: attr(),
addingNoteDatePlaceholder: attr({
compute() {
return this.env._t("Today");
},
}),
addingNoteDoFocus: attr({
default: false,
}),
isAddingNote: attr({
default: false,
}),
noteInputRef: attr(),
},
});

View file

@ -0,0 +1,78 @@
.o_kanban_group .note_text_line_through {
text-decoration: line-through;
}
.o_note_form_view {
.o_form_sheet_bg {
display: flex;
flex-direction: column;
padding: 0;
.o_form_statusbar {
margin: 0;
}
.o_form_sheet {
margin: 0;
border: none;
flex: 1;
box-shadow: none;
padding: 0;
max-width: 100%;
.oe_pad {
flex: 1;
margin-bottom: 0;
display: flex;
flex-direction: column;
.oe_pad_content {
border: none;
flex: 1;
}
}
}
.note-editable {
border: none;
padding: $o-sheet-vpadding $o-horizontal-padding 10px !important;
min-height: 300px;
}
}
.o_field_widget[name="memo"] {
padding: 0;
margin: 0;
min-height: 200px;
height: 100%
}
&.o_form_readonly {
.oe_memo {
padding: $o-sheet-vpadding $o-horizontal-padding;
}
}
.oe_memo {
overflow-x: hidden;
}
}
// Quick create notes from systray
.o_note.o_ActivityMenuView_activityGroup {
.o_ActivityMenuView_activityGroupInfo {
.o_ActivityMenuView_activityGroupTitle {
.o_ActivityMenuView_activityGroupName {
flex: 1 1 100%;
}
}
.o_note_input_box {
display: flex;
p {
flex: 1 1 auto;
margin-bottom: 0px;
}
}
.o_note_save {
font-size: 11px;
font-weight: bold;
}
}
.o_note_input {
border: none;
}
}