Smart view to default page without results

Hi,

Problem:
We have created a smart view imitating a default table, just with an extra special search field. When applying filters or searches, where no results appear, the site gets all empty. We are looking for the default behavior, which is the view shown in image below.

The image is from another tab, using the default table implementation, where the filtering and searching behavior is as we want it to be, where no results are found.

How can we achieve what can be seen at the image?

Should we return something special to the system?

Project Name: Leadtime
Project smart view: Leads-smart-view

Best regards.
Magnus

Hi @magnus.jakobsen :wave: Thank you for your feedback :pray:

Could you send your smart view code? (or a simplified version). Then we could try to reproduce your issue and hopefully fix it.

import Component from '@ember/component';
import { inject as service } from '@ember/service';
import SmartViewMixin from 'client/mixins/smart-view-mixin';

let component = null;

const missingCustomerIdWarning = 'You need to filter leads by customer to export for delivery.';

const customerFieldId = 'leadtime-customer-field';
const customerListId = 'leadtime-customer-field-list';
const customerListClass = 'c-list c-list--autocomplete';
const customerFieldSpanId = 'leadtime-customer-field-span';
const customerFieldInputId = 'leadtime-customer-input';
const editLayoutButtonId = 'edit-layout-button';
let timeoutId = 0;

const searchBarInputClass = 'c-beta-search-bar__input';
const searchBarIconClass = 'c-beta-search-bar__icon';

const paginationLeftQuery = '.material-icons.c-beta-paginator__chevron.c-beta-paginator__chevron--left';
const paginationRightQuery = '.material-icons.c-beta-paginator__chevron.c-beta-paginator__chevron--right';
let paginationLeft = null;
let paginationRight = null;

const filtersButtonId = 'c-beta-filter-button';
const filtersButtonTextClass = 'c-beta-filter-button__text';
const filtersClearConditionButtonClass = 'c-beta-filter-footer__clear-condition';
const filtersApplyConditionButtonClass = 'c-beta-filter-footer__apply';
const filtersDiscardButtonClass = 'c-beta-filter-footer__discard';
let filtersButton = null;
let filtersClearConditionButton = null;
let filtersApplyConditionButton = null;
let filtersDiscardButton = null;
let filtersForm = null;

const popUpContainerClass = 'l-popup-container';
const filtersAggregatorOperatorClass = 'c-beta-filter-operator__operator';
const filtersEntryClass = 'c-beta-filter-entry';
const filtersEntryFieldClass = 'c-beta-filter-entry__field';
const filtersEntrySubFieldClass = 'c-beta-filter-entry__sub-field';
const filtersEntryOperatorClass = 'c-beta-filter-entry__operator';
const filtersEntryValueClass = 'c-beta-filter-entry__value';
const filtersEntryValueSelectQuery = '.c-beta-select:last-child';
const filtersEntrySelectClass = 'c-beta-select__value';
const filtersEntryInputClass = 'c-beta-input';
const dateInputTypeClass = 'c-beta-input-date__input';
const filtersFormQuery = '.l-beta-filter-form-entries';
const filtersAddConditionButtonQuery = '.c-beta-filter-footer__add-condition';
const filtersRemoveConditionButtonQuery = '.c-beta-filter-entry__remove';

const actionsButtonQuery = '.c-beta-dropdown-actions-container .c-beta-button';
const exportLeadsOpenButtonQuery = '[data-test-action-name="Export Leads"]';
const exportLeadsActivateButtonQuery = '.l-overlay__sidepage__footer .c-beta-button--primary';
const getRandomLeadsButtonQuery = '[data-test-action-name="Get Random Leads"]';
const actionsListQuery = 'ul.c-beta-dropdown-actions';
let actionsButton = null;

const filtersInputsTextValuesMap = {
    is: 'equal',
    'is not': 'not_equal',
    'starts with': 'starts_with',
    'ends with': 'ends_with',
    'contains': 'contains',
    'not contains': 'not_contains',
    'is greater than': 'greater_than',
    'is less than': 'less_than',
    'is after': 'after',
    'is before': 'before',
    'is present': 'present',
    'is blank': 'blank',
    'is today': 'today',
    'was yesterday': 'yesterday',
    'was in previous X days': 'previous_x_days',
    'was in previous week': 'previous_week',
    'was in previous month': 'previous_month',
    'was in previous quarter': 'previous_quarter',
    'was in previous year': 'previous_year',
    'is these X days to date': 'previous_x_days_to_date',
    'is this week to date': 'previous_week_to_date',
    'is this month to date': 'previous_month_to_date',
    'is this quarter to date': 'previous_quarter_to_date',
    'is this year to date': 'previous_year_to_date',
    'is in the past': 'past',
    'is in the future': 'future',
    'was before X hours ago': 'before_x_hours_ago',
    'is after X hours ago': 'after_x_hours_ago',
};

