sr-npm 3.1.25 → 3.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -81,6 +81,8 @@ const possibleUrlParams=[
81
81
  "storename",
82
82
  ]
83
83
 
84
+
85
+
84
86
  module.exports = {
85
87
  CAREERS_MULTI_BOXES_PAGE_CONSTS,
86
88
  FiltersIds,
@@ -119,8 +119,10 @@ async function htmlRichContentConverter(sections,richContentConverterToken) {
119
119
  const richContentObject = {}
120
120
  for (const [sectionTitle, sectionData] of Object.entries(sections)) {
121
121
  if (sectionData.text) {
122
+ // Strip span tags but keep their content , since <span> tags paragraphs are deleted by the converter
123
+ const cleanedHtml = sectionData.text.replace(/<\/?span[^>]*>/gi, '');
122
124
  const raw = JSON.stringify({
123
- content: sectionData.text,
125
+ content: cleanedHtml,
124
126
  });
125
127
  const requestOptions = {
126
128
  method: 'post',
@@ -137,7 +139,10 @@ async function htmlRichContentConverter(sections,richContentConverterToken) {
137
139
  );
138
140
  if (response.ok) {
139
141
  const data = await response.json();
140
- const richContentWithSpacing=addSpacingToRichContent(sectionData.text,data.richContent.richContent);
142
+ // Fix list items with nested paragraphs (causes line breaks after bold text)
143
+ const flattenedContent = flattenListItems(data.richContent.richContent);
144
+ // const richContentWithSpacing=addSpacingToRichContent(cleanedHtml,flattenedContent);
145
+ const richContentWithSpacing=addEmptyParagraphsBetweenConsecutive(cleanedHtml,flattenedContent);
141
146
  richContentObject[sectionTitle] = richContentWithSpacing
142
147
  }
143
148
  else {
@@ -148,148 +153,6 @@ async function htmlRichContentConverter(sections,richContentConverterToken) {
148
153
  return richContentObject;
149
154
  }
150
155
 
151
- //Adds empty paragraph nodes between sections in rich content
152
- // to create visual spacing that the Wix RICOS converter strips out
153
- function addSpacingToRichContent(html, richContent) {
154
- if (!richContent || !richContent.nodes) {
155
- return richContent;
156
- }
157
-
158
- // Extract paragraph texts from HTML that end with &#xa0;
159
- const htmlParagraphsWithSpace = [];
160
- // Extract paragraphs with <br> tags
161
- const htmlParagraphsWithBr = new Map(); // text -> array of parts split by <br>
162
-
163
- const pTagRegex = /<p>(.*?)<\/p>/gi;
164
- let match;
165
-
166
- while ((match = pTagRegex.exec(html)) !== null) {
167
- const content = match[1];
168
-
169
- // Check if this paragraph ends with &#xa0; (before closing tags)
170
- if (content.includes('&#xa0;')) {
171
- const textOnly = content.replace(/<[^>]+>/g, '').trim();
172
- htmlParagraphsWithSpace.push(textOnly);
173
- }
174
-
175
- // Check if this paragraph contains <br> tags
176
- if (content.includes('<br>') || content.includes('<br/>') || content.includes('<br />')) {
177
- // Split by <br> tags and extract text parts
178
- const parts = content.split(/<br\s*\/?>/i).map(part =>
179
- part.replace(/<[^>]+>/g, '').trim()
180
- ).filter(part => part.length > 0);
181
-
182
- if (parts.length > 1) {
183
- // Store the parts for this paragraph
184
- const fullText = content.replace(/<[^>]+>/g, '').replace(/\s+/g, '').trim();
185
- htmlParagraphsWithBr.set(fullText, parts);
186
- }
187
- }
188
- }
189
-
190
- const nodes = richContent.nodes;
191
- const newNodes = [];
192
- let nodeIdCounter = 0;
193
-
194
- // Check if a paragraph is bold (has BOLD decoration)
195
- const isBoldParagraph = (node) => {
196
- if (node.type !== 'PARAGRAPH') return false;
197
- const decorations = node.nodes?.[0]?.textData?.decorations || [];
198
- return decorations.some(d => d.type === 'BOLD');
199
- };
200
-
201
- // Check if a paragraph node's text matches one with &#xa0; in HTML
202
- const needsSpacingAfter = (node) => {
203
- if (node.type !== 'PARAGRAPH') return false;
204
-
205
- // Add spacing after bold paragraphs
206
- if (isBoldParagraph(node)) {
207
- return true;
208
- }
209
-
210
- const text = node.nodes?.[0]?.textData?.text || '';
211
- const trimmedText = text.trim();
212
-
213
- // Check if this text matches any HTML paragraph that had &#xa0;
214
- return htmlParagraphsWithSpace.some(htmlText => {
215
- const cleanHtml = htmlText.replace(/&#xa0;/g, ' ').trim();
216
- return trimmedText.includes(cleanHtml) || cleanHtml.includes(trimmedText);
217
- });
218
- };
219
-
220
- // Check if a paragraph contains text that should be split by <br>
221
- const shouldSplitByBr = (node) => {
222
- if (node.type !== 'PARAGRAPH') return null;
223
-
224
- const text = node.nodes?.[0]?.textData?.text || '';
225
- const normalizedText = text.replace(/\s+/g, '').trim();
226
-
227
- // Find matching HTML paragraph with <br>
228
- for (const [htmlText, parts] of htmlParagraphsWithBr.entries()) {
229
- if (normalizedText.includes(htmlText) || htmlText.includes(normalizedText)) {
230
- return parts;
231
- }
232
- }
233
- return null;
234
- };
235
-
236
- // Add spacing after bulleted lists
237
- const isListEnd = (currentNode, nextNode) => {
238
- return currentNode.type === 'BULLETED_LIST' &&
239
- nextNode &&
240
- nextNode.type === 'PARAGRAPH';
241
- };
242
-
243
- for (let i = 0; i < nodes.length; i++) {
244
- const currentNode = nodes[i];
245
- const nextNode = nodes[i + 1];
246
-
247
- // Check if this paragraph should be split by <br>
248
- const brParts = shouldSplitByBr(currentNode);
249
- if (brParts && brParts.length > 1) {
250
- // Split into multiple paragraphs and add spacing between them
251
- const decorations = currentNode.nodes?.[0]?.textData?.decorations || [];
252
-
253
- brParts.forEach((part, idx) => {
254
- newNodes.push({
255
- ...currentNode,
256
- id: `${currentNode.id}_split_${idx}`,
257
- nodes: [{
258
- type: "TEXT",
259
- id: "",
260
- nodes: [],
261
- textData: {
262
- text: part,
263
- decorations: decorations
264
- }
265
- }]
266
- });
267
-
268
- // Add empty paragraph after each split part except the last
269
- if (idx < brParts.length - 1) {
270
- newNodes.push(createEmptyParagraph(`empty_br_${nodeIdCounter++}`));
271
- }
272
- });
273
-
274
- // Add spacing after the split paragraphs if there's a next node
275
- if (nextNode) {
276
- newNodes.push(createEmptyParagraph(`empty_${nodeIdCounter++}`));
277
- }
278
- } else {
279
- newNodes.push(currentNode);
280
-
281
- // Add empty paragraph ONLY after paragraphs with &#xa0; or after lists
282
- if ((needsSpacingAfter(currentNode) || isListEnd(currentNode, nextNode)) && nextNode) {
283
- newNodes.push(createEmptyParagraph(`empty_${nodeIdCounter++}`));
284
- }
285
- }
286
- }
287
-
288
- return {
289
- ...richContent,
290
- nodes: newNodes
291
- };
292
- }
293
156
 
294
157
  function createEmptyParagraph(id) {
295
158
  return {
@@ -314,6 +177,84 @@ function createEmptyParagraph(id) {
314
177
  };
315
178
  }
316
179
 
180
+ // Flattens LIST_ITEM nodes by removing nested PARAGRAPH wrappers
181
+ // Fixes Wix converter bug where bold text + regular text in <li> creates line breaks
182
+ function flattenListItems(richContent) {
183
+ if (!richContent || !richContent.nodes) return richContent;
184
+
185
+ const processNode = (node) => {
186
+ if (node.type === 'BULLETED_LIST' || node.type === 'ORDERED_LIST') {
187
+ return {
188
+ ...node,
189
+ nodes: node.nodes.map(listItem => {
190
+ if (listItem.type !== 'LIST_ITEM') return listItem;
191
+
192
+ // Flatten: extract TEXT nodes from nested PARAGRAPHs
193
+ const flattenedChildren = [];
194
+ for (const child of listItem.nodes) {
195
+ if (child.type === 'PARAGRAPH' && child.nodes) {
196
+ // Pull TEXT nodes out of the PARAGRAPH
197
+ flattenedChildren.push(...child.nodes);
198
+ } else {
199
+ flattenedChildren.push(child);
200
+ }
201
+ }
202
+
203
+ return { ...listItem, nodes: flattenedChildren };
204
+ })
205
+ };
206
+ }
207
+ return node;
208
+ };
209
+
210
+ return {
211
+ ...richContent,
212
+ nodes: richContent.nodes.map(processNode)
213
+ };
214
+ }
215
+
216
+ // Adds empty paragraph nodes between consecutive paragraphs and before lists
217
+ function addEmptyParagraphsBetweenConsecutive(html, richContent) {
218
+ if (!richContent || !richContent.nodes) return richContent;
219
+ const hasConsecutiveParagraphs = /<\/p>\s*<p/i.test(html);
220
+ const hasParagraphBeforeList = /<\/p>\s*<ul/i.test(html);
221
+ const hasParagraphAfterList = /<\/ul>\s*<p/i.test(html);
222
+
223
+ if (!hasConsecutiveParagraphs && !hasParagraphBeforeList && !hasParagraphAfterList) return richContent;
224
+
225
+ const nodes = richContent.nodes;
226
+ const newNodes = [];
227
+ let nodeIdCounter = 0;
228
+
229
+ for (let i = 0; i < nodes.length; i++) {
230
+ const currentNode = nodes[i];
231
+ const nextNode = nodes[i + 1];
232
+
233
+ newNodes.push(currentNode);
234
+
235
+ if (currentNode.type === 'PARAGRAPH' && nextNode) {
236
+ // Add empty paragraph between consecutive paragraphs
237
+ if (hasConsecutiveParagraphs && nextNode.type === 'PARAGRAPH') {
238
+ newNodes.push(createEmptyParagraph(`empty_consecutive_${nodeIdCounter++}`));
239
+ }
240
+ // Add empty paragraph before list
241
+ if (hasParagraphBeforeList && nextNode.type === 'BULLETED_LIST') {
242
+ newNodes.push(createEmptyParagraph(`empty_before_list_${nodeIdCounter++}`));
243
+ }
244
+ }
245
+
246
+ // Add empty paragraph after list
247
+ if (hasParagraphAfterList && currentNode.type === 'BULLETED_LIST' && nextNode && nextNode.type === 'PARAGRAPH') {
248
+ newNodes.push(createEmptyParagraph(`empty_after_list_${nodeIdCounter++}`));
249
+ }
250
+ }
251
+
252
+ return {
253
+ ...richContent,
254
+ nodes: newNodes
255
+ };
256
+ }
257
+
317
258
 
318
259
 
319
260
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sr-npm",
3
- "version": "3.1.25",
3
+ "version": "3.1.27",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,6 +22,7 @@
22
22
  "@wix/essentials": "^0.1.24",
23
23
  "@wix/secrets": "1.0.53",
24
24
  "@wix/site-location": "^1.0.0",
25
+ "@wix/site-seo": "^1.21.0",
25
26
  "@wix/site-window": "^1.0.0",
26
27
  "axios": "^1.11.0",
27
28
  "jest": "^30.0.5",
@@ -1,5 +1,5 @@
1
1
  const { COLLECTIONS,CUSTOM_VALUES_COLLECTION_FIELDS,JOBS_COLLECTION_FIELDS } = require('../backend/collectionConsts');
2
- const { CAREERS_PAGE_SELECTORS, GLOBAL_SECTIONS_SELECTORS } = require('../public/selectors');
2
+ const { CAREERS_PAGE_SELECTORS, GLOBAL_SECTIONS_SELECTORS, SEARCH_RESULTS_SELECTORS, MOBILE_FILTER_BOX_SELECTORS } = require('../public/selectors');
3
3
 
4
4
  const { window } = require('@wix/site-window');
5
5
  const { queryParams,onChange} = require('wix-location-frontend');
@@ -18,7 +18,8 @@ const { groupValuesByField,
18
18
  getFieldByTitle,
19
19
  getCorrectOption,
20
20
  getOptionIndexFromCheckBox,
21
- getAllDatasetItems
21
+ getAllDatasetItems,
22
+ handleSEOTitle
22
23
  } = require('./pagesUtils');
23
24
  const { handlePrimarySearch, queryPrimarySearchResults } = require('../public/primarySearchUtils');
24
25
 
@@ -30,6 +31,7 @@ const countsByFieldId = new Map(); // fieldId -> {valueId: count} map of counts
30
31
  let allfields=[] // all fields in the database
31
32
  let alljobs=[] // all jobs in the database
32
33
  let allvaluesobjects=[] // all values in the database
34
+ let cities=[] // all cities in the database
33
35
  let valueToJobs={} // valueId -> array of jobIds
34
36
  let currentJobs=[] // current jobs that are displayed in the jobs repeater
35
37
  let allsecondarySearchJobs=[] // secondary search results that are displayed in the jobs repeater
@@ -38,7 +40,6 @@ let secondarySearchIsFilled=false // whether the secondary search is filled with
38
40
  let keywordAllJobs; // all jobs that are displayed in the jobs repeater when the keyword is filled
39
41
  let ActivateURLOnchange=true; // whether to activate the url onchange
40
42
  let considerAllJobs=false; // whether to consider all jobs or not
41
-
42
43
  const pagination = {
43
44
  pageSize: 10,
44
45
  currentPage: 1,
@@ -61,32 +62,68 @@ async function careersMultiBoxesPageOnReady(_$w,urlParams) {
61
62
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.CLEAR_ALL_BUTTON_ID).onClick(async () => {
62
63
  await clearAll(_$w);
63
64
  });
64
- if (await window.formFactor() === "Mobile") {
65
- handleFilterInMobile(_$w);
66
- }
65
+
66
+ handleFilterButton(_$w);
67
+
68
+ setInterval(async () => {
69
+ const windowinfo=await window.getBoundingRect();
70
+ if(windowinfo.window.width>1000){
71
+ handleWindowResize(_$w,true);
72
+ }
73
+ else{
74
+ handleWindowResize(_$w);
75
+ }
76
+ }, 600);
77
+
67
78
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.RESULTS_MULTI_STATE_BOX).changeState("results");
68
79
  }
69
80
 
81
+ async function handleWindowResize(_$w,desktop=false) {
82
+ if(desktop){
83
+ MOBILE_FILTER_BOX_SELECTORS.forEach(selector => {
84
+ _$w(selector).expand();
85
+ });
86
+ SEARCH_RESULTS_SELECTORS.forEach(selector => {
87
+ _$w(selector).expand();
88
+ });
89
+ _$w(CAREERS_PAGE_SELECTORS.FILTER_ICON).collapse();
90
+ _$w(CAREERS_PAGE_SELECTORS.EXIT_BUTTON).collapse();
91
+ _$w(CAREERS_PAGE_SELECTORS.REFINE_SEARCH_BUTTON).collapse();
92
+ }
93
+ else{
94
+ if(_$w(CAREERS_PAGE_SELECTORS.FILTER_ICON).collapsed && _$w(CAREERS_PAGE_SELECTORS.EXIT_BUTTON).collapsed && _$w(CAREERS_PAGE_SELECTORS.REFINE_SEARCH_BUTTON).collapsed){
95
+ _$w(CAREERS_PAGE_SELECTORS.FILTER_ICON).expand();
96
+ }
97
+ }
98
+
99
+ }
70
100
  async function handleBackAndForth(_$w){
71
- if(ActivateURLOnchange) {
72
- const newQueryParams=await location.query();
73
- console.log("newQueryParams: ", newQueryParams);
74
- ActivateURLOnchange=false;
75
- await clearAll(_$w,true);
76
- await handleUrlParams(_$w,newQueryParams,true);
77
- ActivateURLOnchange=true;
101
+ if(ActivateURLOnchange) {
102
+ await clearAll(_$w);
103
+ }
104
+ else{
105
+ ActivateURLOnchange=true;
106
+ }
78
107
 
79
- }
80
- else{
81
- ActivateURLOnchange=true;
82
- }
108
+ // if(ActivateURLOnchange) {
109
+ // const newQueryParams=await location.query();
110
+ // console.log("newQueryParams: ", newQueryParams);
111
+ // ActivateURLOnchange=false;
112
+ // await clearAll(_$w,true);
113
+ // await handleUrlParams(_$w,newQueryParams,true);
114
+ // ActivateURLOnchange=true;
115
+
116
+ // }
117
+ // else{
118
+ // ActivateURLOnchange=true;
119
+ // }
83
120
  }
84
121
 
85
122
  async function clearAll(_$w,urlOnChange=false) {
86
- if(selectedByField.size>0 || _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.SECONDARY_SEARCH_INPUT).value || _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).value) {
87
123
 
88
124
  for(const field of allfields) {
89
125
  _$w(`#${FiltersIds[field.title]}CheckBox`).selectedIndices = [];
126
+ _$w(`#${FiltersIds[field.title]}input`).value='';
90
127
  }
91
128
  selectedByField.clear();
92
129
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.SECONDARY_SEARCH_INPUT).value='';
@@ -102,41 +139,26 @@ async function clearAll(_$w,urlOnChange=false) {
102
139
  await updateJobsAndNumbersAndFilters(_$w,true);
103
140
  }
104
141
 
105
- }
106
142
  }
107
143
 
108
- function handleFilterInMobile(_$w) {
109
- const searchResultsSelectors = [
110
- CAREERS_PAGE_SELECTORS.RESULT_BOX,
111
- CAREERS_PAGE_SELECTORS.PAGINATION_BTN,
112
- CAREERS_PAGE_SELECTORS.HEAD_BTNS,
113
- CAREERS_PAGE_SELECTORS.SELECTED_VALUES_REPEATER,
114
- CAREERS_PAGE_SELECTORS.BUTTOM_TXT,
115
- CAREERS_PAGE_SELECTORS.SECTION_24,
116
- CAREERS_PAGE_SELECTORS.SECTION_3,
117
- CAREERS_PAGE_SELECTORS.LINE_3,
118
- CAREERS_PAGE_SELECTORS.FILTER_ICON];
119
-
120
- const mobileFilterBoxSelectors = [
121
- CAREERS_PAGE_SELECTORS.FILTER_BOX,
122
- CAREERS_PAGE_SELECTORS.REFINE_SEARCH_BUTTON,
123
- CAREERS_PAGE_SELECTORS.EXIT_BUTTON,
124
- ];
144
+ async function handleFilterButton(_$w) {
145
+
146
+
125
147
 
126
148
  _$w(CAREERS_PAGE_SELECTORS.FILTER_ICON).onClick(()=>{
127
- mobileFilterBoxSelectors.forEach(selector => {
149
+ MOBILE_FILTER_BOX_SELECTORS.forEach(selector => {
128
150
  _$w(selector).expand();
129
151
  });
130
- searchResultsSelectors.forEach(selector => {
152
+ SEARCH_RESULTS_SELECTORS.forEach(selector => {
131
153
  _$w(selector).collapse();
132
154
  });
133
155
  });
134
156
 
135
157
  const exitFilterBox = () => {
136
- mobileFilterBoxSelectors.forEach(selector => {
158
+ MOBILE_FILTER_BOX_SELECTORS.forEach(selector => {
137
159
  _$w(selector).collapse();
138
160
  });
139
- searchResultsSelectors.forEach(selector => {
161
+ SEARCH_RESULTS_SELECTORS.forEach(selector => {
140
162
  _$w(selector).expand();
141
163
  });
142
164
  }
@@ -150,11 +172,15 @@ function handleFilterInMobile(_$w) {
150
172
  });
151
173
 
152
174
  //onmobile we should collapse the filter box and the refine search button by default
153
- mobileFilterBoxSelectors.forEach(selector => {
175
+ const formFactor = await window.formFactor();
176
+ if(formFactor === "Mobile" || formFactor === "Tablet") {
177
+ MOBILE_FILTER_BOX_SELECTORS.forEach(selector => {
154
178
  _$w(selector).collapse();
155
179
  });
156
180
  }
157
181
 
182
+ }
183
+
158
184
 
159
185
  async function handleUrlParams(_$w,urlParams,handleBackAndForth=false) {
160
186
  try {
@@ -169,6 +195,7 @@ async function handleUrlParams(_$w,urlParams,handleBackAndForth=false) {
169
195
 
170
196
  currentJobs = items;
171
197
  keywordAllJobs = items;
198
+ await handleSEOTitle(`${decodeURIComponent(urlParams.keyword)} Search Results | The Warehouse Group`);
172
199
  }
173
200
 
174
201
  for (const url of possibleUrlParams)
@@ -364,7 +391,7 @@ async function loadJobsRepeater(_$w) {
364
391
  async function loadFilters(_$w) {
365
392
  try {
366
393
  // 1) Load all categories (fields)
367
- const cities = await getAllRecords(COLLECTIONS.CITIES);
394
+ cities = await getAllRecords(COLLECTIONS.CITIES);
368
395
  for(const city of cities) {
369
396
  valueToJobs[city._id] = city.jobIds;
370
397
  }
@@ -400,6 +427,7 @@ async function loadJobsRepeater(_$w) {
400
427
 
401
428
  _$w(`#${FiltersIds[field.title]}CheckBox`).selectedIndices = []; // start empty
402
429
  _$w(`#${FiltersIds[field.title]}CheckBox`).onChange(async (ev) => {
430
+
403
431
  dontUpdateThisCheckBox=field._id;
404
432
  const selected = ev.target.value; // array of selected value IDs
405
433
  let fieldTitle=field.title.toLowerCase().replace(' ', '');
@@ -480,8 +508,13 @@ function getValueFromValueId(valueIds, value) {
480
508
  {
481
509
  const selectedFieldId=Array.from( selectedByField.keys() )[0]
482
510
  if(selectedFieldId===fieldId) {
511
+ if(selectedFieldId==="Location") {
512
+ countsMap = new Map(cities.map(city=>[city._id, city.count]));
513
+ }
514
+ else{
483
515
  const relevantFields=allvaluesobjects.filter(val=>val.customField===selectedFieldId)
484
516
  countsMap = new Map(relevantFields.map(val=>[val.valueId, val.count]));
517
+ }
485
518
  considerAllJobs=false;
486
519
  }
487
520
  }
@@ -518,11 +551,7 @@ function getValueFromValueId(valueIds, value) {
518
551
 
519
552
  // Sort alphabetically by label
520
553
  filtered.sort((a, b) => (a.label || '').localeCompare(b.label || ''));
521
- // Preserve currently selected values that are still visible
522
- // let prevSelected=[]
523
- // clearAll? prevSelected=[]:prevSelected= _$w(`#${FiltersIds[fieldTitle]}CheckBox`).value;
524
554
  const visibleSet = new Set(filtered.map(o => o.value));
525
- //const preserved = prevSelected.filter(v => visibleSet.has(v));
526
555
  if(filtered.length===0) {
527
556
  _$w(`#${FiltersIds[fieldTitle]}MultiBox`).changeState(`${FiltersIds[fieldTitle]}NoResults`);
528
557
  }
@@ -591,11 +620,14 @@ function getValueFromValueId(valueIds, value) {
591
620
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationTotalCountText).text = secondarySearchIsFilled? Math.ceil(currentSecondarySearchJobs.length/pagination.pageSize).toString():Math.ceil(currentJobs.length/pagination.pageSize).toString();
592
621
  if(jobsFirstPage.length===0) {
593
622
  await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX).changeState("noJobs");
623
+ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText).text = "0";
624
+ pagination.currentPage=0;
594
625
  }
595
626
  else{
596
627
  await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX).changeState("searchResult");
628
+ pagination.currentPage=1;
597
629
  }
598
- pagination.currentPage=1;
630
+
599
631
  handlePaginationButtons(_$w);
600
632
  }
601
633
 
@@ -603,7 +635,7 @@ function handlePaginationButtons(_$w)
603
635
  {
604
636
  handlePageUrlParam();
605
637
 
606
- pagination.currentPage===1? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).disable():_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).enable();
638
+ pagination.currentPage===1 || pagination.currentPage===0? _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).disable():_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).enable();
607
639
  if(secondarySearchIsFilled) {
608
640
  if(currentSecondarySearchJobs.length===0) {
609
641
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_NEXT).disable();
@@ -622,9 +654,8 @@ function handlePaginationButtons(_$w)
622
654
 
623
655
  function handlePageUrlParam() {
624
656
  ActivateURLOnchange=false;
625
- if(pagination.currentPage==1)
657
+ if(pagination.currentPage==1 || pagination.currentPage==0)
626
658
  {
627
-
628
659
  queryParams.remove(["page"]);
629
660
  }
630
661
  else{
@@ -704,6 +735,8 @@ async function secondarySearch(_$w,query) {
704
735
 
705
736
  if(jobsFirstPage.length===0) {
706
737
  await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX).changeState("noJobs");
738
+ _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText).text = "0";
739
+ pagination.currentPage=0;
707
740
  }
708
741
  else{
709
742
  await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_MULTI_STATE_BOX).changeState("searchResult");
@@ -730,6 +763,7 @@ async function secondarySearch(_$w,query) {
730
763
  }
731
764
 
732
765
 
766
+
733
767
  module.exports = {
734
768
  careersMultiBoxesPageOnReady,
735
769
  secondarySearch
@@ -1,7 +1,7 @@
1
1
  const { items: wixData } = require('@wix/data');
2
2
  const { JOBS_COLLECTION_FIELDS,COLLECTIONS } = require('../backend/collectionConsts');
3
3
  const { normalizeString } = require('../backend/utils');
4
-
4
+ const { seo } = require('@wix/site-seo');
5
5
  function groupValuesByField(values, refKey) {
6
6
  const map = new Map();
7
7
  for (const v of values) {
@@ -106,6 +106,11 @@ async function getLatestJobsByValue(Value) {
106
106
  return latestJobs;
107
107
  }
108
108
 
109
+ async function handleSEOTitle(title) {
110
+ await seo.setTitle(title);
111
+
112
+ }
113
+
109
114
  module.exports = {
110
115
  groupValuesByField,
111
116
  debounce,
@@ -117,5 +122,6 @@ module.exports = {
117
122
  getLatestJobsByValue,
118
123
  getValueFromValueId,
119
124
  getAllRecordsWithoutMultiRef,
120
- getAllDatasetItems
125
+ getAllDatasetItems,
126
+ handleSEOTitle
121
127
  }
@@ -50,8 +50,27 @@ const FILTER_FIELDS = {
50
50
  SEARCH: 'title',
51
51
  }
52
52
 
53
+
54
+ const SEARCH_RESULTS_SELECTORS = [
55
+ CAREERS_PAGE_SELECTORS.RESULT_BOX,
56
+ CAREERS_PAGE_SELECTORS.PAGINATION_BTN,
57
+ CAREERS_PAGE_SELECTORS.HEAD_BTNS,
58
+ CAREERS_PAGE_SELECTORS.SELECTED_VALUES_REPEATER,
59
+ CAREERS_PAGE_SELECTORS.BUTTOM_TXT,
60
+ CAREERS_PAGE_SELECTORS.SECTION_24,
61
+ CAREERS_PAGE_SELECTORS.SECTION_3,
62
+ CAREERS_PAGE_SELECTORS.LINE_3,
63
+ CAREERS_PAGE_SELECTORS.FILTER_ICON];
64
+
65
+ const MOBILE_FILTER_BOX_SELECTORS = [
66
+ CAREERS_PAGE_SELECTORS.FILTER_BOX,
67
+ CAREERS_PAGE_SELECTORS.REFINE_SEARCH_BUTTON,
68
+ CAREERS_PAGE_SELECTORS.EXIT_BUTTON,
69
+ ];
53
70
  module.exports = {
54
71
  CAREERS_PAGE_SELECTORS,
55
72
  GLOBAL_SECTIONS_SELECTORS,
56
73
  FILTER_FIELDS,
74
+ SEARCH_RESULTS_SELECTORS,
75
+ MOBILE_FILTER_BOX_SELECTORS,
57
76
  }