mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
Home WIP: Get notes working
This commit is contained in:
parent
514d4cf207
commit
dc5d31eb02
@ -110,10 +110,10 @@ class home_note_portlet extends home_portlet
|
||||
if(!$content['note'])
|
||||
{
|
||||
$content['note'] = '';
|
||||
Api\Json\Response::get()->apply('app.home.note_edit',array($id));
|
||||
$content['edit_settings'] = true;
|
||||
}
|
||||
|
||||
$etemplate->exec('home.home_note_portlet.exec',$content,array(),array('__ALL__'=>true),array('id' =>$id));
|
||||
//$etemplate->exec('home.home_note_portlet.exec',$content,array(),array('__ALL__'=>true),array('id' =>$id));
|
||||
}
|
||||
|
||||
public function get_actions()
|
||||
@ -168,9 +168,14 @@ class home_note_portlet extends home_portlet
|
||||
public function get_description()
|
||||
{
|
||||
return array(
|
||||
'displayName'=> lang('Note'),
|
||||
'title'=> $this->context['title'],
|
||||
'description'=> lang('A quick note')
|
||||
'displayName' => lang('Note'),
|
||||
'title' => $this->context['title'],
|
||||
'description' => lang('A quick note')
|
||||
);
|
||||
}
|
||||
|
||||
public function get_type()
|
||||
{
|
||||
return 'et2-portlet-note';
|
||||
}
|
||||
}
|
58
home/js/Et2PortletNote.ts
Normal file
58
home/js/Et2PortletNote.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import shoelace from "../../api/js/etemplate/Styles/shoelace";
|
||||
import {css, html, TemplateResult, unsafeHTML} from "@lion/core";
|
||||
import {Et2Portlet} from "../../api/js/etemplate/Et2Portlet/Et2Portlet";
|
||||
|
||||
/**
|
||||
* Home portlet to show a note
|
||||
*/
|
||||
export class Et2PortletNote extends Et2Portlet
|
||||
{
|
||||
static get styles()
|
||||
{
|
||||
return [
|
||||
...shoelace,
|
||||
...(super.styles || []),
|
||||
css`
|
||||
.delete_button {
|
||||
padding-right: 10px;
|
||||
}
|
||||
`
|
||||
]
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
||||
this.edit = this.edit.bind(this);
|
||||
}
|
||||
|
||||
public edit()
|
||||
{
|
||||
// CKEditor is impossible to use below a certain size
|
||||
// Add 35px for the toolbar, 35px for the buttons
|
||||
let window_width = Math.max(580, parseInt(getComputedStyle(this).width) + 20);
|
||||
let window_height = Math.max(350, parseInt(getComputedStyle(this).height) + 70);
|
||||
|
||||
// Open popup, but add 70 to the height for the toolbar
|
||||
this.egw().open_link(this.egw().link('/index.php', {
|
||||
menuaction: 'home.home_note_portlet.edit',
|
||||
id: this.id,
|
||||
height: window_height - 70
|
||||
}), 'home_' + this.id, window_width + 'x' + window_height, 'home');
|
||||
}
|
||||
|
||||
bodyTemplate() : TemplateResult
|
||||
{
|
||||
return html`
|
||||
<div @dblclick=${this.edit}>
|
||||
${unsafeHTML(this.settings?.note || "")}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
if(!customElements.get("et2-portlet-note"))
|
||||
{
|
||||
customElements.define("et2-portlet-note", Et2PortletNote);
|
||||
}
|
221
home/js/app.ts
221
home/js/app.ts
@ -15,6 +15,7 @@ import {Et2Portlet} from "../../api/js/etemplate/Et2Portlet/Et2Portlet";
|
||||
import {Et2PortletFavorite} from "./Et2PortletFavorite";
|
||||
import {loadWebComponent} from "../../api/js/etemplate/Et2Widget/Et2Widget";
|
||||
import "./Et2PortletList";
|
||||
import "./Et2PortletNote";
|
||||
import Sortable from "sortablejs/modular/sortable.complete.esm.js";
|
||||
|
||||
/**
|
||||
@ -133,18 +134,8 @@ export class HomeApp extends EgwApp
|
||||
app.home.add_from_drop(action, [{data: ui.helper.context.dataset}])
|
||||
}
|
||||
});
|
||||
// Bind to unload to remove it from our list
|
||||
/*
|
||||
.on('clear', '.et2_container[id]', jQuery.proxy(function(e)
|
||||
{
|
||||
if(e.target && e.target.id && this.portlets[e.target.id])
|
||||
{
|
||||
this.portlets[e.target.id].destroy();
|
||||
delete this.portlets[e.target.id];
|
||||
}
|
||||
}, this));
|
||||
|
||||
*/
|
||||
this._do_ordering()
|
||||
}
|
||||
else if(et2.uniqueId)
|
||||
{
|
||||
@ -516,183 +507,13 @@ export class HomeApp extends EgwApp
|
||||
{
|
||||
list.link_change(link_id, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions for the note portlet
|
||||
*/
|
||||
/**
|
||||
* Set up for editing a note
|
||||
* CKEditor has CSP issues, so we need a popup
|
||||
*
|
||||
* @param {egwAction} action
|
||||
* @param {egwActionObject[]} Selected
|
||||
*/
|
||||
note_edit(action, selected)
|
||||
{
|
||||
if(!selected && typeof action == 'string')
|
||||
{
|
||||
let id = action;
|
||||
}
|
||||
else
|
||||
{
|
||||
let id = selected[0].id;
|
||||
}
|
||||
|
||||
// Aim to match the size
|
||||
let portlet_dom = jQuery('[id$=' + id + '][data-sizex]', this.portlet_container.getDOMNode());
|
||||
let width = portlet_dom.attr('data-sizex') * this.GRID;
|
||||
let height = portlet_dom.attr('data-sizey') * this.GRID;
|
||||
|
||||
// CKEditor is impossible to use below a certain size
|
||||
// Add 35px for the toolbar, 35px for the buttons
|
||||
let window_width = Math.max(580, width + 20);
|
||||
let window_height = Math.max(350, height + 70);
|
||||
|
||||
// Open popup, but add 70 to the height for the toolbar
|
||||
this.egw.open_link(this.egw.link('/index.php', {
|
||||
menuaction: 'home.home_note_portlet.edit',
|
||||
id: id,
|
||||
height: window_height - 70
|
||||
}), 'home_' + id, window_width + 'x' + window_height, 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Favorites / nextmatch
|
||||
*/
|
||||
/**
|
||||
* Toggle the nextmatch header shown / hidden
|
||||
*
|
||||
* @param {Event} event
|
||||
* @param {et2_button} widget
|
||||
*/
|
||||
nextmatch_toggle_header(event, widget)
|
||||
{
|
||||
widget.set_class(widget.class == 'opened' ? 'closed' : 'opened');
|
||||
// We operate on the DOM here, nm should be unaware of our fiddling
|
||||
let nm = widget.getParent().getWidgetById('nm');
|
||||
if(!nm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide header
|
||||
nm.div.toggleClass('header_hidden');
|
||||
nm.set_hide_header(nm.div.hasClass('header_hidden'));
|
||||
nm.resize();
|
||||
}
|
||||
}
|
||||
|
||||
app.classes.home = HomeApp;
|
||||
|
||||
/// Base class code
|
||||
|
||||
/**
|
||||
* Base class for portlet specific javascript
|
||||
*
|
||||
* Should this maybe extend et2_portlet? It would complicate instantiation.
|
||||
*
|
||||
* @type @exp;Class@call;extend
|
||||
*/
|
||||
export class HomePortlet
|
||||
{
|
||||
protected portlet = null;
|
||||
|
||||
init(portlet)
|
||||
{
|
||||
this.portlet = portlet;
|
||||
}
|
||||
|
||||
destroy()
|
||||
{
|
||||
this.portlet = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle framework refresh messages to determine if the portlet needs to
|
||||
* refresh too.
|
||||
*
|
||||
* App is responsible for only reacting to "messages" it is interested in!
|
||||
*
|
||||
*/
|
||||
observer(_msg, _app, _id, _type, _msg_type, _targetapp)
|
||||
{
|
||||
// Not interested
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
app.classes.home.home_link_portlet = app.classes.home.home_portlet.extend({
|
||||
init: function(portlet) {
|
||||
// call parent
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// Check for tooltip
|
||||
if(this.portlet)
|
||||
{
|
||||
let content = jQuery('.tooltip', this.portlet.content);
|
||||
if(content.length && content.children().length)
|
||||
{
|
||||
//Check if the tooltip is already initialized
|
||||
this.portlet.content.tooltip({
|
||||
items: this.portlet.content,
|
||||
content: content.html(),
|
||||
tooltipClass: 'portlet_' + this.portlet.id,
|
||||
show: {effect: 'slideDown', delay:500},
|
||||
hide: {effect: 'slideUp', delay: 500},
|
||||
position: {my: "left top", at:"left bottom", collision: "flipfit"},
|
||||
open: jQuery.proxy(function(event, ui) {
|
||||
// Calendar specific formatting
|
||||
if(ui.tooltip.has('.calendar_calEventTooltip').length)
|
||||
{
|
||||
ui.tooltip.removeClass("ui-tooltip");
|
||||
ui.tooltip.addClass("calendar_uitooltip");
|
||||
}
|
||||
},this),
|
||||
close: function(event,ui) {
|
||||
ui.tooltip.hover(
|
||||
function() {
|
||||
jQuery(this).stop(true).fadeTo(100,1);
|
||||
},
|
||||
function() {
|
||||
jQuery(this).slideUp("400",function() {jQuery(this).remove();});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
observer: function(_msg, _app, _id, _type)
|
||||
{
|
||||
if(this.portlet && this.portlet.settings)
|
||||
{
|
||||
let value = this.portlet.settings.entry || {};
|
||||
if(value.app && value.app == _app && value.id && value.id == _id)
|
||||
{
|
||||
// We don't just get the updated title, in case there's a custom
|
||||
// template with more fields
|
||||
app.home.refresh(this.portlet.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
app.classes.home.home_list_portlet = app.classes.home.home_portlet.extend({
|
||||
observer: function(_msg, _app, _id, _type)
|
||||
{
|
||||
if(this.portlet && this.portlet.getWidgetById('list'))
|
||||
{
|
||||
let list = this.portlet.getWidgetById('list').options.value;
|
||||
for(let i = 0; i < list.length; i++)
|
||||
{
|
||||
if(list[i].app == _app && list[i].id == _id)
|
||||
{
|
||||
app.home.refresh(this.portlet.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
app.classes.home.home_weather_portlet = app.classes.home.home_portlet.extend({
|
||||
init: function(portlet) {
|
||||
// call parent
|
||||
@ -712,42 +533,4 @@ app.classes.home.home_weather_portlet = app.classes.home.home_portlet.extend({
|
||||
}
|
||||
}
|
||||
});
|
||||
app.classes.home.home_favorite_portlet = app.classes.home.home_portlet.extend({
|
||||
init: function(portlet) {
|
||||
// call parent
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// Somehow favorite got lost, or is not set
|
||||
if(portlet.options && portlet.options.settings && typeof portlet.options.settings !== 'undefined' &&
|
||||
!portlet.options.settings.favorite
|
||||
)
|
||||
{
|
||||
portlet.edit_settings();
|
||||
}
|
||||
},
|
||||
observer: function(_msg, _app, _id, _type, _msg_type, _targetapp)
|
||||
{
|
||||
if(this.portlet.class.indexOf(_app) == 0 || this.portlet.class == 'home_favorite_portlet')
|
||||
{
|
||||
this.portlet.getWidgetById('nm').refresh(_id,_type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* An example illustrating extending the base code for a application specific code.
|
||||
* See also the calendar app, which needs custom handlers
|
||||
*
|
||||
* @type @exp;app@pro;classes@pro;home@pro;home_favorite_portlet@call;extend
|
||||
* Note we put it in home, but this code should go in addressbook/js/addressbook_favorite_portlet.js
|
||||
*
|
||||
app.classes.home.addressbook_favorite_portlet = app.classes.home.home_favorite_portlet.extend({
|
||||
|
||||
observer: function(_msg, _app, _id, _type, _msg_type, _targetapp)
|
||||
{
|
||||
// Just checking...
|
||||
debugger;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
@ -2,13 +2,24 @@
|
||||
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
|
||||
<overlay>
|
||||
<template id="home.note" template="" lang="" group="0" version="1.9.001">
|
||||
<et2-vbox>
|
||||
<htmlarea id="note"/>
|
||||
<et2-hbox id="button" class="dialogFooterToolbar">
|
||||
<et2-button statustext="Saves this entry" label="Save" id="save" image="save"></et2-button>
|
||||
<et2-button statustext="Apply the changes" label="Apply" id="apply" image="apply"></et2-button>
|
||||
<et2-button statustext="leave without saveing the entry" label="Cancel" id="cancel" onclick="window.close();" image="cancel"></et2-button>
|
||||
<et2-button statustext="leave without saveing the entry" label="Cancel" id="cancel"
|
||||
onclick="window.close();" image="cancel"></et2-button>
|
||||
</et2-hbox>
|
||||
</et2-vbox>
|
||||
<styles>
|
||||
#home-note et2-vbox {
|
||||
height: 100%;
|
||||
}
|
||||
#home-note et2-vbox > div {
|
||||
flex: 1 1 auto;
|
||||
width: initial;
|
||||
height: initial;
|
||||
}
|
||||
.home_note_portlet .et2_container > div {
|
||||
overflow: auto;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user