const clearAllButtonClass = `
    c-beta-filter-footer__clear-condition c-beta-button c-beta-button--link-secondary-light
    c-beta-button--tiny c-beta-button--regular c-beta-button--icon-before
`;
const clearAllButtonInnerHTML = `
<span class="c-beta-button__text">Clear all</span>
<i class="material-icons
    c-beta-button__icon
    c-beta-button__icon--tiny
    c-beta-button__icon--left">
    close
</i>
`;

function removeCustomerList() {
    const customerList = document.getElementById(customerListId);

    if (!customerList) {
        return;
    }

    customerList.remove();
}

function addCustomerList(customers, component) {
    if (!customers || !customers.length) {
        return;
    }

    const customerFieldSpan = document.getElementById(customerFieldSpanId);
    const customerFieldInput = document.getElementById(customerFieldInputId);

    if (!customerFieldSpan || !customerFieldInput) {
        return;
    }

    const customerList = document.createElement('ul');
    customerList.id = customerListId;
    customerList.className = customerListClass;
    const customerListInnerHTML = customers.map(customer => {
        const id = customer.id;
        const companyName = customer['forest-company']['forest-companyName'];

        if (!id || !companyName) {
            return '';
        }

        return `<li role="button" data-customer-id="${id}"><div>${companyName}</div></li>`;
    }).join('');

    if (!customerListInnerHTML) {
        return;
    }

    customerList.innerHTML = customerListInnerHTML;
    customerFieldSpan.prepend(customerList);

    customerList.addEventListener('click', event => {
        let { target: element } = event;

        while (element.nodeName !== 'LI') {
            if (element.nodeName === 'UL') {
                return;
            }

            element = element.parentNode;
        }

        const { customerId } = element.dataset;

        if (!customerId) {
            return;
        }

        const { textContent: companyName } = document.querySelector(`[data-customer-id='${customerId}']`);

        component.set('customerId', customerId);
        component.set('inputValue', companyName);
        component.actions.fetchData(component);
        customerFieldInput.value = companyName;
        removeCustomerList();
    });
}

function getColumn(columns, inputField) {
    return columns.find(({ field }) => {
        if (!field) {
            return false;
        }

        return field.displayName === inputField;
    });
}

function getFieldName(inputField) {
    if (!component || !component.columns || !component.columns.length) {
        return inputField;
    }

    const column = getColumn(component.columns, inputField);

    if (!column || !column.field.field) {
        return inputField;
    }

    return column.field.field;
}

function getSubFieldName(inputField, inputSubField) {
    if (!component || !component.columns || !component.columns.length) {
        return inputSubField;
    }

    const column = getColumn(component.columns, inputField);

    if (!column || !column.field.referenceModel || !column.field.referenceModel.filterableFields) {
        return inputSubField;
    }

    const filterableField = column.field.referenceModel.filterableFields.find(field => (
        field.displayName === inputSubField
    ));

    if (!filterableField || !filterableField.field) {
        return inputSubField;
    }

    return filterableField.field;
}

function toggleCustomerField() {
    const customerField = document.getElementById(customerFieldId)

    if (customerField) {
        customerField.style.display = customerField.style.display === 'none' ? 'block' : 'none';
    }
}

function handleDocumentClick(event) {
    const inputField = document.getElementById(customerFieldInputId);

    if (event.target === inputField) {
        return;
    }

    const customerList = document.getElementById(customerListId);

    if (customerList) {
        customerList.remove();
    }
}

function handleSearchBarInputKeydown(event) {
    if (event.keyCode === 13) {
        event.preventDefault();
        event.stopPropagation();
        component.actions.fetchData();
    }
}

function handleSearchBarInputChange(event) {
    const { value } = event.currentTarget;
    component.set('searchValue', value);

    if (value === '') {
        event.preventDefault();
        event.stopPropagation();
        component.actions.fetchData();
    }
}

function handleSearchBarIconClick(event) {
    event.preventDefault();
    event.stopPropagation();
    component.actions.fetchData();
}

