sr-npm 3.1.22 → 3.1.24

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.
package/backend/data.js CHANGED
@@ -463,14 +463,18 @@ function fetchJobLocation(jobDetails) {
463
463
 
464
464
  async function createCollections() {
465
465
  console.log("Creating collections");
466
+ if(siteconfig===undefined) {
467
+ await getSiteConfig();
468
+ }
469
+
466
470
  await Promise.all(
467
471
  [createCollectionIfMissing(COLLECTIONS.JOBS, COLLECTIONS_FIELDS.JOBS,{ insert: 'ADMIN', update: 'ADMIN', remove: 'ADMIN', read: 'ANYONE' }),
468
472
  createCollectionIfMissing(COLLECTIONS.CITIES, COLLECTIONS_FIELDS.CITIES),
469
473
  createCollectionIfMissing(COLLECTIONS.AMOUNT_OF_JOBS_PER_DEPARTMENT, COLLECTIONS_FIELDS.AMOUNT_OF_JOBS_PER_DEPARTMENT),
470
474
  createCollectionIfMissing(COLLECTIONS.SECRET_MANAGER_MIRROR, COLLECTIONS_FIELDS.SECRET_MANAGER_MIRROR),
471
475
  createCollectionIfMissing(COLLECTIONS.BRANDS, COLLECTIONS_FIELDS.BRANDS),
472
- createCollectionIfMissing(COLLECTIONS.CUSTOM_VALUES, COLLECTIONS_FIELDS.CUSTOM_VALUES),
473
- createCollectionIfMissing(COLLECTIONS.CUSTOM_FIELDS, COLLECTIONS_FIELDS.CUSTOM_FIELDS)
476
+ siteconfig.customFields==="true" ? createCollectionIfMissing(COLLECTIONS.CUSTOM_VALUES, COLLECTIONS_FIELDS.CUSTOM_VALUES) : null,
477
+ siteconfig.customFields==="true" ? createCollectionIfMissing(COLLECTIONS.CUSTOM_FIELDS, COLLECTIONS_FIELDS.CUSTOM_FIELDS) : null
474
478
  ]);
475
479
  console.log("finished creating Collections");
476
480
  }
@@ -528,13 +532,16 @@ async function syncJobsFast() {
528
532
 
529
533
  async function clearCollections() {
530
534
  console.log("clearing collections");
535
+ if(siteconfig===undefined) {
536
+ await getSiteConfig();
537
+ }
531
538
  await Promise.all([
532
539
  wixData.truncate(COLLECTIONS.CITIES),
533
540
  wixData.truncate(COLLECTIONS.AMOUNT_OF_JOBS_PER_DEPARTMENT),
534
541
  wixData.truncate(COLLECTIONS.JOBS),
535
542
  wixData.truncate(COLLECTIONS.BRANDS),
536
- wixData.truncate(COLLECTIONS.CUSTOM_VALUES),
537
- wixData.truncate(COLLECTIONS.CUSTOM_FIELDS),
543
+ siteconfig.customFields==="true" ? wixData.truncate(COLLECTIONS.CUSTOM_VALUES) : null,
544
+ siteconfig.customFields==="true" ? wixData.truncate(COLLECTIONS.CUSTOM_FIELDS) : null,
538
545
  ]);
539
546
  console.log("cleared collections successfully");
540
547
  }
@@ -115,6 +115,7 @@ async function fetchJobDescription(jobId,testObject=undefined) {
115
115
  }
116
116
 
117
117
  async function htmlRichContentConverter(sections,richContentConverterToken) {
118
+
118
119
  const richContentObject = {}
119
120
  for (const [sectionTitle, sectionData] of Object.entries(sections)) {
120
121
  if (sectionData.text) {
@@ -136,7 +137,8 @@ async function htmlRichContentConverter(sections,richContentConverterToken) {
136
137
  );
137
138
  if (response.ok) {
138
139
  const data = await response.json();
139
- richContentObject[sectionTitle] = data.richContent.richContent;
140
+ const richContentWithSpacing=addSpacingToRichContent(sectionData.text,data.richContent.richContent);
141
+ richContentObject[sectionTitle] = richContentWithSpacing
140
142
  }
141
143
  else {
142
144
  throw new Error("Error converting html to rich content response: "+response);
@@ -146,6 +148,178 @@ async function htmlRichContentConverter(sections,richContentConverterToken) {
146
148
  return richContentObject;
147
149
  }
148
150
 
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  
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
+
294
+ function createEmptyParagraph(id) {
295
+ return {
296
+ type: "PARAGRAPH",
297
+ id: id,
298
+ nodes: [
299
+ {
300
+ type: "TEXT",
301
+ id: "",
302
+ nodes: [],
303
+ textData: {
304
+ text: "",
305
+ decorations: []
306
+ }
307
+ }
308
+ ],
309
+ paragraphData: {
310
+ textStyle: {
311
+ textAlignment: "AUTO"
312
+ }
313
+ }
314
+ };
315
+ }
316
+
317
+
318
+
319
+
320
+
321
+
322
+
149
323
 
150
324
 
151
325
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sr-npm",
3
- "version": "3.1.22",
3
+ "version": "3.1.24",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -253,6 +253,7 @@ async function handleParams(_$w,param,values) {
253
253
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText).text = pagination.currentPage.toString();
254
254
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = nextPageJobs;
255
255
  handlePaginationButtons(_$w);
256
+ await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).scrollTo();
256
257
  });
257
258
 
258
259
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PAGE_BUTTON_PREVIOUS).onClick(async () => {
@@ -261,6 +262,7 @@ async function handleParams(_$w,param,values) {
261
262
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.paginationCurrentText).text = pagination.currentPage.toString();
262
263
  _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = previousPageJobs;
263
264
  handlePaginationButtons(_$w);
265
+ await _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.PRIMARY_SEARCH_INPUT).scrollTo();
264
266
  });
265
267
  } catch (error) {
266
268
  console.error('Failed to load pagination buttons:', error);
@@ -482,6 +484,8 @@ function getValueFromValueId(valueIds, value) {
482
484
  ? withCounts.filter(o => (o.label || '').toLowerCase().includes(searchQuery))
483
485
  : withCounts;
484
486
 
487
+ // Sort alphabetically by label
488
+ filtered.sort((a, b) => (a.label || '').localeCompare(b.label || ''));
485
489
  // Preserve currently selected values that are still visible
486
490
  // let prevSelected=[]
487
491
  // clearAll? prevSelected=[]:prevSelected= _$w(`#${FiltersIds[fieldTitle]}CheckBox`).value;