Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Build

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build widget
run: make
25 changes: 25 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Tests

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Run tests
run: yarn test
76 changes: 5 additions & 71 deletions app/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.css'], function ($, Ractive, mainTemplate, css) {
define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.css', 'app/helpers'], function ($, Ractive, mainTemplate, css, helpers) {

'use strict';

$.noConflict();
var MAX_DETAIL_LEN = 100;
var xhr_suggestions = null;
var timeout_suggestions = null;
var search_widget = {
Expand Down Expand Up @@ -89,7 +88,7 @@ define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.cs
ev.original.preventDefault();
if (newPage > totalPages || newPage < 1) return false;

changePagination(that, newPage);
helpers.changePagination(that, newPage);
doSearch(that, false);
}
});
Expand All @@ -110,17 +109,12 @@ define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.cs
url: url + '/'+term+'?page='+page+'&page_size='+perPage,
dataType: "json"
}).done(function(resp) {
var results = resp.results.map(function(r) {
var detail = r.hasOwnProperty('meta_description') ? r.meta_description : r.content;
detail = detail.length > MAX_DETAIL_LEN ? detail.substring(0, MAX_DETAIL_LEN) + '...' : detail;
var title = r.hasOwnProperty('meta_title') ? r.meta_title : r.title;
return {link: r.url, title: title, detail: detail};
});
var results = helpers.mapSearchResults(resp.results);

that.set('total', resp.qty);
that.set('results', results);

if(reset) resetPagination(that);
if(reset) helpers.resetPagination(that);

}).fail(function(resp) {
// error response
Expand All @@ -135,9 +129,7 @@ define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.cs
url: 'https://'+that.baseUrl+'/api/public/v1/suggestions/'+that.context+'/'+term,
dataType: "json"
}).done(function(resp) {
var results = resp.results.map(function(r) {
return {link: r.payload, title: r.term};
});
var results = helpers.mapSuggestions(resp.results);
xhr_suggestions = null;
that.set('suggestions', results);

Expand All @@ -146,64 +138,6 @@ define(['jquery', 'ractive', 'rv!templates/template', 'text!css/widget-styles.cs
});
}

function resetPagination(that) {
var total = that.get('total');
var perPage = that.get('perPage');
var totalPages = Math.ceil(total / perPage);
var lastPage = (totalPages < 5) ? totalPages : 5;
var newPagesToShow = [];

for( var i = 1; i <= lastPage; i++) {
newPagesToShow.push(i);
}

that.set('page', 1);
that.set('pagesToShow', newPagesToShow);

// change results
var newResultLimit = (perPage);
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', 1);
that.set('toResult', newResultLimit);
}

function changePagination(that, newPage) {
var total = that.get('total');
var pagesToShow = that.get('pagesToShow');
var perPage = that.get('perPage');
var lastPage = pagesToShow[pagesToShow.length - 1];
var firstPage = pagesToShow[0];
var totalPages = Math.ceil(total / perPage);
var newPagesToShow = [];

that.set('page', newPage);

// change results
var newResultLimit = (newPage * perPage);
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', ((newPage - 1) * perPage) + 1);
that.set('toResult', newResultLimit);

// change pagination
if (newPage > lastPage - 1 || newPage < firstPage + 1) {
var pageFrom;
var pageTo = ((newPage + 2) < 5) ? 5 : (newPage + 2);
newPagesToShow = []

if (pageTo > totalPages) {
pageTo = totalPages;
}

pageFrom = ((pageTo - 4) < 1) ? 1 : (pageTo - 4);

for( var i = pageFrom; i <= pageTo; i++) {
newPagesToShow.push(i);
}

that.set('pagesToShow', newPagesToShow);
}
}

function centerPopup(el) {
var winW = $(window).width();
var newPopWidth = winW * 0.8;
Expand Down
84 changes: 84 additions & 0 deletions app/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
define([], function () {

'use strict';

var MAX_DETAIL_LEN = 100;

function mapSearchResults(results) {
return results.map(function(r) {
var detail = r.hasOwnProperty('meta_description') ? r.meta_description : r.content;
detail = detail.length > MAX_DETAIL_LEN ? detail.substring(0, MAX_DETAIL_LEN) + '...' : detail;
var title = r.hasOwnProperty('meta_title') ? r.meta_title : r.title;
return {link: r.url, title: title, detail: detail};
});
}

function mapSuggestions(results) {
return results.map(function(r) {
return {link: r.payload, title: r.term};
});
}

function resetPagination(that) {
var total = that.get('total');
var perPage = that.get('perPage');
var totalPages = Math.ceil(total / perPage);
var lastPage = (totalPages < 5) ? totalPages : 5;
var newPagesToShow = [];

for (var i = 1; i <= lastPage; i++) {
newPagesToShow.push(i);
}

that.set('page', 1);
that.set('pagesToShow', newPagesToShow);

var newResultLimit = perPage;
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', 1);
that.set('toResult', newResultLimit);
Comment on lines +22 to +39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle the zero-results case explicitly.

When total is 0, Line 38 sets fromResult to 1 while Line 39 sets toResult to 0, and pagesToShow is left empty. That produces an impossible 1-0 of 0 state for empty searches.

Proposed fix
 function resetPagination(that) {
     var total = that.get('total');
     var perPage = that.get('perPage');
+
+    if (total === 0) {
+        that.set('page', 1);
+        that.set('pagesToShow', []);
+        that.set('fromResult', 0);
+        that.set('toResult', 0);
+        return;
+    }
+
     var totalPages = Math.ceil(total / perPage);
     var lastPage = (totalPages < 5) ? totalPages : 5;
     var newPagesToShow = [];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function resetPagination(that) {
var total = that.get('total');
var perPage = that.get('perPage');
var totalPages = Math.ceil(total / perPage);
var lastPage = (totalPages < 5) ? totalPages : 5;
var newPagesToShow = [];
for (var i = 1; i <= lastPage; i++) {
newPagesToShow.push(i);
}
that.set('page', 1);
that.set('pagesToShow', newPagesToShow);
var newResultLimit = perPage;
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', 1);
that.set('toResult', newResultLimit);
function resetPagination(that) {
var total = that.get('total');
var perPage = that.get('perPage');
if (total === 0) {
that.set('page', 1);
that.set('pagesToShow', []);
that.set('fromResult', 0);
that.set('toResult', 0);
return;
}
var totalPages = Math.ceil(total / perPage);
var lastPage = (totalPages < 5) ? totalPages : 5;
var newPagesToShow = [];
for (var i = 1; i <= lastPage; i++) {
newPagesToShow.push(i);
}
that.set('page', 1);
that.set('pagesToShow', newPagesToShow);
var newResultLimit = perPage;
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', 1);
that.set('toResult', newResultLimit);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/helpers.js` around lines 22 - 39, In resetPagination, explicitly handle
the total === 0 case: at the top of the function (inside resetPagination) check
if total === 0 and then set pagesToShow to an empty array, set page to 0 (or
another sentinel for “no page”), and set fromResult and toResult both to 0, then
return; otherwise continue the existing logic that computes totalPages,
lastPage, newPagesToShow, etc.; update references to pagesToShow, page,
fromResult, and toResult accordingly so the UI never shows an impossible "1-0 of
0" state.

}

function changePagination(that, newPage) {
var total = that.get('total');
var pagesToShow = that.get('pagesToShow');
var perPage = that.get('perPage');
var lastPage = pagesToShow[pagesToShow.length - 1];
var firstPage = pagesToShow[0];
var totalPages = Math.ceil(total / perPage);
var newPagesToShow = [];

that.set('page', newPage);

var newResultLimit = (newPage * perPage);
newResultLimit = (newResultLimit > total) ? total : newResultLimit;
that.set('fromResult', ((newPage - 1) * perPage) + 1);
that.set('toResult', newResultLimit);

if (newPage > lastPage - 1 || newPage < firstPage + 1) {
var pageFrom;
var pageTo = ((newPage + 2) < 5) ? 5 : (newPage + 2);

if (pageTo > totalPages) {
pageTo = totalPages;
}

pageFrom = ((pageTo - 4) < 1) ? 1 : (pageTo - 4);

for (var i = pageFrom; i <= pageTo; i++) {
newPagesToShow.push(i);
}

that.set('pagesToShow', newPagesToShow);
}
}

return {
MAX_DETAIL_LEN: MAX_DETAIL_LEN,
mapSearchResults: mapSearchResults,
mapSuggestions: mapSuggestions,
resetPagination: resetPagination,
changePagination: changePagination
};

});
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
plugins: ['transform-amd-to-commonjs']
};
22 changes: 11 additions & 11 deletions embed.min.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
testEnvironment: 'jsdom',
testMatch: ['<rootDir>/tests/**/*.test.js'],
transform: {
'\\.js$': 'babel-jest'
},
transformIgnorePatterns: [
'/node_modules/'
]
};
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@
"rv": "^0.1.8",
"rvc": "^0.5.0"
},
"devDependencies": {},
"devDependencies": {
"@babel/core": "^7.29.0",
"babel-jest": "^30.3.0",
"babel-plugin-transform-amd-to-commonjs": "^1.6.0",
"jest": "^30.3.0",
"jest-environment-jsdom": "^30.3.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest"
},
"repository": {
"type": "git",
Expand Down
Loading
Loading