From b1a3dcd908676cd1fe2a082a44f083bc1ad47283 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Tue, 28 Feb 2023 15:23:19 +0000 Subject: [PATCH 1/5] Directly load a single entry to open the detail view faster --- js/layout-javascript/small-card-code.js | 131 ++++++++++++++++++++---- 1 file changed, 112 insertions(+), 19 deletions(-) diff --git a/js/layout-javascript/small-card-code.js b/js/layout-javascript/small-card-code.js index fd0eff14..fbb655d4 100644 --- a/js/layout-javascript/small-card-code.js +++ b/js/layout-javascript/small-card-code.js @@ -925,6 +925,11 @@ DynamicList.prototype.initialize = function() { .then(function() { // Render Base HTML template _this.renderBaseHTML(); + + // Check if it's meant to directly open a single record + return _this.checkIsToOpen(); + }) + .then(function() { // Determine filter types from configuration _this.filterTypes = _this.Utils.getFilterTypes({ instance: _this }); @@ -1002,8 +1007,6 @@ DynamicList.prototype.initialize = function() { }) .then(function(response) { _this.listItems = _.uniqBy(response, 'id'); - - return _this.checkIsToOpen(); }) .then(function() { _this.modifiedListItems = _this.Utils.Records.addFilterProperties({ @@ -1029,37 +1032,127 @@ DynamicList.prototype.changeSortOrder = function() { } }; +DynamicList.prototype.getDataSourceConnection = function() { + return Fliplet.DataSources.connect(this.data.dataSourceId, { + offline: this.data.hasOwnProperty('cache') ? this.data.cache : undefined + }); +}; + +DynamicList.prototype.loadSingleRecordData = function() { + var _this = this; + + // Hook: flListDataBeforeGetRecord + return Fliplet.Hooks.run('flListDataBeforeGetRecord', { + instance: this, + config: this.data, + id: this.data.id, + uuid: this.data.uuid, + container: this.$container, + openQuery: this.pvOpenQuery + }).then(function() { + return _this.getDataSourceConnection(); + }).then(function(connection) { + // Get single record + if (_.hasIn(_this.pvOpenQuery, 'id')) { + return connection.findById(_this.pvOpenQuery.id); + } else if (_.hasIn(_this.pvOpenQuery, 'value') && _.hasIn(_this.pvOpenQuery, 'column')) { + var query = { where: {} }; + + query.where[_this.pvOpenQuery.column] = _this.pvOpenQuery.value; + + return connection.findOne(query); + } + }).then(function(record) { + var records = [record]; + + // Add computed fields + _this.Utils.Records.addComputedFields({ + records: records, + config: _this.data, + filterTypes: _this.filterTypes + }); + + return Fliplet.Hooks.run('flListDataAfterGetRecord', { + instance: _this, + config: _this.data, + id: _this.data.id, + uuid: _this.data.uuid, + container: _this.$container, + openQuery: _this.pvOpenQuery, + record: records[0] + }).then(function() { + // Add permissions + records = _this.getPermissions(records); + + return records; + }); + }).then(function(records) { + // Get full list of aggregated columns + return _this.Utils.Records.getFields(records, _this.data.dataSourceId) + .then(function(columns) { + _this.dataSourceColumns = columns; + + return records; + }); + }).then(function(records) { + // Update files for media fields + return _this.Utils.Records.updateFiles({ + records: records, + config: _this.data + }); + }).then(function(response) { + return _.uniqBy(response, 'id')[0]; + }); +}; + DynamicList.prototype.checkIsToOpen = function() { var _this = this; var entry; + var loadSingleRecordData; if (!_this.queryOpen) { return Promise.resolve(); } - if (_.hasIn(_this.pvOpenQuery, 'id')) { - entry = _.find(_this.listItems, { id: _this.pvOpenQuery.id }); - } else if (_.hasIn(_this.pvOpenQuery, 'value') && _.hasIn(_this.pvOpenQuery, 'column')) { - entry = _.find(_this.listItems, function(row) { - // eslint-disable-next-line eqeqeq - return row.data[_this.pvOpenQuery.column] == _this.pvOpenQuery.value; - }); - } + if (typeof this.listItems !== 'undefined') { + if (_.hasIn(this.pvOpenQuery, 'id')) { + entry = _.find(this.listItems, { id: this.pvOpenQuery.id }); + } else if (_.hasIn(this.pvOpenQuery, 'value') && _.hasIn(this.pvOpenQuery, 'column')) { + entry = _.find(this.listItems, function(row) { + // eslint-disable-next-line eqeqeq + return row.data[_this.pvOpenQuery.column] == _this.pvOpenQuery.value; + }); + } - if (!entry) { - Fliplet.UI.Toast(T('widgets.list.dynamic.notifications.notFound')); + if (!entry) { + Fliplet.UI.Toast(T('widgets.list.dynamic.notifications.notFound')); - return Promise.resolve(); + return Promise.resolve(); + } + + loadSingleRecordData = Promise.resolve(entry); + } else { + loadSingleRecordData = this.loadSingleRecordData(); } - var modifiedData = _this.addSummaryData([entry]); + return loadSingleRecordData.then(function(record) { + if (!record) { + Fliplet.UI.Toast(T('widgets.list.dynamic.notifications.notFound')); - return _this.showDetails(entry.id, modifiedData).then(function() { - _this.openedEntryOnQuery = true; + return Promise.resolve(); + } + + var modifiedData = _this.addSummaryData([record]); + + return _this.showDetails(record.id, modifiedData).then(function() { + _this.openedEntryOnQuery = true; - // Wait for overlay transition to complete - return new Promise(function(resolve) { - setTimeout(resolve, 250); + // Wait for overlay transition to complete + return new Promise(function(resolve) { + setTimeout(function() { + resolve(true); + }, 250); + }); }); }); }; From d7cf69ce8dd9b92df69d6a80e6d805ae930e1021 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Tue, 28 Feb 2023 18:32:28 +0000 Subject: [PATCH 2/5] Add initial render flag to beforeRenderList hook --- js/layout-javascript/small-card-code.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/layout-javascript/small-card-code.js b/js/layout-javascript/small-card-code.js index fbb655d4..88528848 100644 --- a/js/layout-javascript/small-card-code.js +++ b/js/layout-javascript/small-card-code.js @@ -1675,7 +1675,8 @@ DynamicList.prototype.searchData = function(options) { showBookmarks: _this.showBookmarks, sortField: _this.sortField, sortOrder: _this.sortOrder, - limit: limit + limit: limit, + initialRender: !!options.initialRender }).then(function() { searchedData = searchedData || []; From b6647d02bf256e2f8a2192e9cc24c499ff091c4a Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Wed, 1 Mar 2023 18:56:09 +0000 Subject: [PATCH 3/5] Adds new hook for intercepting initialisation --- js/layout-javascript/small-card-code.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/js/layout-javascript/small-card-code.js b/js/layout-javascript/small-card-code.js index 88528848..8a3704ec 100644 --- a/js/layout-javascript/small-card-code.js +++ b/js/layout-javascript/small-card-code.js @@ -926,6 +926,15 @@ DynamicList.prototype.initialize = function() { // Render Base HTML template _this.renderBaseHTML(); + return Fliplet.Hooks.run('flListDataBeforeInit', { + instance: _this, + config: _this.data, + id: _this.data.id, + uuid: _this.data.uuid, + container: _this.$container + }); + }) + .then(function() { // Check if it's meant to directly open a single record return _this.checkIsToOpen(); }) @@ -1041,7 +1050,6 @@ DynamicList.prototype.getDataSourceConnection = function() { DynamicList.prototype.loadSingleRecordData = function() { var _this = this; - // Hook: flListDataBeforeGetRecord return Fliplet.Hooks.run('flListDataBeforeGetRecord', { instance: this, config: this.data, From 1e6e533328da7e89e5833365404fcac60a299d54 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Thu, 2 Mar 2023 12:31:26 +0000 Subject: [PATCH 4/5] Use the same existing hook (with new payload) to avoid breaking changes --- js/layout-javascript/small-card-code.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/js/layout-javascript/small-card-code.js b/js/layout-javascript/small-card-code.js index 8a3704ec..cebd455f 100644 --- a/js/layout-javascript/small-card-code.js +++ b/js/layout-javascript/small-card-code.js @@ -1050,13 +1050,14 @@ DynamicList.prototype.getDataSourceConnection = function() { DynamicList.prototype.loadSingleRecordData = function() { var _this = this; - return Fliplet.Hooks.run('flListDataBeforeGetRecord', { + return Fliplet.Hooks.run('flListDataBeforeGetData', { instance: this, config: this.data, id: this.data.id, uuid: this.data.uuid, container: this.$container, - openQuery: this.pvOpenQuery + openQuery: this.pvOpenQuery, + getSingleEntry: true }).then(function() { return _this.getDataSourceConnection(); }).then(function(connection) { @@ -1080,13 +1081,14 @@ DynamicList.prototype.loadSingleRecordData = function() { filterTypes: _this.filterTypes }); - return Fliplet.Hooks.run('flListDataAfterGetRecord', { + return Fliplet.Hooks.run('flListDataAfterGetData', { instance: _this, config: _this.data, id: _this.data.id, uuid: _this.data.uuid, container: _this.$container, openQuery: _this.pvOpenQuery, + getSingleEntry: true, record: records[0] }).then(function() { // Add permissions From 5ad21a4a3148198c5e0eb4b4d63c513094fba357 Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Fri, 3 Mar 2023 23:51:12 +0000 Subject: [PATCH 5/5] Only add summary data for entries before rendering --- js/layout-javascript/small-card-code.js | 27 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/js/layout-javascript/small-card-code.js b/js/layout-javascript/small-card-code.js index cebd455f..d38c4d6a 100644 --- a/js/layout-javascript/small-card-code.js +++ b/js/layout-javascript/small-card-code.js @@ -1152,9 +1152,7 @@ DynamicList.prototype.checkIsToOpen = function() { return Promise.resolve(); } - var modifiedData = _this.addSummaryData([record]); - - return _this.showDetails(record.id, modifiedData).then(function() { + return _this.showDetails(record.id, [record]).then(function() { _this.openedEntryOnQuery = true; // Wait for overlay transition to complete @@ -1368,6 +1366,8 @@ DynamicList.prototype.renderLoopSegment = function(options) { ? Handlebars.compile(this.data.advancedSettings.loopHTML) : Handlebars.compile(Fliplet.Widget.Templates[this.layoutMapping[this.data.layout]['loop']]()); + data = this.addSummaryData(data); + return new Promise(function(resolve) { function render() { // get the next batch of items to render @@ -1479,25 +1479,28 @@ DynamicList.prototype.attachLazyLoadObserver = function(options) { }); }; -DynamicList.prototype.renderLoopHTML = function() { +DynamicList.prototype.renderLoopHTML = function(options) { + options = options || {}; + // Function that renders the List template var _this = this; + var records = options.records || []; var limitedList; var isSorting = this.sortField && ['asc', 'desc'].indexOf(this.sortOrder) > -1; if (_this.data.enabledLimitEntries && _this.data.limitEntries >= 0 && !_this.isSearching && !_this.isFiltering && !_this.showBookmarks && !isSorting) { - limitedList = _this.modifiedListItems.slice(0, _this.data.limitEntries); + limitedList = records.slice(0, _this.data.limitEntries); // Hides the entry limit warning if the number of entries to show is less than the limit value - if (_this.data.limitEntries > _this.modifiedListItems.length) { + if (_this.data.limitEntries > records.length) { _this.$container.find('.limit-entries-text').addClass('hidden'); } } $('#small-card-list-wrapper-' + _this.data.id).empty(); - this.renderListItems = _.clone(limitedList || _this.modifiedListItems || []); + this.renderListItems = _.clone(limitedList || records || []); var data = this.renderListItems.splice(0, this.data.lazyLoadBatchSize || this.renderListItems.length); @@ -1752,9 +1755,9 @@ DynamicList.prototype.searchData = function(options) { $('#small-card-list-wrapper-' + _this.data.id).html(''); - _this.modifiedListItems = _this.addSummaryData(searchedData); - - return _this.renderLoopHTML().then(function(records) { + return _this.renderLoopHTML({ + records: searchedData + }).then(function(records) { _this.searchedListItems = searchedData; // Render user profile @@ -2220,6 +2223,10 @@ DynamicList.prototype.showDetails = function(id, listData) { detailViewOptions: _this.data.detailViewOptions }) .then(function(files) { + if (typeof entryData.originalData === 'undefined') { + entryData = _this.addSummaryData([entryData])[0]; + } + entryData = _this.addDetailViewData(entryData); if (files && Array.isArray(files)) {