mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
e0d284d3ae
Static account options added to CalendarOwner were blocking the group data needed, fixed by using sent options over account options
185 lines
5.2 KiB
TypeScript
185 lines
5.2 KiB
TypeScript
/*
|
|
* Calendar owner widget
|
|
*
|
|
* @license https://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
* @package calendar
|
|
* @subpackage etemplate
|
|
* @link https://www.egroupware.org
|
|
* @author Nathan Gray
|
|
*/
|
|
|
|
import {Et2Select} from "../../api/js/etemplate/Et2Select/Et2Select";
|
|
import {css, html, nothing} from "@lion/core";
|
|
import {IsEmail} from "../../api/js/etemplate/Validators/IsEmail";
|
|
import {cleanSelectOptions} from "../../api/js/etemplate/Et2Select/FindSelectOptions";
|
|
import {Et2StaticSelectMixin} from "../../api/js/etemplate/Et2Select/StaticOptions";
|
|
|
|
/**
|
|
* Select widget customised for calendar owner, which can be a user
|
|
* account or group, or an entry from almost any app, or an email address
|
|
*
|
|
*/
|
|
export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
|
|
{
|
|
|
|
static get styles()
|
|
{
|
|
return [
|
|
...super.styles,
|
|
css`
|
|
/* Larger maximum height before scroll*/
|
|
.select__tags {
|
|
max-height: 10em;
|
|
}
|
|
`
|
|
];
|
|
}
|
|
|
|
constructor(...args : any[])
|
|
{
|
|
super(...args);
|
|
this.searchUrl = "calendar_owner_etemplate_widget::ajax_search";
|
|
this.multiple = true;
|
|
|
|
// Take grants into account for search
|
|
this.searchOptions['checkgrants'] = true;
|
|
}
|
|
|
|
connectedCallback()
|
|
{
|
|
super.connectedCallback();
|
|
|
|
// Start fetch of users
|
|
const type = this.egw().preference('account_selection', 'common');
|
|
if(!type || type == "none")
|
|
{
|
|
return;
|
|
}
|
|
let fetch = [];
|
|
// for primary_group we only display owngroups == own memberships, not other groups
|
|
if(type === 'primary_group')
|
|
{
|
|
fetch.push(this.egw().accounts('accounts').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
|
fetch.push(this.egw().accounts('owngroups').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
|
}
|
|
else
|
|
{
|
|
fetch.push(this.egw().accounts('accounts').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
|
fetch.push(this.egw().accounts('groups').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
|
|
}
|
|
this.fetchComplete = Promise.all(fetch)
|
|
.then(() => this._renderOptions());
|
|
}
|
|
|
|
/**
|
|
* Override parent to handle our special additional data types (c#,r#,etc.) when they
|
|
* are not available client side.
|
|
*
|
|
* @param {string|string[]} _value array of selected owners, which can be a number,
|
|
* or a number prefixed with one character indicating the resource type.
|
|
*/
|
|
set_value(_value)
|
|
{
|
|
super.set_value(_value);
|
|
|
|
// If parent didn't find a label, label will be the same as ID so we
|
|
// can find them that way
|
|
let missing_labels = [];
|
|
this.updateComplete.then(() =>
|
|
{
|
|
for(var i = 0; i < this.value.length; i++)
|
|
{
|
|
if(!this.select_options.find(o => o.value == this.value[i]))
|
|
{
|
|
missing_labels.push(this.value[i]);
|
|
}
|
|
}
|
|
if(Object.keys(missing_labels).length > 0)
|
|
{
|
|
// Proper label was not found by parent - ask directly
|
|
this.egw().json('calendar_owner_etemplate_widget::ajax_owner', [missing_labels], function(data)
|
|
{
|
|
for(let owner in data)
|
|
{
|
|
if(!owner || typeof owner == "undefined")
|
|
{
|
|
continue;
|
|
}
|
|
// Put it in the list of options
|
|
let index = this.select_options.findIndex(o => o.value == owner);
|
|
let remote_index = this._selected_remote.findIndex(o => o.value == owner);
|
|
if(remote_index !== -1)
|
|
{
|
|
this._selected_remote[remote_index] = data[owner];
|
|
}
|
|
else if(index == -1)
|
|
{
|
|
this._selected_remote.push(data[owner]);
|
|
}
|
|
}
|
|
this.requestUpdate("select_options");
|
|
this.updateComplete.then(() => {this.syncItemsFromValue();});
|
|
}, this, true, this).sendRequest();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check a value for missing options and remove them.
|
|
*
|
|
* Override to allow any value, since we won't have all options
|
|
*
|
|
* @param {string[]} value
|
|
* @returns {string[]}
|
|
*/
|
|
filterOutMissingOptions(value : string[]) : string[]
|
|
{
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Override icon for the select option to use lavatar
|
|
*
|
|
* @param option
|
|
* @protected
|
|
*/
|
|
protected _iconTemplate(option)
|
|
{
|
|
// Not a user / contact, no icon - use app image
|
|
if(!option.fname && !option.lname && !option.icon && option.app)
|
|
{
|
|
return html`
|
|
<et2-image src="${option.app}/navbar" style="width: var(--icon-width)"></et2-image>`;
|
|
}
|
|
// lavatar uses a size property, not a CSS variable
|
|
let style = getComputedStyle(this);
|
|
return html`
|
|
<et2-lavatar slot="prefix" part="icon" .size=${style.getPropertyValue("--icon-width")}
|
|
lname=${option.lname || nothing}
|
|
fname=${option.fname || nothing}
|
|
image=${option.icon || nothing}
|
|
>
|
|
</et2-lavatar>`;
|
|
}
|
|
|
|
/**
|
|
* Check if a free entry value is acceptable.
|
|
* We only check the free entry, since value can be mixed.
|
|
*
|
|
* @param text
|
|
* @returns {boolean}
|
|
*/
|
|
public validateFreeEntry(text) : boolean
|
|
{
|
|
let validators = [...this.validators, new IsEmail()];
|
|
let result = validators.filter(v =>
|
|
v.execute(text, v.param, {node: this}),
|
|
);
|
|
return result.length == 0;
|
|
}
|
|
}
|
|
|
|
if(!customElements.get("et2-calendar-owner"))
|
|
{
|
|
customElements.define("et2-calendar-owner", CalendarOwner);
|
|
} |