When an Owner is selected, the Customer filter options will update to show the corresponding customers, and vice versa
This commit is contained in:
40
dist/chromium/content.js
vendored
40
dist/chromium/content.js
vendored
@@ -2601,6 +2601,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -2661,6 +2662,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7053,21 +7055,35 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
}
|
||||
|
||||
// Keep stored selections intact: narrowing a menu must not turn an implicit
|
||||
// "all" into a second filter that prevents expanding the original selection.
|
||||
function getAvailableCustomerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allOwners = getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key));
|
||||
return getCustomerOptions(allOwners ? items : items.filter(item => opportunitiesFilterState.selectedOwnerKeys.has(getOwnerKey(item))));
|
||||
}
|
||||
|
||||
function getAvailableOwnerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allCustomers = getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key));
|
||||
return getOwnerOptions(allCustomers ? items : items.filter(item => opportunitiesFilterState.selectedCustomerKeys.has(getCustomerKey(item))));
|
||||
}
|
||||
|
||||
function renderCustomerFilter() {
|
||||
const trigger = document.getElementById(CUSTOMER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(CUSTOMER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(CUSTOMER_FILTER_SELECT_ALL_ID);
|
||||
const customerOptions = getCustomerOptions();
|
||||
const customerOptions = getAvailableCustomerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = customerOptions.filter((customer) => opportunitiesFilterState.selectedCustomerKeys.has(customer.key)).length;
|
||||
trigger.disabled = customerOptions.length === 0;
|
||||
trigger.disabled = getCustomerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(customerOptions.length, selectedCount);
|
||||
searchInput.value = opportunitiesFilterState.customerSearch;
|
||||
selectAllCheckbox.disabled = customerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getCustomerOptions().length === 0;
|
||||
selectAllCheckbox.checked = customerOptions.length > 0 && selectedCount === customerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < customerOptions.length;
|
||||
renderCustomerFilterList();
|
||||
@@ -7081,7 +7097,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.customerSearch.trim().toLocaleLowerCase();
|
||||
const customerOptions = getCustomerOptions().filter((customer) => {
|
||||
const customerOptions = getAvailableCustomerOptions().filter((customer) => {
|
||||
return customer.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -7103,7 +7119,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedCustomerKeys.has(customer.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
if (getAvailableCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedCustomerKeys.clear();
|
||||
opportunitiesFilterState.selectedCustomerKeys.add(customer.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -7115,6 +7131,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7129,18 +7146,18 @@ function createOpportunitiesFilters({
|
||||
const trigger = document.getElementById(OWNER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(OWNER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(OWNER_FILTER_SELECT_ALL_ID);
|
||||
const ownerOptions = getOwnerOptions();
|
||||
const ownerOptions = getAvailableOwnerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = ownerOptions.filter((owner) => opportunitiesFilterState.selectedOwnerKeys.has(owner.key)).length;
|
||||
trigger.disabled = ownerOptions.length === 0;
|
||||
trigger.disabled = getOwnerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(ownerOptions.length, selectedCount)
|
||||
.replace("customer", "owner");
|
||||
searchInput.value = opportunitiesFilterState.ownerSearch;
|
||||
selectAllCheckbox.disabled = ownerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getOwnerOptions().length === 0;
|
||||
selectAllCheckbox.checked = ownerOptions.length > 0 && selectedCount === ownerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < ownerOptions.length;
|
||||
renderOwnerFilterList();
|
||||
@@ -7154,7 +7171,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.ownerSearch.trim().toLocaleLowerCase();
|
||||
const ownerOptions = getOwnerOptions().filter((owner) => {
|
||||
const ownerOptions = getAvailableOwnerOptions().filter((owner) => {
|
||||
return owner.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -7176,7 +7193,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedOwnerKeys.has(owner.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
if (getAvailableOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedOwnerKeys.clear();
|
||||
opportunitiesFilterState.selectedOwnerKeys.add(owner.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -7188,6 +7205,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7269,7 +7287,7 @@ function createOpportunitiesFilters({
|
||||
return opportunitiesFilterState.selectedStatuses.has(statusCode);
|
||||
}
|
||||
|
||||
return { resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
return { getAvailableCustomerOptions, getAvailableOwnerOptions, resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
}
|
||||
|
||||
// Source: src/features/opportunities/formatters.js
|
||||
|
||||
40
dist/firefox/content.js
vendored
40
dist/firefox/content.js
vendored
@@ -2601,6 +2601,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -2661,6 +2662,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7053,21 +7055,35 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
}
|
||||
|
||||
// Keep stored selections intact: narrowing a menu must not turn an implicit
|
||||
// "all" into a second filter that prevents expanding the original selection.
|
||||
function getAvailableCustomerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allOwners = getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key));
|
||||
return getCustomerOptions(allOwners ? items : items.filter(item => opportunitiesFilterState.selectedOwnerKeys.has(getOwnerKey(item))));
|
||||
}
|
||||
|
||||
function getAvailableOwnerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allCustomers = getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key));
|
||||
return getOwnerOptions(allCustomers ? items : items.filter(item => opportunitiesFilterState.selectedCustomerKeys.has(getCustomerKey(item))));
|
||||
}
|
||||
|
||||
function renderCustomerFilter() {
|
||||
const trigger = document.getElementById(CUSTOMER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(CUSTOMER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(CUSTOMER_FILTER_SELECT_ALL_ID);
|
||||
const customerOptions = getCustomerOptions();
|
||||
const customerOptions = getAvailableCustomerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = customerOptions.filter((customer) => opportunitiesFilterState.selectedCustomerKeys.has(customer.key)).length;
|
||||
trigger.disabled = customerOptions.length === 0;
|
||||
trigger.disabled = getCustomerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(customerOptions.length, selectedCount);
|
||||
searchInput.value = opportunitiesFilterState.customerSearch;
|
||||
selectAllCheckbox.disabled = customerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getCustomerOptions().length === 0;
|
||||
selectAllCheckbox.checked = customerOptions.length > 0 && selectedCount === customerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < customerOptions.length;
|
||||
renderCustomerFilterList();
|
||||
@@ -7081,7 +7097,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.customerSearch.trim().toLocaleLowerCase();
|
||||
const customerOptions = getCustomerOptions().filter((customer) => {
|
||||
const customerOptions = getAvailableCustomerOptions().filter((customer) => {
|
||||
return customer.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -7103,7 +7119,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedCustomerKeys.has(customer.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
if (getAvailableCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedCustomerKeys.clear();
|
||||
opportunitiesFilterState.selectedCustomerKeys.add(customer.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -7115,6 +7131,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7129,18 +7146,18 @@ function createOpportunitiesFilters({
|
||||
const trigger = document.getElementById(OWNER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(OWNER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(OWNER_FILTER_SELECT_ALL_ID);
|
||||
const ownerOptions = getOwnerOptions();
|
||||
const ownerOptions = getAvailableOwnerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = ownerOptions.filter((owner) => opportunitiesFilterState.selectedOwnerKeys.has(owner.key)).length;
|
||||
trigger.disabled = ownerOptions.length === 0;
|
||||
trigger.disabled = getOwnerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(ownerOptions.length, selectedCount)
|
||||
.replace("customer", "owner");
|
||||
searchInput.value = opportunitiesFilterState.ownerSearch;
|
||||
selectAllCheckbox.disabled = ownerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getOwnerOptions().length === 0;
|
||||
selectAllCheckbox.checked = ownerOptions.length > 0 && selectedCount === ownerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < ownerOptions.length;
|
||||
renderOwnerFilterList();
|
||||
@@ -7154,7 +7171,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.ownerSearch.trim().toLocaleLowerCase();
|
||||
const ownerOptions = getOwnerOptions().filter((owner) => {
|
||||
const ownerOptions = getAvailableOwnerOptions().filter((owner) => {
|
||||
return owner.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -7176,7 +7193,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedOwnerKeys.has(owner.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
if (getAvailableOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedOwnerKeys.clear();
|
||||
opportunitiesFilterState.selectedOwnerKeys.add(owner.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -7188,6 +7205,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -7269,7 +7287,7 @@ function createOpportunitiesFilters({
|
||||
return opportunitiesFilterState.selectedStatuses.has(statusCode);
|
||||
}
|
||||
|
||||
return { resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
return { getAvailableCustomerOptions, getAvailableOwnerOptions, resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
}
|
||||
|
||||
// Source: src/features/opportunities/formatters.js
|
||||
|
||||
@@ -310,6 +310,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -370,6 +371,7 @@ function createContentModal({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
|
||||
@@ -202,21 +202,35 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
}
|
||||
|
||||
// Keep stored selections intact: narrowing a menu must not turn an implicit
|
||||
// "all" into a second filter that prevents expanding the original selection.
|
||||
function getAvailableCustomerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allOwners = getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key));
|
||||
return getCustomerOptions(allOwners ? items : items.filter(item => opportunitiesFilterState.selectedOwnerKeys.has(getOwnerKey(item))));
|
||||
}
|
||||
|
||||
function getAvailableOwnerOptions() {
|
||||
const items = opportunitiesTableState.opportunitiesTableState.items;
|
||||
const allCustomers = getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key));
|
||||
return getOwnerOptions(allCustomers ? items : items.filter(item => opportunitiesFilterState.selectedCustomerKeys.has(getCustomerKey(item))));
|
||||
}
|
||||
|
||||
function renderCustomerFilter() {
|
||||
const trigger = document.getElementById(CUSTOMER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(CUSTOMER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(CUSTOMER_FILTER_SELECT_ALL_ID);
|
||||
const customerOptions = getCustomerOptions();
|
||||
const customerOptions = getAvailableCustomerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = customerOptions.filter((customer) => opportunitiesFilterState.selectedCustomerKeys.has(customer.key)).length;
|
||||
trigger.disabled = customerOptions.length === 0;
|
||||
trigger.disabled = getCustomerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(customerOptions.length, selectedCount);
|
||||
searchInput.value = opportunitiesFilterState.customerSearch;
|
||||
selectAllCheckbox.disabled = customerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getCustomerOptions().length === 0;
|
||||
selectAllCheckbox.checked = customerOptions.length > 0 && selectedCount === customerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < customerOptions.length;
|
||||
renderCustomerFilterList();
|
||||
@@ -230,7 +244,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.customerSearch.trim().toLocaleLowerCase();
|
||||
const customerOptions = getCustomerOptions().filter((customer) => {
|
||||
const customerOptions = getAvailableCustomerOptions().filter((customer) => {
|
||||
return customer.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -252,7 +266,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedCustomerKeys.has(customer.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
if (getAvailableCustomerOptions().every(option => opportunitiesFilterState.selectedCustomerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedCustomerKeys.clear();
|
||||
opportunitiesFilterState.selectedCustomerKeys.add(customer.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -264,6 +278,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedCustomerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderCustomerFilter();
|
||||
renderOwnerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -278,18 +293,18 @@ function createOpportunitiesFilters({
|
||||
const trigger = document.getElementById(OWNER_FILTER_BUTTON_ID);
|
||||
const searchInput = document.getElementById(OWNER_FILTER_SEARCH_ID);
|
||||
const selectAllCheckbox = document.getElementById(OWNER_FILTER_SELECT_ALL_ID);
|
||||
const ownerOptions = getOwnerOptions();
|
||||
const ownerOptions = getAvailableOwnerOptions();
|
||||
|
||||
if (!trigger || !searchInput || !selectAllCheckbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedCount = ownerOptions.filter((owner) => opportunitiesFilterState.selectedOwnerKeys.has(owner.key)).length;
|
||||
trigger.disabled = ownerOptions.length === 0;
|
||||
trigger.disabled = getOwnerOptions().length === 0;
|
||||
trigger.textContent = getCustomerFilterSummary(ownerOptions.length, selectedCount)
|
||||
.replace("customer", "owner");
|
||||
searchInput.value = opportunitiesFilterState.ownerSearch;
|
||||
selectAllCheckbox.disabled = ownerOptions.length === 0;
|
||||
selectAllCheckbox.disabled = getOwnerOptions().length === 0;
|
||||
selectAllCheckbox.checked = ownerOptions.length > 0 && selectedCount === ownerOptions.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < ownerOptions.length;
|
||||
renderOwnerFilterList();
|
||||
@@ -303,7 +318,7 @@ function createOpportunitiesFilters({
|
||||
}
|
||||
|
||||
const normalizedSearch = opportunitiesFilterState.ownerSearch.trim().toLocaleLowerCase();
|
||||
const ownerOptions = getOwnerOptions().filter((owner) => {
|
||||
const ownerOptions = getAvailableOwnerOptions().filter((owner) => {
|
||||
return owner.label.toLocaleLowerCase().includes(normalizedSearch);
|
||||
});
|
||||
|
||||
@@ -325,7 +340,7 @@ function createOpportunitiesFilters({
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = opportunitiesFilterState.selectedOwnerKeys.has(owner.key);
|
||||
checkbox.addEventListener("change", () => {
|
||||
if (getOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
if (getAvailableOwnerOptions().every(option => opportunitiesFilterState.selectedOwnerKeys.has(option.key))) {
|
||||
opportunitiesFilterState.selectedOwnerKeys.clear();
|
||||
opportunitiesFilterState.selectedOwnerKeys.add(owner.key);
|
||||
} else if (checkbox.checked) {
|
||||
@@ -337,6 +352,7 @@ function createOpportunitiesFilters({
|
||||
opportunitiesFilterState.hasSavedOwnerFilter = true;
|
||||
saveFilterPreferences();
|
||||
renderOwnerFilter();
|
||||
renderCustomerFilter();
|
||||
renderOpportunitiesTable();
|
||||
});
|
||||
|
||||
@@ -418,5 +434,5 @@ function createOpportunitiesFilters({
|
||||
return opportunitiesFilterState.selectedStatuses.has(statusCode);
|
||||
}
|
||||
|
||||
return { resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
return { getAvailableCustomerOptions, getAvailableOwnerOptions, resetCustomerAndOwnerFiltersForPeriod, renderStageFilterButtons, toggleStageFilter, renderStatusFilterButtons, toggleStatusFilter, toggleCustomerFilterPanel, closeCustomerFilterPanel, toggleOwnerFilterPanel, closeOwnerFilterPanel, resetCustomerFilter, resetOwnerFilter, renderCustomerFilter, renderCustomerFilterList, renderOwnerFilter, renderOwnerFilterList, getSortedOpportunities, matchesTableSearch, matchesSelectedStatus };
|
||||
}
|
||||
|
||||
43
tests/dependentFilters.test.cjs
Normal file
43
tests/dependentFilters.test.cjs
Normal file
@@ -0,0 +1,43 @@
|
||||
const { test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { loadApplication } = require('./support/application.cjs');
|
||||
function setup() {
|
||||
const app = loadApplication('content');
|
||||
const items = [['A', 'X'], ['A', 'Y'], ['B', 'Y'], ['C', 'Z'], ['A', 'X']].map(([customer, owner]) => ({
|
||||
CustomerAccount: { PartyId: customer, PartyUniqueName: customer }, Owner: owner
|
||||
}));
|
||||
app.opportunitiesTableState.opportunitiesTableState.items = items;
|
||||
app.opportunitiesFilters.resetCustomerFilter(items);
|
||||
app.opportunitiesFilters.resetOwnerFilter(items);
|
||||
return { filters: app.opportunitiesFilters, state: app.opportunitiesFilterState };
|
||||
}
|
||||
const labels = options => Array.from(options, option => option.label);
|
||||
test('customers narrow owners without losing all-owner selection; widening restores options', () => {
|
||||
const { filters, state } = setup();
|
||||
state.selectedCustomerKeys = new Set(['party:A']);
|
||||
assert.deepEqual(labels(filters.getAvailableOwnerOptions()), ['X', 'Y']);
|
||||
assert.deepEqual(labels(filters.getAvailableCustomerOptions()), ['A', 'B', 'C']);
|
||||
state.selectedCustomerKeys.add('party:C');
|
||||
assert.deepEqual(labels(filters.getAvailableOwnerOptions()), ['X', 'Y', 'Z']);
|
||||
assert.equal(state.selectedOwnerKeys.size, 3);
|
||||
});
|
||||
test('owners narrow customers and multi-selection combines their customers', () => {
|
||||
const { filters, state } = setup();
|
||||
state.selectedOwnerKeys = new Set(['name:Y']);
|
||||
assert.deepEqual(labels(filters.getAvailableCustomerOptions()), ['A', 'B']);
|
||||
assert.deepEqual(labels(filters.getAvailableOwnerOptions()), ['X', 'Y', 'Z']);
|
||||
state.selectedOwnerKeys.add('name:Z');
|
||||
assert.deepEqual(labels(filters.getAvailableCustomerOptions()), ['A', 'B', 'C']);
|
||||
});
|
||||
test('both filters use the opposite selection, independent of search and stage', () => {
|
||||
const { filters, state } = setup();
|
||||
state.selectedOwnerKeys = new Set(['name:Y']);
|
||||
state.selectedCustomerKeys = new Set(['party:A']);
|
||||
state.tableSearch = 'no match';
|
||||
state.selectedStages.clear();
|
||||
assert.deepEqual(labels(filters.getAvailableCustomerOptions()), ['A', 'B']);
|
||||
assert.deepEqual(labels(filters.getAvailableOwnerOptions()), ['X', 'Y']);
|
||||
state.selectedCustomerKeys.clear();
|
||||
assert.deepEqual(labels(filters.getAvailableOwnerOptions()), []);
|
||||
assert.deepEqual(labels(filters.getAvailableCustomerOptions()), ['A', 'B']);
|
||||
});
|
||||
Reference in New Issue
Block a user