sr-npm 1.7.573 → 1.7.575
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.
|
@@ -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
|
@@ -1,86 +1,75 @@
|
|
|
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');
|
|
1
4
|
|
|
2
|
-
|
|
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();
|
|
3
9
|
|
|
4
10
|
async function careersMultiBoxesPageOnReady(_$w) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
console.log("careersMultiBoxesPageOnReady");
|
|
8
|
-
|
|
11
|
+
await loadJobs(_$w);
|
|
12
|
+
await loadFilters(_$w);
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
async function loadJobs(_$w) {
|
|
12
|
-
_$w(
|
|
13
|
-
$item(
|
|
14
|
-
$item(
|
|
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
|
|
15
19
|
});
|
|
16
20
|
|
|
17
21
|
return wixData.query(COLLECTIONS.JOBS)
|
|
18
22
|
.find()
|
|
19
23
|
.then((res) => {
|
|
20
|
-
$w(
|
|
24
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.JOBS_REPEATER).data = res.items;
|
|
21
25
|
})
|
|
22
26
|
.catch((err) => {
|
|
23
27
|
console.error('Failed to load jobs:', err);
|
|
24
28
|
});
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
async function loadFilters() {
|
|
31
|
+
async function loadFilters(_$w) {
|
|
28
32
|
try {
|
|
29
|
-
|
|
30
33
|
// 1) Load all categories (fields)
|
|
31
|
-
const fields = await getAllRecords(
|
|
32
|
-
$w(
|
|
34
|
+
const fields = await getAllRecords(COLLECTIONS.CUSTOM_FIELDS);
|
|
35
|
+
_$w(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_REPEATER).data = fields;
|
|
33
36
|
|
|
34
37
|
// 2) Load all values once and group them by referenced field
|
|
35
|
-
const values = await getAllRecords(
|
|
36
|
-
const valuesByFieldId = groupValuesByField(values,
|
|
38
|
+
const values = await getAllRecords(COLLECTIONS.CUSTOM_VALUES);
|
|
39
|
+
const valuesByFieldId = groupValuesByField(values, CUSTOM_VALUES_COLLECTION_FIELDS.CUSTOM_FIELD);
|
|
37
40
|
valuesByFieldIdGlobal = valuesByFieldId; // store globally
|
|
38
41
|
|
|
39
|
-
// Simple debounce helper so we don't re-render on every keystroke
|
|
40
|
-
const debounce = (fn, ms = 150) => {
|
|
41
|
-
let t;
|
|
42
|
-
return (...args) => {
|
|
43
|
-
clearTimeout(t);
|
|
44
|
-
t = setTimeout(() => fn(...args), ms);
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
42
|
|
|
48
43
|
// 3) Bind each filter repeater item
|
|
49
|
-
$w(
|
|
50
|
-
$item(
|
|
51
|
-
$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()
|
|
52
47
|
})
|
|
53
48
|
const fieldId = itemData._id;
|
|
54
49
|
|
|
55
50
|
// Set the filter label (category name)
|
|
56
|
-
|
|
57
|
-
const label = itemData.title || itemData.name || itemData.label || 'Filter';
|
|
58
|
-
$item(FILTER_LABEL_ID).placeholder = label;
|
|
51
|
+
$item(CAREERS_MULTI_BOXES_PAGE_CONSTS.FILTER_LABEL).placeholder = itemData.title
|
|
59
52
|
|
|
60
53
|
// Build CheckboxGroup options for this field
|
|
61
54
|
const fieldValues = valuesByFieldId.get(fieldId) || [];
|
|
62
|
-
console.log("fieldValues : ",fieldValues)
|
|
63
55
|
const originalOptions = fieldValues.map(v => ({
|
|
64
56
|
label: v.title ,
|
|
65
57
|
value: v._id
|
|
66
58
|
}));
|
|
67
|
-
console.log("options: ",originalOptions)
|
|
68
59
|
optionsByFieldId.set(fieldId, originalOptions);
|
|
69
60
|
const counter={}
|
|
70
61
|
for (const val of fieldValues) {
|
|
71
|
-
const result=await wixData.queryReferenced(
|
|
72
|
-
console.log("result: ",result)
|
|
62
|
+
const result=await wixData.queryReferenced(COLLECTIONS.CUSTOM_VALUES, val, CUSTOM_VALUES_COLLECTION_FIELDS.MULTI_REF_JOBS_CUSTOM_VALUES)
|
|
73
63
|
counter[val.title]=result._totalCount
|
|
74
64
|
}
|
|
75
|
-
console.log("counter: ",counter)
|
|
76
65
|
countsByFieldId.set(fieldId, new Map(originalOptions.map(o => [o.value, counter[o.label]])));
|
|
77
66
|
|
|
78
67
|
// Initialize UI
|
|
79
68
|
updateOptionsUI($item, fieldId, ''); // no search query
|
|
80
69
|
|
|
81
70
|
//$item(CHECKBOX_GROUP_ID).options = originalOptions;
|
|
82
|
-
$item(
|
|
83
|
-
$item(
|
|
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) => {
|
|
84
73
|
const selected = ev.target.value; // array of selected value IDs
|
|
85
74
|
if (selected && selected.length) {
|
|
86
75
|
selectedByField.set(fieldId, selected);
|
|
@@ -91,24 +80,7 @@ async function loadJobs(_$w) {
|
|
|
91
80
|
refreshFacetCounts(); // recompute and update counts in all lists
|
|
92
81
|
|
|
93
82
|
});
|
|
94
|
-
|
|
95
83
|
|
|
96
|
-
// $item(FILTER_LABEL_ID).onInput(() => {
|
|
97
|
-
// const query = ($item(FILTER_LABEL_ID).value || '').toLowerCase().trim();
|
|
98
|
-
// const base = optionsByFieldId.get(fieldId) || [];
|
|
99
|
-
// const filtered = query
|
|
100
|
-
// ? base.filter(o => (o.label || '').toLowerCase().includes(query))
|
|
101
|
-
// : base.slice();
|
|
102
|
-
|
|
103
|
-
// // Preserve selections that are still visible
|
|
104
|
-
// const prevSelected = $item(CHECKBOX_GROUP_ID).value || [];
|
|
105
|
-
// const visibleValues = new Set(filtered.map(o => o.value));
|
|
106
|
-
// const preserved = prevSelected.filter(v => visibleValues.has(v));
|
|
107
|
-
|
|
108
|
-
// $item(CHECKBOX_GROUP_ID).options = filtered;
|
|
109
|
-
// $item(CHECKBOX_GROUP_ID).value = preserved; // do NOT call applyJobFilters here
|
|
110
|
-
// });
|
|
111
|
-
|
|
112
84
|
// Input typing -> only filter this list’s visible options (no Jobs query)
|
|
113
85
|
const runFilter = debounce(() => {
|
|
114
86
|
const query = ($item(FILTER_LABEL_ID).value || '').toLowerCase().trim();
|
|
@@ -130,6 +102,129 @@ async function loadJobs(_$w) {
|
|
|
130
102
|
}
|
|
131
103
|
}
|
|
132
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
|
+
}
|
|
133
228
|
|
|
134
229
|
|
|
135
230
|
|
package/pages/careersPage.js
CHANGED
|
@@ -25,7 +25,7 @@ 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];
|