From 3fbf2e99fd657602a6d422581d9d46f44acfa020 Mon Sep 17 00:00:00 2001 From: ralf Date: Tue, 24 Sep 2024 11:32:17 +0200 Subject: [PATCH] * All apps: limit number of loaded links to 20 and showing a load more button, if more are available --- api/js/etemplate/Et2Link/Et2LinkString.ts | 120 +++++++++++++--------- api/lang/egw_de.lang | 2 +- api/lang/egw_en.lang | 1 + api/src/Etemplate/Widget/Link.php | 12 ++- api/src/Link.php | 4 +- 5 files changed, 85 insertions(+), 54 deletions(-) diff --git a/api/js/etemplate/Et2Link/Et2LinkString.ts b/api/js/etemplate/Et2Link/Et2LinkString.ts index c302b081b9..05501c3e24 100644 --- a/api/js/etemplate/Et2Link/Et2LinkString.ts +++ b/api/js/etemplate/Et2Link/Et2LinkString.ts @@ -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; @@ -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 `; } + /** + * Render "more links available" + * + * @param link + * @returns {TemplateResult} + * @protected + */ + protected _moreAvailableTemplate(link : LinkInfo) : TemplateResult + { + return html` + `; + } + /** * 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); \ No newline at end of file +} \ No newline at end of file diff --git a/api/lang/egw_de.lang b/api/lang/egw_de.lang index d92e1d88e4..1aaf44d35f 100644 --- a/api/lang/egw_de.lang +++ b/api/lang/egw_de.lang @@ -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 diff --git a/api/lang/egw_en.lang b/api/lang/egw_en.lang index 8482910ec2..2018609d9c 100644 --- a/api/lang/egw_en.lang +++ b/api/lang/egw_en.lang @@ -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 diff --git a/api/src/Etemplate/Widget/Link.php b/api/src/Etemplate/Widget/Link.php index be99431a36..0bd36ffba2 100644 --- a/api/src/Etemplate/Widget/Link.php +++ b/api/src/Etemplate/Widget/Link.php @@ -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 diff --git a/api/src/Link.php b/api/src/Link.php index 26e3313c81..217c71c768 100644 --- a/api/src/Link.php +++ b/api/src/Link.php @@ -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=
"; print_r($ids); echo "
\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; }