* All apps: limit number of loaded links to 20 and showing a load more button, if more are available

This commit is contained in:
ralf 2024-09-24 11:32:17 +02:00
parent a15136733c
commit 3fbf2e99fd
5 changed files with 85 additions and 54 deletions

View File

@ -13,8 +13,10 @@
import {css, html, LitElement, PropertyValues, render, TemplateResult} from "lit";
import {until} from "lit/directives/until.js";
import {Et2Widget} from "../Et2Widget/Et2Widget";
import {Et2Link, LinkInfo} from "./Et2Link";
import {LinkInfo} from "./Et2Link";
import {et2_IDetachedDOM} from "../et2_core_interfaces";
import {property} from "lit/decorators/property.js";
import {customElement} from "lit/decorators/custom-element.js";
/**
* Display a list of entries in a comma separated list
@ -25,6 +27,7 @@ import {et2_IDetachedDOM} from "../et2_core_interfaces";
*/
// @ts-ignore TypeScript says there's something wrong with types
@customElement('et2-link-string')
export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetachedDOM
{
@ -62,52 +65,52 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
}
static get properties()
{
return {
...super.properties,
/**
* Specify the application for all the entries, so you only need to specify the entry ID
*/
application: {
type: String,
reflect: true,
},
/**
* Application entry ID
*/
entryId: {
type: String,
reflect: true
},
/**
* Application filter
* Set to an appname or comma separated list of applications to show only linked entries from those
* applications
*/
onlyApp: {
type: String
},
/**
* Type filter
* Sub-type key to list only entries of that type
*/
linkType: {
type: String
},
/**
* Specify the application for all the entries, so you only need to specify the entry ID
*/
@property({ type: String, reflect: true })
application;
// Show links that are marked as deleted, being held for purge
showDeleted: {type: Boolean},
/**
* Application entry ID
*/
@property({type: String, reflect: true})
entryId;
/**
* Pass value as an object, will be parsed to set application & entryId
*/
value: {
type: Object,
reflect: false
}
}
}
/**
* Application filter
* Set to an appname or comma separated list of applications to show only linked entries from those
* applications
*/
@property({type: String})
onlyApp;
/**
* Type filter
* Sub-type key to list only entries of that type
*/
@property({type: String})
linkType;
/**
* Show links that are marked as deleted, being held for purge
*/
@property({type: Boolean})
showDeleted = false;
/**
* Pass value as an object, will be parsed to set application & entryId
*/
@property({type: Object})
value;
/**
* Number of application-links to load (file-links are always fully loaded currently)
*
* If number is exceeded, a "Load more links ..." button is displayed, which will load the double amount of links each time clicked
*/
@property({type: Number})
limit = 20;
protected _link_list : LinkInfo[];
protected _loadingPromise : Promise<LinkInfo[]>;
@ -116,7 +119,6 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
{
super();
this._link_list = []
this.__showDeleted = false;
}
async getUpdateComplete()
@ -228,6 +230,21 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
<et2-link app="${link.app}" entryId="${id}" .value=${link} ._parent=${this}></et2-link>`;
}
/**
* Render "more links available"
*
* @param link
* @returns {TemplateResult}
* @protected
*/
protected _moreAvailableTemplate(link : LinkInfo) : TemplateResult
{
return html`
<et2-button image="${link.icon}" label="${link.title}" .onclick="${() => {
this.get_links();
}}" ._parent=${this} slot="link_exceeded"></et2-button>`;
}
/**
* Render that we're waiting for data
* @returns {TemplateResult}
@ -256,7 +273,7 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
links.forEach((link) =>
{
let temp = document.createElement("div");
render(this._linkTemplate(link), temp);
render(link.app === 'exceeded' ? this._moreAvailableTemplate(link) : this._linkTemplate(link), temp);
temp.childNodes.forEach((node) => this.appendChild(node));
})
@ -290,8 +307,11 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
to_app: this.application,
to_id: this.entryId,
only_app: this.onlyApp,
show_deleted: this.showDeleted
show_deleted: this.showDeleted,
limit: this.limit
};
this.limit *= 2; // double number of loaded links on next call
if(this._loadingPromise)
{
// Already waiting
@ -333,6 +353,4 @@ export class Et2LinkString extends Et2Widget(LitElement) implements et2_IDetache
this[k] = _values[k];
}
}
};
customElements.define("et2-link-string", Et2LinkString);
}

View File

@ -5,7 +5,6 @@
%1 email addresses inserted common de %1 E-Mail-Adressen eingefügt.
%1 email(s) added into %2 common de %1 E-Mail-Adresse(n) in %2 hinzugefügt
%1 etemplates deleted common de %1 eTemplate(s) gelöscht
%1 etemplates for application '%2' dumped to '%3' common de %1 eTemplate(s) für die Anwendung '%2' nach '%3' geschrieben
%1 etemplates found common de %1 eTemplate(s) gefunden.
%1 file common de %1 Datei
%1 is not executable by the webserver !!! common de %1 ist nicht ausführbar durch den Webserver!
@ -819,6 +818,7 @@ list members common de Mitglieder anzeigen
list of files linked to the current record preferences de Liste der Dokumente, die zu dem aktuellen Datensatz gehören.
lithuania common de LITAUEN
load common de Daten werden geladen
load more links ... common de Weitere Verknüpfungen laden ...
load this template into the editor common de Lädt diese Template zum Bearbeiten
loading common de Lade
local common de Lokal

View File

@ -819,6 +819,7 @@ list members common en List members
list of files linked to the current record preferences en List of files linked to the current record
lithuania common en LITHUANIA
load common en Load
load more links ... common en Load more links ...
load this template into the editor common en Load template to the editor
loading common en Loading
local common en Local

View File

@ -201,7 +201,8 @@ class Link extends Etemplate\Widget
$app = $value['to_app'];
$id = $value['to_id'];
$links = Api\Link::get_links($app, $id, $value['only_app'], 'link_lastmod DESC', true, $value['show_deleted']);
$links = Api\Link::get_links($app, $id, $value['only_app'] ?? '', 'link_lastmod DESC', true, $value['show_deleted'], $value['limit'] ?? null);
$limit_exceeded = !empty($value['limit']) && Api\Link::$limit_exceeded;
$only_links = [];
if($value['only_app'])
{
@ -243,6 +244,15 @@ class Link extends Etemplate\Widget
$link['help'] = lang('Remove this link (not the entry itself)');
}
}
if ($limit_exceeded)
{
$links[] = [
'app' => 'exceeded',
'id' => 'exceeded',
'title' => lang('Load more links ...'),
'icon' => 'box-arrow-down',
];
}
$response = Api\Json\Response::get();
// Strip keys, unneeded and cause index problems on the client side

View File

@ -522,6 +522,7 @@ class Link extends Link\Storage
return $ids;
}
$ids = Link\Storage::get_links($app, $id, $only_app, $order, $deleted, $limit);
$limit_exceeded = self::$limit_exceeded;
if (empty($only_app) || $only_app == self::VFS_APPNAME ||
($only_app[0] == '!' && $only_app != '!'.self::VFS_APPNAME))
{
@ -533,7 +534,7 @@ class Link extends Link\Storage
//echo "ids=<pre>"; print_r($ids); echo "</pre>\n";
if ($cache_titles)
{
// agregate links by app
// aggregate links by app
$app_ids = array();
foreach($ids as $link)
{
@ -553,6 +554,7 @@ class Link extends Link\Storage
}
reset($ids);
}
self::$limit_exceeded = $limit_exceeded;
return $ids;
}