function setFiltersButtonText() {
    if (!component.appliedFiltersEntries.length) {
        return;
    }

    const filtersButtonText = document.querySelector(`.${filtersButtonTextClass}`);

    if (filtersButtonText) {
        const filtersEntriesArray = Array.from(document.querySelectorAll(`.${filtersEntryClass}`));
        const appliedFiltersEntries = [];

        component.appliedFiltersEntries.forEach(entry => {
            if (filtersEntriesArray.includes(entry)) {
                appliedFiltersEntries.push(entry);
            }
        });

        const { length: appliedFiltersEntriesLength } = appliedFiltersEntries;

        if (!appliedFiltersEntriesLength) {
            filtersButtonText.textContent = 'Filter';
        } else {
            filtersButtonText.textContent = appliedFiltersEntriesLength === 1 ? '1 Filter' : `${appliedFiltersEntriesLength} Filters`;
        }

        component.set('appliedFiltersEntries', appliedFiltersEntries);
    }
}

function adjustDateTimeFormat(dateStringInddMMYYYYFormat) {
    const dateParts = dateStringInddMMYYYYFormat.split('/');
    const dateStringInMMddYYYYFormat = `${dateParts[1]}/${dateParts[0]}/${dateParts[2]}`;

    return dateStringInMMddYYYYFormat;
}

