sr-npm 1.7.572 → 1.7.574
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/careersMultiBoxesPageIds.js +14 -0
- package/backend/index.js +1 -0
- package/package.json +1 -1
- package/pages/careersMultiBoxesPage.js +233 -0
- package/pages/careersPage.js +8 -4
- package/pages/index.js +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const CAREERS_MULTI_BOXES_PAGE_CONSTS={
|
|
2
|
+
FILTER_REPEATER: '#filterReapter',
|
|
3
|
+
JOBS_REPEATER: '#jobsReapter',
|
|
4
|
+
JOBS_REPEATER_ITEM_TITLE: '#jobTitle',
|
|
5
|
+
JOBS_REPEATER_ITEM_LOCATION: '#locationLabel',
|
|
6
|
+
FILTER_LABEL: '#FilterTextInput',
|
|
7
|
+
FILTER_CHECKBOX_CONTAINER: '#FilterCheckBoxContainer',
|
|
8
|
+
FILTER_REPEATER_ITEM_CHECKBOX: '#filterCheckBox',
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = {
|
|
13
|
+
CAREERS_MULTI_BOXES_PAGE_CONSTS,
|
|
14
|
+
}
|
package/backend/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
const { COLLECTIONS,CUSTOM_VALUES_COLLECTION_FIELDS,JOBS_COLLECTION_FIELDS } = require('../backend/collectionConsts');
|
|
2
|
+
const { items: wixData } = require('@wix/data');
|
|
3
|
+
const {CAREERS_MULTI_BOXES_PAGE_CONSTS} = require('../backend/careersMultiBoxesPageIds');
|
|
4
|
+
|
|
5
|
+
let valuesByFieldIdGlobal = null;
|
|
6
|
+
const selectedByField = new Map(); // fieldId -> array of selected value IDs
|
|
7
|
+
const optionsByFieldId = new Map(); // fieldId -> [{label, value}]
|
|
8
|
+
const countsByFieldId = new Map();
|
|
9
|
+
|
|
10
|
+
async function careersMultiBoxesPageOnReady(_$w) {
|
|
11
|
+
await loadJobs(_$w);
|
|
12
|
+
await loadFilters(_$w);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function loadJobs(_$w) {
|
|
16
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).onItemReady(($item, itemData) => {
|
|
17
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_TITLE).text = itemData.title || '';
|
|
18
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER_ITEM_LOCATION).text=itemData.location.fullLocation
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return wixData.query(COLLECTIONS.JOBS)
|
|
22
|
+
.find()
|
|
23
|
+
.then((res) => {
|
|
24
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = res.items;
|
|
25
|
+
})
|
|
26
|
+
.catch((err) => {
|
|
27
|
+
console.error('Failed to load jobs:', err);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function loadFilters() {
|
|
32
|
+
try {
|
|
33
|
+
// 1) Load all categories (fields)
|
|
34
|
+
const fields = await getAllRecords(COLLECTIONS.CUSTOM_FIELDS);
|
|
35
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER).data = fields;
|
|
36
|
+
|
|
37
|
+
// 2) Load all values once and group them by referenced field
|
|
38
|
+
const values = await getAllRecords(COLLECTIONS.CUSTOM_VALUES);
|
|
39
|
+
const valuesByFieldId = groupValuesByField(values, CUSTOM_VALUES_COLLECTION_FIELDS.CUSTOM_FIELD);
|
|
40
|
+
valuesByFieldIdGlobal = valuesByFieldId; // store globally
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// 3) Bind each filter repeater item
|
|
44
|
+
$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER).onItemReady(async ($item, itemData) => {
|
|
45
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_LABEL).onClick(()=>{
|
|
46
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_CHECKBOX_CONTAINER).collapsed ? $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_CHECKBOX_CONTAINER).expand() : $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_CHECKBOX_CONTAINER).collapse()
|
|
47
|
+
})
|
|
48
|
+
const fieldId = itemData._id;
|
|
49
|
+
|
|
50
|
+
// Set the filter label (category name)
|
|
51
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_LABEL).placeholder = itemData.title
|
|
52
|
+
|
|
53
|
+
// Build CheckboxGroup options for this field
|
|
54
|
+
const fieldValues = valuesByFieldId.get(fieldId) || [];
|
|
55
|
+
const originalOptions = fieldValues.map(v => ({
|
|
56
|
+
label: v.title ,
|
|
57
|
+
value: v._id
|
|
58
|
+
}));
|
|
59
|
+
optionsByFieldId.set(fieldId, originalOptions);
|
|
60
|
+
const counter={}
|
|
61
|
+
for (const val of fieldValues) {
|
|
62
|
+
const result=await wixData.queryReferenced(COLLECTIONS.CUSTOM_VALUES, val, CUSTOM_VALUES_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES)
|
|
63
|
+
counter[val.title]=result._totalCount
|
|
64
|
+
}
|
|
65
|
+
countsByFieldId.set(fieldId, new Map(originalOptions.map(o => [o.value, counter[o.label]])));
|
|
66
|
+
|
|
67
|
+
// Initialize UI
|
|
68
|
+
updateOptionsUI($item, fieldId, ''); // no search query
|
|
69
|
+
|
|
70
|
+
//$item(CHECKBOX_GROUP_ID).options = originalOptions;
|
|
71
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER_ITEM_CHECKBOX).selectedIndices = []; // start empty
|
|
72
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER_ITEM_CHECKBOX).onChange((ev) => {
|
|
73
|
+
const selected = ev.target.value; // array of selected value IDs
|
|
74
|
+
if (selected && selected.length) {
|
|
75
|
+
selectedByField.set(fieldId, selected);
|
|
76
|
+
} else {
|
|
77
|
+
selectedByField.delete(fieldId);
|
|
78
|
+
}
|
|
79
|
+
applyJobFilters(); // re-query jobs
|
|
80
|
+
refreshFacetCounts(); // recompute and update counts in all lists
|
|
81
|
+
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Input typing -> only filter this list’s visible options (no Jobs query)
|
|
85
|
+
const runFilter = debounce(() => {
|
|
86
|
+
const query = ($item(FILTER_LABEL_ID).value || '').toLowerCase().trim();
|
|
87
|
+
updateOptionsUI($item, fieldId, query);
|
|
88
|
+
}, 150);
|
|
89
|
+
$item(FILTER_LABEL_ID).onInput(runFilter);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
await refreshFacetCounts();
|
|
93
|
+
// After counts are ready, re-render all items to show numbers
|
|
94
|
+
$w(FILTER_REPEATER_ID).forEachItem(($item, itemData) => {
|
|
95
|
+
const query = ($item(FILTER_LABEL_ID).value || '').toLowerCase().trim();
|
|
96
|
+
updateOptionsUI($item, itemData._id, query);
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
});
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error('Failed to load filters:', err);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async function getAllRecords(collectionId) {
|
|
107
|
+
let q = wixData.query(collectionId);
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
const items = [];
|
|
111
|
+
let res = await q.limit(1000).find();
|
|
112
|
+
items.push(...res.items);
|
|
113
|
+
|
|
114
|
+
while (res.hasNext()) {
|
|
115
|
+
res = await res.next();
|
|
116
|
+
items.push(...res.items);
|
|
117
|
+
}
|
|
118
|
+
return items;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const debounce = (fn, ms = 150) => {
|
|
122
|
+
let t;
|
|
123
|
+
return (...args) => {
|
|
124
|
+
clearTimeout(t);
|
|
125
|
+
t = setTimeout(() => fn(...args), ms);
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
function updateOptionsUI($item, fieldId, searchQuery) {
|
|
130
|
+
const base = optionsByFieldId.get(fieldId) || [];
|
|
131
|
+
const countsMap = countsByFieldId.get(fieldId) || new Map();
|
|
132
|
+
// Build display options with counts
|
|
133
|
+
const withCounts = base.map(o => {
|
|
134
|
+
const count = countsMap.get(o.value) || 0;
|
|
135
|
+
return {
|
|
136
|
+
label: `${o.label} (${count})`,
|
|
137
|
+
value: o.value
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Apply search
|
|
142
|
+
const filtered = searchQuery
|
|
143
|
+
? withCounts.filter(o => (o.label || '').toLowerCase().includes(searchQuery))
|
|
144
|
+
: withCounts;
|
|
145
|
+
|
|
146
|
+
// Preserve currently selected values that are still visible
|
|
147
|
+
const prevSelected = $item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER_ITEM_CHECKBOX).value || [];
|
|
148
|
+
const visibleSet = new Set(filtered.map(o => o.value));
|
|
149
|
+
const preserved = prevSelected.filter(v => visibleSet.has(v));
|
|
150
|
+
|
|
151
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER_ITEM_CHECKBOX).options = filtered;
|
|
152
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER_ITEM_CHECKBOX).value = preserved;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function applyJobFilters(filterByField) {
|
|
156
|
+
let q = wixData.query(COLLECTIONS.JOBS)
|
|
157
|
+
|
|
158
|
+
// AND across categories, OR within each category
|
|
159
|
+
for (const [, values] of selectedByField.entries()) {
|
|
160
|
+
if (values && values.length) {
|
|
161
|
+
q = q.hasSome(filterByField, values);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
q.find()
|
|
166
|
+
.then((res) => { _$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = res.items; })
|
|
167
|
+
.catch((err) => { console.error('Failed to filter jobs:', err); });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
async function refreshFacetCounts() {
|
|
172
|
+
if (!valuesByFieldIdGlobal)
|
|
173
|
+
{
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const fieldIds = Array.from(optionsByFieldId.keys());
|
|
178
|
+
// Run per-field queries in parallel
|
|
179
|
+
const tasks = fieldIds.map(async (fieldId) => {
|
|
180
|
+
// Build query with selections from all other fields
|
|
181
|
+
let q = wixData.query(COLLECTIONS.JOBS);
|
|
182
|
+
for (const [fid, values] of selectedByField.entries()) {
|
|
183
|
+
if (fid !== fieldId && values && values.length) {
|
|
184
|
+
q = q.hasSome(JOBS_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES, values);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Fetch all matching jobs (paged)
|
|
189
|
+
const jobs = await findAll(q);
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
// Prepare a set of valid option IDs for this field
|
|
193
|
+
const options = optionsByFieldId.get(fieldId) || [];
|
|
194
|
+
const optionSet = new Set(options.map(o => o.value));
|
|
195
|
+
|
|
196
|
+
// Tally counts
|
|
197
|
+
const counts = new Map(); // valueId -> count
|
|
198
|
+
for (const job of jobs) {
|
|
199
|
+
const referencedfield= await wixData.queryReferenced(COLLECTIONS.JOBS, job, JOBS_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES)
|
|
200
|
+
const vals = referencedfield._items
|
|
201
|
+
//const vals = job[JOB_VALUES_FIELD] || [];
|
|
202
|
+
for (const val of vals) {
|
|
203
|
+
if (optionSet.has(val._id)) {
|
|
204
|
+
counts.set(val._id, (counts.get(val._id) || 0) + 1);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Ensure every option has a count (zero if absent)
|
|
211
|
+
for (const o of options) {
|
|
212
|
+
if (!counts.has(o.value))
|
|
213
|
+
{
|
|
214
|
+
counts.set(o.value, 0);}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
countsByFieldId.set(fieldId, counts);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
await Promise.all(tasks);
|
|
221
|
+
|
|
222
|
+
// After counts are ready, update all items currently rendered
|
|
223
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER).forEachItem(($item, itemData) => {
|
|
224
|
+
const query = ($item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_LABEL).value || '').toLowerCase().trim();
|
|
225
|
+
updateOptionsUI($item, itemData._id, query);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
module.exports = {
|
|
232
|
+
careersMultiBoxesPageOnReady
|
|
233
|
+
};
|
package/pages/careersPage.js
CHANGED
|
@@ -4,7 +4,7 @@ const { window } = require('@wix/site-window');
|
|
|
4
4
|
const { query,queryParams,onChange} = require("wix-location-frontend");
|
|
5
5
|
const { location } = require("@wix/site-location");
|
|
6
6
|
const { COLLECTIONS } = require('../backend/collectionConsts');
|
|
7
|
-
|
|
7
|
+
const { careersMultiBoxesPageOnReady } = require('./careersMultiBoxesPage');
|
|
8
8
|
const {
|
|
9
9
|
debounce,
|
|
10
10
|
getFilter,
|
|
@@ -25,11 +25,15 @@ const {
|
|
|
25
25
|
let searchInputBlurredFirstTime=true;
|
|
26
26
|
let siteconfig;
|
|
27
27
|
|
|
28
|
-
async function careersPageOnReady(_$w,thisObject,queryParams) {
|
|
28
|
+
async function careersPageOnReady(_$w,thisObject=null,queryParams=null) {
|
|
29
29
|
if(siteconfig===undefined) {
|
|
30
30
|
const queryResult = await wixData.query(COLLECTIONS.SITE_CONFIGS).find();
|
|
31
31
|
siteconfig = queryResult.items[0];
|
|
32
32
|
}
|
|
33
|
+
if(siteconfig.customFields==="true") {
|
|
34
|
+
await careersMultiBoxesPageOnReady(_$w);
|
|
35
|
+
}
|
|
36
|
+
else{
|
|
33
37
|
console.log("queryParams: ", queryParams);
|
|
34
38
|
const { page, keyWord, department, location,jobType,brand } = queryParams;
|
|
35
39
|
queryPageVar=page;
|
|
@@ -46,7 +50,7 @@ await init(_$w);
|
|
|
46
50
|
await handleBrandDropdown(_$w);
|
|
47
51
|
await handleUrlParams(_$w);
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
}
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
|
|
@@ -510,7 +514,7 @@ async function handleBrandDropdown(_$w){
|
|
|
510
514
|
console.log("showing brand dropdown");
|
|
511
515
|
_$w('#dropdownBrand').show();
|
|
512
516
|
}
|
|
513
|
-
}
|
|
517
|
+
}
|
|
514
518
|
module.exports = {
|
|
515
519
|
careersPageOnReady,
|
|
516
520
|
};
|