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'])
|
if(!$content['note'])
|
||||||
{
|
{
|
||||||
$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()
|
public function get_actions()
|
||||||
@ -160,7 +160,7 @@ class home_note_portlet extends home_portlet
|
|||||||
);
|
);
|
||||||
// Internal - no type means it won't show in configure dialog
|
// Internal - no type means it won't show in configure dialog
|
||||||
$properties[] = array(
|
$properties[] = array(
|
||||||
'name' => 'note'
|
'name' => 'note'
|
||||||
);
|
);
|
||||||
return $properties;
|
return $properties;
|
||||||
}
|
}
|
||||||
@ -168,9 +168,14 @@ class home_note_portlet extends home_portlet
|
|||||||
public function get_description()
|
public function get_description()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'displayName'=> lang('Note'),
|
'displayName' => lang('Note'),
|
||||||
'title'=> $this->context['title'],
|
'title' => $this->context['title'],
|
||||||
'description'=> lang('A quick note')
|
'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);
|
||||||
|
}
|
223
home/js/app.ts
223
home/js/app.ts
@ -15,6 +15,7 @@ import {Et2Portlet} from "../../api/js/etemplate/Et2Portlet/Et2Portlet";
|
|||||||
import {Et2PortletFavorite} from "./Et2PortletFavorite";
|
import {Et2PortletFavorite} from "./Et2PortletFavorite";
|
||||||
import {loadWebComponent} from "../../api/js/etemplate/Et2Widget/Et2Widget";
|
import {loadWebComponent} from "../../api/js/etemplate/Et2Widget/Et2Widget";
|
||||||
import "./Et2PortletList";
|
import "./Et2PortletList";
|
||||||
|
import "./Et2PortletNote";
|
||||||
import Sortable from "sortablejs/modular/sortable.complete.esm.js";
|
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}])
|
app.home.add_from_drop(action, [{data: ui.helper.context.dataset}])
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Bind to unload to remove it from our list
|
|
||||||
/*
|
this._do_ordering()
|
||||||
.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));
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else if(et2.uniqueId)
|
else if(et2.uniqueId)
|
||||||
{
|
{
|
||||||
@ -516,183 +507,13 @@ export class HomeApp extends EgwApp
|
|||||||
{
|
{
|
||||||
list.link_change(link_id, row);
|
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;
|
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({
|
app.classes.home.home_weather_portlet = app.classes.home.home_portlet.extend({
|
||||||
init: function(portlet) {
|
init: function(portlet) {
|
||||||
// call parent
|
// 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,19 +2,30 @@
|
|||||||
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
|
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
|
||||||
<overlay>
|
<overlay>
|
||||||
<template id="home.note" template="" lang="" group="0" version="1.9.001">
|
<template id="home.note" template="" lang="" group="0" version="1.9.001">
|
||||||
<htmlarea id="note"/>
|
<et2-vbox>
|
||||||
<et2-hbox id="button" class="dialogFooterToolbar">
|
<htmlarea id="note"/>
|
||||||
<et2-button statustext="Saves this entry" label="Save" id="save" image="save"></et2-button>
|
<et2-hbox id="button" class="dialogFooterToolbar">
|
||||||
<et2-button statustext="Apply the changes" label="Apply" id="apply" image="apply"></et2-button>
|
<et2-button statustext="Saves this entry" label="Save" id="save" image="save"></et2-button>
|
||||||
<et2-button statustext="leave without saveing the entry" label="Cancel" id="cancel" onclick="window.close();" image="cancel"></et2-button>
|
<et2-button statustext="Apply the changes" label="Apply" id="apply" image="apply"></et2-button>
|
||||||
</et2-hbox>
|
<et2-button statustext="leave without saveing the entry" label="Cancel" id="cancel"
|
||||||
<styles>
|
onclick="window.close();" image="cancel"></et2-button>
|
||||||
.home_note_portlet .et2_container > div {
|
</et2-hbox>
|
||||||
overflow: auto;
|
</et2-vbox>
|
||||||
}
|
<styles>
|
||||||
.home_note_portlet .et2_container div.dialogFooterToolbar {
|
#home-note et2-vbox {
|
||||||
display:none;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</styles>
|
#home-note et2-vbox > div {
|
||||||
</template>
|
flex: 1 1 auto;
|
||||||
|
width: initial;
|
||||||
|
height: initial;
|
||||||
|
}
|
||||||
|
.home_note_portlet .et2_container > div {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.home_note_portlet .et2_container div.dialogFooterToolbar {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
</styles>
|
||||||
|
</template>
|
||||||
</overlay>
|
</overlay>
|
Loading…
Reference in New Issue
Block a user