function handleFiltersButtonClick(event) {
    const popUpContainer = document.querySelector(`.${popUpContainerClass}`);

    if (popUpContainer && popUpContainer.style.display === 'none') {
        event.stopPropagation();
        popUpContainer.style.display = 'block';
    }

    const intervalId = setInterval(() => {
        const renderedApplyButton = document.querySelector(`.${filtersApplyConditionButtonClass}`);

        if (renderedApplyButton) {
            clearInterval(intervalId);

            const renderedDiscardButton = document.querySelector(`.${filtersDiscardButtonClass}`);
            const renderedClearButton = document.querySelector(`.${filtersClearConditionButtonClass}`);

            if (component.filtersObject) {
                if (!filtersClearConditionButton) {
                    filtersClearConditionButton = document.createElement('button');
                    filtersClearConditionButton.className = clearAllButtonClass;
                    filtersClearConditionButton.innerHTML = clearAllButtonInnerHTML;
                    filtersClearConditionButton.addEventListener('click', event => {
                        event.stopPropagation();

                        if (component.filtersObject) {
                            component.set('filtersObject', null);
                            component.set('appliedFiltersEntries', []);
                            component.actions.fetchData();
                            const filtersButtonText = document.querySelector(`.${filtersButtonTextClass}`);

                            if (filtersButtonText) {
                                filtersButtonText.textContent = 'Filter';
                            }

                            document.querySelector(`.${popUpContainerClass}`).style.display = 'none';

                            if (filtersDiscardButton) {
                                filtersClearConditionButton.replaceWith(filtersDiscardButton);
                                filtersDiscardButton.click();
                            }
                        }
                    });
                }

                if (renderedDiscardButton && !renderedClearButton) {
                    filtersDiscardButton = renderedDiscardButton;
                    renderedDiscardButton.replaceWith(filtersClearConditionButton);
                }
            } else if (renderedDiscardButton) {
                renderedDiscardButton.addEventListener('click', () => {
                    component.set('aggregators', []);
                });
            }

            const addFilterButton = document.querySelector(filtersAddConditionButtonQuery);

            if (addFilterButton) {
                addFilterButton.addEventListener('click', () => {
                    const initialRemoveButtons = document.querySelectorAll(filtersRemoveConditionButtonQuery);
                    const intervalId = setInterval(initialRemoveButtons => {
                        const removeButtons = document.querySelectorAll(filtersRemoveConditionButtonQuery);

                        if (removeButtons.length > initialRemoveButtons.length) {
                            clearInterval(intervalId);
                            const aggregators = [];
                            const aggregatorList = document.querySelectorAll(`.${filtersAggregatorOperatorClass}`);
                            Array.prototype.forEach.call(aggregatorList, listItem => {
                                aggregators.push(listItem.textContent.trim());
                            });
                            component.set('aggregators', aggregators);

                            Array.from(removeButtons).slice(initialRemoveButtons.length).forEach(button => {
                                button.addEventListener('click', () => {
                                    const aggregatorList = document.querySelectorAll(`.${filtersAggregatorOperatorClass}`);
                                    const aggregators = [];

                                    Array.prototype.forEach.call(aggregatorList, listItem => {
                                        aggregators.push(listItem.textContent.trim());
                                    });

                                    setFiltersButtonText();
                                    component.set('aggregators', aggregators);
                                });
                            });
                        }
                    }, 100, initialRemoveButtons);
                });
            }

            const renderedFiltersForm = document.querySelector(filtersFormQuery);

            if (!filtersForm || renderedFiltersForm !== filtersForm) {
                filtersForm = renderedFiltersForm;
                const aggregatorList = document.querySelectorAll(`.${filtersAggregatorOperatorClass}`);
                const { aggregators } = component;

                if (aggregatorList.length && aggregators.length) {
                    Array.prototype.forEach.call(aggregatorList, (listItem, index) => {
                        const aggregator = aggregators[index];

                        if (aggregator === 'and' && listItem.classList.contains(`${filtersAggregatorOperatorClass}--or`)) {
                            listItem.classList.replace(`${filtersAggregatorOperatorClass}--or`, `${filtersAggregatorOperatorClass}--and`);
                            listItem.textContent = 'and';
                        } else if (aggregator === 'or' && listItem.classList.contains(`${filtersAggregatorOperatorClass}--and`)) {
                            listItem.classList.replace(`${filtersAggregatorOperatorClass}--and`, `${filtersAggregatorOperatorClass}--or`);
                            listItem.textContent = 'or';
                        }
                    });
                }

                renderedFiltersForm.addEventListener('click', event => {
                    const { target } = event;

                    if (target.classList.contains(filtersAggregatorOperatorClass)) {
                        const aggregatorList = document.querySelectorAll(`.${filtersAggregatorOperatorClass}`);

                        if (aggregatorList.length === 1) {
                            return;
                        }

                        const aggregators = [...component.aggregators];

                        Array.prototype.forEach.call(aggregatorList, (listItem, index) => {
                            if (listItem === target) {
                                const aggregator = target.textContent.trim();

                                if (aggregator === aggregators[index]) {
                                    if (aggregator === 'and') {
                                        aggregators[index] = 'or';
                                        listItem.classList.replace(`${filtersAggregatorOperatorClass}--and`, `${filtersAggregatorOperatorClass}--or`);
                                        listItem.textContent = 'or';
                                    } else {
                                        aggregators[index] = 'and';
                                        listItem.classList.replace(`${filtersAggregatorOperatorClass}--or`, `${filtersAggregatorOperatorClass}--and`);
                                        listItem.textContent = 'and';
                                    }
                                } else {
                                    aggregators[index] = aggregator;
                                }

                                return;
                            }

                            const aggregator = aggregators[index];

                            if (aggregator === 'and' && listItem.classList.contains(`${filtersAggregatorOperatorClass}--or`)) {
                                listItem.classList.replace(`${filtersAggregatorOperatorClass}--or`, `${filtersAggregatorOperatorClass}--and`);
                                listItem.textContent = 'and';
                            } else if (aggregator === 'or' && listItem.classList.contains(`${filtersAggregatorOperatorClass}--and`)) {
                                listItem.classList.replace(`${filtersAggregatorOperatorClass}--and`, `${filtersAggregatorOperatorClass}--or`);
                                listItem.textContent = 'or';
                            }
                        });

                        component.set('aggregators', aggregators);
                    }
                });
            }

            if (renderedApplyButton !== filtersApplyConditionButton) {
                filtersApplyConditionButton = renderedApplyButton;
                filtersApplyConditionButton.addEventListener('click', event => {
                    event.stopPropagation();
                    let filtersObject = {};
                    let conditions = null;
                    const filtersEntries = document.querySelectorAll(`.${filtersEntryClass}`);
                    const { length: filtersEntriesLength } = filtersEntries;

                    if (filtersEntriesLength > 1) {
                        conditions = [];
                    }

                    for (let i = 0; i < filtersEntriesLength; i++) {
                        const filter = {};
                        const { id: filtersEntriesId } = filtersEntries[i];
                        const entryField = document.querySelector(
                            `#${filtersEntriesId} .${filtersEntryFieldClass} .${filtersEntrySelectClass}`
                        );
                        const entrySubField = document.querySelector(
                            `#${filtersEntriesId} .${filtersEntrySubFieldClass} .${filtersEntrySelectClass}`
                        );
                        const entryOperator = document.querySelector(
                            `#${filtersEntriesId} .${filtersEntryOperatorClass} .${filtersEntrySelectClass}`
                        );
                        const entryValue = document.querySelector(
                            `#${filtersEntriesId} .${filtersEntryValueClass} .${filtersEntrySelectClass}`
                        ) || document.querySelector(
                            `#${filtersEntriesId} .${filtersEntryValueClass} .${filtersEntryInputClass}`
                        ) || document.querySelector(
                            `#${filtersEntriesId} ${filtersEntryValueSelectQuery} .${filtersEntrySelectClass}`
                        );

                        const inputField = entryField.textContent;
                        filter.field = getFieldName(inputField);

                        if (entrySubField) {
                            const subField = getSubFieldName(inputField, entrySubField.textContent);
                            filter.field += `:${subField}`;
                        }

                        filter.operator = filtersInputsTextValuesMap[entryOperator.textContent];

                        if (entryValue) {
                            if (entryValue.classList.contains(dateInputTypeClass)) {
                                const inMMddYYYYFormat = adjustDateTimeFormat(entryValue.value);
                                filter.value = new Date(inMMddYYYYFormat).toISOString();
                            } else if (entryValue.type === 'number') {
                                filter.value = parseInt(entryValue.value);
                            } else {
                                filter.value = entryValue.value || entryValue.textContent;
                            }
                        } else {
                            filter.value = null;
                        }

                        if (conditions) {
                            conditions.push(filter);
                        } else {
                            filtersObject = filter;
                        }
                    }

                    if (conditions) {
                        const { aggregators } = component;
                        const aggregator = aggregators[0];

                        if (aggregators.some(item => item !== aggregator)) {
                            let filter = conditions[0];
                            const combinedConditions = [];
                            filtersObject.aggregator = 'or';

                            conditions.slice(1).forEach((condition, index) => {
                                if (aggregators[index] === 'or') {
                                    combinedConditions.push(filter);
                                    filter = condition;
                                } else {
                                    if (filter.aggregator) {
                                        filter.conditions.push(condition);
                                    } else {
                                        filter = {
                                            aggregator: 'and',
                                            conditions: [filter, condition],
                                        };
                                    }
                                }
                            });

                            combinedConditions.push(filter);
                            filtersObject.conditions = combinedConditions;
                        } else {
                            filtersObject.aggregator = aggregator;
                            filtersObject.conditions = conditions;
                        }
                    }

                    component.set('appliedFiltersEntries', [...filtersEntries]);
                    component.set('filtersObject', filtersObject);
                    component.actions.fetchData();
                    const filtersButtonText = document.querySelector(`.${filtersButtonTextClass}`);

                    if (filtersButtonText) {
                        filtersButtonText.textContent = filtersEntriesLength === 1 ?
                            '1 Filter' : `${filtersEntriesLength} Filters`;
                    }

                    document.querySelector(`.${popUpContainerClass}`).style.display = 'none';
                });
            }
        }
    }, 100);
}



