Calendar: Group calendar owner / participant search results by resource type

This commit is contained in:
nathan 2023-11-01 13:26:23 -06:00
parent bed98c0e9e
commit 5d705c3b79
4 changed files with 58 additions and 18 deletions

View File

@ -739,7 +739,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
* @param option * @param option
* @protected * @protected
*/ */
protected _iconTemplate(option) protected _iconTemplate(option : SelectOption)
{ {
if(!option.icon) if(!option.icon)
{ {
@ -767,7 +767,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
{ {
const readonly = (this.readonly || option && typeof (option.disabled) != "undefined" && option.disabled); const readonly = (this.readonly || option && typeof (option.disabled) != "undefined" && option.disabled);
const isEditable = this.editModeEnabled && !readonly; const isEditable = this.editModeEnabled && !readonly;
const image = this._iconTemplate(option); const image = this._iconTemplate(option.option ?? option);
const tagName = this.tagTag; const tagName = this.tagTag;
return html` return html`
<${tagName} <${tagName}

View File

@ -1119,7 +1119,18 @@ export const Et2WithSearchMixin = dedupeMixin(<T extends Constructor<LitElement>
this._total_result_count = 0; this._total_result_count = 0;
// Not searching anymore, clear flag // Not searching anymore, clear flag
this.select_options.map((o) => o.isMatch = null); const clear_flag = (option) =>
{
if(Array.isArray(option.value))
{
option.map(clear_flag)
}
else
{
option.isMatch = null
}
}
this.select_options.map(clear_flag);
this.requestUpdate("select_options"); this.requestUpdate("select_options");
} }
@ -1238,6 +1249,8 @@ export const Et2WithSearchMixin = dedupeMixin(<T extends Constructor<LitElement>
{ {
this._total_result_count += results.total; this._total_result_count += results.total;
delete results.total; delete results.total;
// Make it an array, since it was probably an object, and cleanSelectOptions() treats objects differently
results = Object.values(results);
} }
else else
{ {
@ -1260,20 +1273,32 @@ export const Et2WithSearchMixin = dedupeMixin(<T extends Constructor<LitElement>
{ {
return Promise.resolve(); return Promise.resolve();
} }
// Add a "remote" class so we can tell these apart from any local results const process = (entries) =>
for(let i = entries.length - 1; i >= 0; i--)
{ {
const entry = entries[i]; // Add a "remote" class so we can tell these apart from any local results
entry.class = (entry.class || "") + " remote"; for(let i = entries.length - 1; i >= 0; i--)
// Server says it's a match
entry.isMatch = true;
// Avoid duplicates with existing options
if(this.select_options.some(o => o.value == entry.value))
{ {
entries.splice(i, 1); const entry = entries[i];
entry.class = (entry.class || "") + " remote";
// Handle option groups
if(Array.isArray(entry.value))
{
process(entry.value);
continue;
}
// Server says it's a match
entry.isMatch = true;
// Avoid duplicates with existing options
if(this.select_options.some(o => o.value == entry.value))
{
entries.splice(i, 1);
}
} }
} }
process(entries);
this._remote_options = entries; this._remote_options = entries;
this.requestUpdate("select_options"); this.requestUpdate("select_options");

View File

@ -300,7 +300,7 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
continue; continue;
} }
foreach(array_unique($_results, SORT_REGULAR) as $id => $title) foreach($_results as $id => $title)
{ {
if($id && $title) if($id && $title)
{ {
@ -309,7 +309,11 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
} }
if(count($mapped)) if(count($mapped))
{ {
$results = array_merge($results, $mapped); $results[] = [
'label' => $data['app'],
'value' => $mapped,
'icon' => $data['icon'] ?? Link::get_registry($data['app'], 'icon')
];
} }
} }
if($total) if($total)
@ -411,6 +415,9 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
default : default :
// do nothing // do nothing
} }
// Make sure ID (value) is string
$value['value'] = (string)$value['value'];
return $value; return $value;
} }

View File

@ -103,9 +103,18 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
let missing_labels = []; let missing_labels = [];
this.updateComplete.then(() => this.updateComplete.then(() =>
{ {
// find that can handle option groups
const find = (option) =>
{
if(Array.isArray(option.value))
{
return option.find(find);
}
return option.value == this.value[i];
}
for(var i = 0; i < this.value.length; i++) for(var i = 0; i < this.value.length; i++)
{ {
if(!this.select_options.find(o => o.value == this.value[i])) if(!this.select_options.find(find))
{ {
missing_labels.push(this.value[i]); missing_labels.push(this.value[i]);
} }
@ -134,7 +143,6 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
} }
} }
this.requestUpdate("select_options"); this.requestUpdate("select_options");
this.updateComplete.then(() => {this.syncItemsFromValue();});
}, this, true, this).sendRequest(); }, this, true, this).sendRequest();
} }
}); });
@ -159,7 +167,7 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
* @param option * @param option
* @protected * @protected
*/ */
protected _iconTemplate(option) protected _iconTemplate(option : SelectOption)
{ {
// Not a user / contact, no icon - use app image // Not a user / contact, no icon - use app image
if(!option.fname && !option.lname && !option.icon && option.app) if(!option.fname && !option.lname && !option.icon && option.app)