function getCookieValue() {
    const cookie = document.cookie.split(';').find(str => str.trim().startsWith('forest_session_data'));

    if (cookie) {
        return cookie.slice(cookie.indexOf('=') + 1);
    }

    return '';
}

function activateLeadsExport(event) {
    event.stopPropagation();

    component.actions.exportLeads();
}

function handleExportLeadsOpenButtonClick() {
    const intervalId = setInterval(() => {
        const exportLeadsActivateButton = document.querySelector(exportLeadsActivateButtonQuery);

        if (exportLeadsActivateButton) {
            clearInterval(intervalId);

            exportLeadsActivateButton.addEventListener('click', activateLeadsExport);
        }
    }, 100);
}

function handleGetRandomLeadsClick(event) {
    event.preventDefault();
    event.stopPropagation();
    const actionsList = document.querySelector(actionsListQuery);

    if (actionsList && actionsButton) {
        actionsList.remove();
        actionsButton.click();
    }

    component.actions.getRandomLeads();
}

function handleActionsButtonClick() {
    const intervalId = setInterval(() => {
        const exportLeadsOpenButton = document.querySelector(exportLeadsOpenButtonQuery);
        const getRandomLeadsButton = document.querySelector(getRandomLeadsButtonQuery);

        if (exportLeadsOpenButton) {
            clearInterval(intervalId);

            exportLeadsOpenButton.addEventListener('click', handleExportLeadsOpenButtonClick);

            if (getRandomLeadsButton) {
                getRandomLeadsButton.addEventListener('click', handleGetRandomLeadsClick);
            }
        }
    }, 100);
}

function getParams(isExport = false) {
    const { sortedField, searchValue, collection: { mainView: { content } }, customerId } = component;
    const { filtersObject, currentPage, orderByNumber } = component;

    const params = {
        sort: 'person.fullName',
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        'page[number]': currentPage || 1,
        'page[size]': content && content.recordsPerPage ? content.recordsPerPage : 15,
    };

    if (isExport) {
        params['page[number]'] = 1;
        params['page[size]'] = 100;
    }

    if (filtersObject) {
        params.filters = JSON.stringify(filtersObject);
    }

    if (sortedField) {
        const { field, order, referenceSortingField: refField } = sortedField;
        params.sort = (order === 'ascending' ? '' : '-') + field + (refField ? `.${refField}` : '');
    }

    if (customerId) {
        params.customerId = customerId;
    }

    if (orderByNumber) {
        params.orderByNumber = orderByNumber;
    }

    if (searchValue && searchValue.length) {
        params.search = searchValue;
    }

    return params;
}

export default Component.extend(SmartViewMixin, {
    store: service(),
    customerId: '',
    inputValue: '',
    filtersObject: null,
    orderByNumber: 0,
    aggregators: [],
    appliedFiltersEntries: [],

	init(...args) {
        this._super(...args);
        this.set('fetchRecords', this.actions.fetchData);

        if (document.getElementById(customerFieldId)) {
            return;
        }

        component = this;

        const editLayoutBtn = document.getElementById(editLayoutButtonId);
        const actionContainer = document.querySelector('.c-beta-header__actions-right');
        const customerField = document.createElement('div');
        customerField.id = customerFieldId;
        customerField.className = 'c-beta-label__input';
        customerField.innerHTML = `
			<div class="c-row-belongs-to ">
                <span id="${customerFieldSpanId}"
                    class="c-row-belongs-to__input-container c-typeahead-field c-typeahead-field--relative">
                    <svg style="visibility:hidden" id="leadtime-customer-input-loader"
                        class="c-beta-loader c-beta-loader--primary c-typeahead-field__loader"
                        width="40px" height="40px" xmlns="http://www.w3.org/2000/svg"
                        viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
						<circle class="c-beta-loader__circle" cx="50" cy="50" fill="none" stroke-width="10"
                            r="35" stroke-dasharray="164.93361431346415 56.97787143782138"
                            transform="rotate(305.844 50 50)">
    						<animateTransform attributeName="transform" calcMode="linear" values="0 50 50;360 50 50"
                                keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite" type="rotate">
                            </animateTransform>
  						</circle>
					</svg>
                    <div class="l-beta-input">
                        <input id="leadtime-customer-input"
                            class="c-beta-input c-beta-input--basic c-row-belongs-to__input"
                            placeholder="Link to a customer…" autocomplete="off">
                    </div>
                </span>
            </div>
		`;

        if (actionContainer) {
    	    actionContainer.prepend(customerField);
            const loader = document.getElementById('leadtime-customer-input-loader');
            const inputField = document.getElementById(customerFieldInputId);

            const getCustomerList = () => {
                const { value } = inputField;

                if (value === this.inputValue) {
                    return;
                }

                this.set('inputValue', value);
                removeCustomerList();

                if (this.customerId) {
                    this.set('customerId', '');
                    this.actions.fetchData();
                }

                if (!value) {
                    loader.style.visibility = 'hidden';
                    return;
                }

                if (timeoutId) {
                    clearTimeout(timeoutId);
                }

                loader.style.visibility = 'visible';

                timeoutId = setTimeout(value => {
                    this.get('store')
                        .query('forest-customer', { companyName: value })
                        .then(customers => {
                            addCustomerList(customers, this);
                        });
                    loader.style.visibility = 'hidden';
                }, 500, value);
            };

            inputField.addEventListener('keyup', getCustomerList);

            inputField.addEventListener('focus', () => {
                if (!this.customerId) {
                    this.set('inputValue', '');
                    getCustomerList();
                }
            });

            document.addEventListener('click', handleDocumentClick);
        }

        const globalElement = document.getElementById('global');

        if (customerField && globalElement && globalElement.classList.contains('v-editor')) {
            customerField.style.display = 'none';
        }

        if (editLayoutBtn) {
            editLayoutBtn.addEventListener('click', toggleCustomerField);
        }

        const searchBarInput = document.querySelector(`.${searchBarInputClass}`);
        const searchBarIcon = document.querySelector(`.${searchBarIconClass}`);

        if (searchBarInput) {
            searchBarInput.addEventListener('keydown', handleSearchBarInputKeydown);
            searchBarInput.addEventListener('input', handleSearchBarInputChange);
        }

        if (searchBarIcon) {
            searchBarIcon.addEventListener('click', handleSearchBarIconClick);
        }
    },

    didRender() {
        this.set('fetchRecords', this.actions.fetchData);
        const renderedFiltersButton = document.getElementById(filtersButtonId);

        if (renderedFiltersButton && renderedFiltersButton !== filtersButton) {
            filtersButton = renderedFiltersButton;
            filtersButton.addEventListener('click', handleFiltersButtonClick);
        }

        const renderedPaginationLeft = document.querySelector(paginationLeftQuery);

        if (renderedPaginationLeft && renderedPaginationLeft !== paginationLeft) {
            paginationLeft = renderedPaginationLeft;
            paginationLeft.addEventListener('click', event => {
                event.stopPropagation();

                if (component.currentPage === 1) {
                    return;
                }

                component.set('currentPage', component.currentPage - 1);
                component.actions.fetchData();
            });
        }

        const renderedPaginationRight = document.querySelector(paginationRightQuery);

        if (renderedPaginationRight && renderedPaginationRight !== paginationRight) {
            paginationRight = renderedPaginationRight;
            paginationRight.addEventListener('click', event => {
                event.stopPropagation();

                if (component.currentPage === component.numberOfPages) {
                    return;
                }

                component.set('currentPage', component.currentPage + 1);
                component.actions.fetchData();
            });
        }

        const renderedActionsButton = document.querySelector(actionsButtonQuery);

        if (renderedActionsButton && renderedActionsButton !== actionsButton) {
            actionsButton = renderedActionsButton;
            actionsButton.addEventListener('click', handleActionsButtonClick);
        }
    },

    willDestroyElement() {
        component = null;

        const filtersButtonText = document.querySelector(`.${filtersButtonTextClass}`);

        if (filtersButtonText) {
            filtersButtonText.textContent = 'Filter';
        }

        const customerField = document.getElementById(customerFieldId);

        if (customerField) {
            customerField.remove();
        }

        const editLayoutBtn = document.getElementById(editLayoutButtonId);

        if (editLayoutBtn) {
            editLayoutBtn.removeEventListener('click', toggleCustomerField);
        }

        document.removeEventListener('click', handleDocumentClick);

        const searchBarInput = document.querySelector(`.${searchBarInputClass}`);

        if (searchBarInput) {
            searchBarInput.removeEventListener('keydown', handleSearchBarInputKeydown);
            searchBarInput.removeEventListener('input', handleSearchBarInputChange);
        }

        const searchBarIcon = document.querySelector(`.${searchBarIconClass}`);

        if (searchBarIcon) {
            searchBarIcon.removeEventListener('click', handleSearchBarIconClick);
        }

        if (filtersButton) {
            filtersButton.removeEventListener('click', handleFiltersButtonClick);
            filtersButton = null;
        }
    },

    actions: {
        sortBy(column, order) {
            this.set('sortedField', column.get('field'));
            this.set('sortedField.order', 'asc' === order ? 'ascending' : 'descending');
            this.set('currentPage', 1);
            let sortQuery = column.get('field.field');
            const { field } = this.columnsVisible.find(({ field }) => field.field === sortQuery);

            if (field.hasReference) {
                sortQuery += `.${field.referenceDisplayField.field}`;
            }

            if (order === 'desc') {
                sortQuery = '-'.concat(sortQuery);
            }

            this.set('orderByNumber', 0);
            this.set('sortQuery', sortQuery);
            this.actions.fetchData();
        },
        fetchData() {
            const params = getParams();
            const countParams = {
                timezone: params.timezone,
            };

            if (params.filters) {
                countParams.filters = params.filters;
            }

            if (params.customerId) {
                countParams.customerId = params.customerId;
            }

            if (params.search) {
                countParams.search = params.search;
            }

            component.set('isLoading', true);

            component.get('store')
                .query('forest-lead', params)
                .then(leads => {
                    component.set('records', leads);
        	        component.set('isLoading', false);
                });

            component.get('store')
                .count(component.collection, countParams)
                .then(count => {
        	        component.set('recordsCount', count);
      	        });
        },
        exportLeads() {
            if (!component.records.content.length) {
                component.toastr.perform('error', 'There are no leads to export.');
                return;
            }

            const customActions = component.collection.get('customActionsOrdered');
            const exportAction = customActions.content.find(({ name }) => name === 'Export Leads');

            if (!exportAction || !exportAction.fieldsOrdered) {
                component.toastr.perform('error', 'Error occured. Can\'t export leads.');
                return;
            }

            const payload = {
                data: {
                    attributes: {
                        collection_name: 'leads',
                        values: {},
                        all_records: false,
                        all_records_subset_query: getParams(true),
                        smart_action_id: 'leads-Export@@@Leads',
                    },
                    type: 'custom-action-requests',
                },
            };

            const { fieldsOrdered } = exportAction;

            for (let i = 0; i < fieldsOrdered.length; i++) {
                const { isRequired, customActionValue, fieldName } = fieldsOrdered[i];

                if (isRequired && !customActionValue) {
                    component.toastr.perform('warning', `${fieldName} is required!`);
                    return;
                }

                if (customActionValue) {
                    payload.data.attributes.values[fieldName] = customActionValue;
                }

                if (fieldName === 'Export type' && customActionValue === 'Delivery' && !component.customerId) {
                    component.toastr.perform('warning', missingCustomerIdWarning);
                    return;
                }
            }

            component.set('isLoading', true);

            fetch(`${component.get('collection.rendering.environment.apiEndpoint')}${exportAction.endpoint}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${getCookieValue()}`,
                },
                body: JSON.stringify(payload),
            }).then(res => {
                if (res.status === 200) {
                    res.blob().then(blob => {
                        const href = window.URL.createObjectURL(blob);
                        const element = document.createElement('a');
                        element.style.display = 'none',
                        element.href = href;
                        element.download = 'leads.csv';
                        document.body.appendChild(element);
                        element.click();
                        window.URL.revokeObjectURL(href);
                        document.body.removeChild(element);
                        component.toastr.perform('success', 'Leads are successfully exported.');
                        component.actions.fetchData();
                    });
                } else {
                    res.json().then(({ error }) => {
                        component.set('isLoading', false);
                        component.toastr.perform('error', error || 'Could not export leads.');
                    });
                }
            }).catch(error => {
                component.set('isLoading', false);
                component.toastr.perform('error', error.message);
            });
        },
        getRandomLeads() {
            if (!component.records.content.length) {
                component.toastr.perform('error', 'There are no leads to randomize.');
                return;
            }

            const customActions = component.collection.get('customActionsOrdered');
            const exportAction = customActions.content.find(({ name }) => name === 'Get Random Leads');

            if (!exportAction) {
                component.toastr.perform('error', 'Error occured. Can\'t get random leads.');
                return;
            }

            const payload = {
                data: {
                    attributes: {
                        collection_name: 'leads',
                        all_records: false,
                        smart_action_id: 'leads-Get@@@Random@@@Leads',
                    },
                    type: 'custom-action-requests',
                },
            };

            component.set('isLoading', true);

            fetch(`${component.get('collection.rendering.environment.apiEndpoint')}${exportAction.endpoint}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${getCookieValue()}`,
                },
                body: JSON.stringify(payload),
            }).then(res => {
                if (res.status === 200) {
                    res.json().then(({ success }) => {
                        component.set('orderByNumber', Math.random());
                        component.toastr.perform('success', success);
                        component.actions.fetchData();
                    });
                } else {
                    res.json().then(({ error }) => {
                        component.set('isLoading', false);
                        component.toastr.perform('error', error || 'Could not export leads.');
                    });
                }
            }).catch(error => {
                component.set('isLoading', false);
                component.toastr.perform('error', error.message);
            });
        },
    },
});

Hi @magnus.jakobsen,

If I understand well your need and your smart view, you’re trying to recreate the basic list view of a collection by yourself using smart views and want to use our default no match animation.

As this no match state and animation is directly related to some of our internal variables and states, you won’t be able to use it as is.

But what concerns me more is that it seems that you entirely rewrote the list view by yourself for a need I don’t understand while that need may probably have been fulfilled in a much straight forward way.

Could you explain to me the need you had in the first place that require all this rewriting of the list view?

1 Like

Hi Lamatt,

We didn’t just rewrote the list view, an extra search bar was added in the top right corner, to link this table to an instance of another one. This was done to combine a custom response, when a specific smart actions was triggered. Meaning, the purpose is to connect this view to a searchable instance of another (more or less).

Just to be clear, this means that there are no way to trigger the ‘no match’ state in anyway in a smart view?

Kind regards,
Magnus

Hi Magnus,

Thanks for your insights!
I’m going to contact you by email so we can review together what would be the best option for your use case :ok_hand:

Best,

Harold