@stratusjs/idx
Version:
AngularJS idx/property Service and Components bundle to be used as an add on to StratusJS
611 lines (609 loc) • 34.6 kB
JavaScript
System.register(["./list.component.less", "./list.carousel.component.less", "lodash", "@stratusjs/runtime/stratus", "angular", "angular-material", "angular-sanitize", "@stratusjs/angularjs/services/collection", "@stratusjs/core/misc", "@stratusjs/core/environment", "@stratusjs/angularjs-extras"], function (exports_1, context_1) {
"use strict";
var lodash_1, stratus_1, angular_1, collection_1, misc_1, environment_1, min, packageName, moduleName, componentName, localDir, localDistStyle;
var __moduleName = context_1 && context_1.id;
return {
setters: [
function (_1) {
},
function (_2) {
},
function (lodash_1_1) {
lodash_1 = lodash_1_1;
},
function (stratus_1_1) {
stratus_1 = stratus_1_1;
},
function (angular_1_1) {
angular_1 = angular_1_1;
},
function (_3) {
},
function (_4) {
},
function (collection_1_1) {
collection_1 = collection_1_1;
},
function (misc_1_1) {
misc_1 = misc_1_1;
},
function (environment_1_1) {
environment_1 = environment_1_1;
},
function (_5) {
}
],
execute: function () {
min = !environment_1.cookie('env') ? '.min' : '';
packageName = 'idx';
moduleName = 'property';
componentName = 'list';
localDir = `${stratus_1.Stratus.BaseUrl}${stratus_1.Stratus.DeploymentPath}@stratusjs/${packageName}/src/${moduleName}/`;
localDistStyle = `${stratus_1.Stratus.BaseUrl}${stratus_1.Stratus.DeploymentPath}@stratusjs/${packageName}/dist/${packageName}.bundle.min.css`;
stratus_1.Stratus.Components.IdxPropertyList = {
bindings: {
elementId: '@',
initNow: '=',
tokenUrl: '@',
googleApiKey: '@',
detailsLinkPopup: '@',
detailsLinkUrl: '@',
detailsLinkTarget: '@',
detailsHideVariables: '@',
detailsTemplate: '@',
advancedSearchUrl: '@',
advancedSearchLinkName: '@',
preferredStatus: '@',
contactName: '@',
contactEmail: '@',
contactPhone: '@',
template: '@',
orderOptions: '@',
displayOrderOptions: '@',
urlLoad: '@',
searchOnLoad: '@',
query: '@',
queryOrder: '@',
queryPerPage: '@',
queryService: '@',
queryWhere: '@',
hideDisclaimer: '@',
displayPerRow: '@',
displayPerRowText: '@',
displayPager: '@',
},
controller($anchorScroll, $attrs, $q, $mdDialog, $scope, $timeout, $window, Idx) {
$scope.localDir = localDir;
$scope.initialized = false;
if ($attrs.tokenUrl) {
Idx.setTokenURL($attrs.tokenUrl);
$scope.tokenLoaded = true;
}
let mlsVariables;
let defaultQuery;
let lastQuery;
const init = async () => {
$scope.uid = misc_1.safeUniqueId(packageName, moduleName, componentName);
$scope.elementId = $attrs.elementId || $scope.uid;
stratus_1.Stratus.Instances[$scope.elementId] = $scope;
$scope.instancePath = `Stratus.Instances.${$scope.elementId}`;
if (!$scope.tokenLoaded && $attrs.tokenUrl) {
Idx.setTokenURL($attrs.tokenUrl);
}
stratus_1.Stratus.Internals.CssLoader(localDistStyle).then();
$scope.urlLoad = $attrs.urlLoad && misc_1.isJSON($attrs.urlLoad) ? JSON.parse($attrs.urlLoad) : true;
$scope.searchOnLoad = $attrs.searchOnLoad && misc_1.isJSON($attrs.searchOnLoad) ? JSON.parse($attrs.searchOnLoad) : true;
$scope.detailsLinkUrl = $attrs.detailsLinkUrl || '';
$scope.detailsLinkTarget = $attrs.detailsLinkTarget || 'popup';
$scope.detailsLinkPopup =
$attrs.detailsLinkPopup && misc_1.isJSON($attrs.detailsLinkPopup) ? JSON.parse($attrs.detailsLinkPopup) :
$scope.detailsLinkTarget === 'popup';
$scope.detailsHideVariables = $attrs.detailsHideVariables && misc_1.isJSON($attrs.detailsHideVariables) ?
JSON.parse($attrs.detailsHideVariables) : [];
$scope.detailsTemplate = $attrs.detailsTemplate || null;
$scope.advancedSearchUrl = $attrs.advancedSearchUrl || '';
$scope.advancedSearchLinkName = $attrs.advancedSearchLinkName || 'Advanced Search';
$scope.preferredStatus = $attrs.preferredStatus || 'Closed';
$scope.carouselOptions = $attrs.carouselOptions && misc_1.isJSON($attrs.carouselOptions) ? JSON.parse($attrs.carouselOptions) : {};
$scope.carouselOptions.autoplay ||= false;
$scope.carouselOptions.autoplayDelay ||= 3000;
$scope.carouselOptions.transitionEffect ||= 'fade';
$scope.carouselOptions.speed ||= 1000;
$scope.carouselOptions.counter ||= false;
if (lodash_1.isString($scope.carouselOptions.counter)) {
if ($scope.carouselOptions.counter === 'bullets') {
$scope.carouselOptions.counter = { render: 'bullets', clickable: true };
}
else if ($scope.carouselOptions.counter === 'numberBullet') {
$scope.carouselOptions.counter = { render: 'numberBullet', clickable: true };
}
}
$scope.query = $attrs.query && misc_1.isJSON($attrs.query) ? JSON.parse($attrs.query) : {};
$scope.query.service = $attrs.queryService && misc_1.isJSON($attrs.queryService) ?
JSON.parse($attrs.queryService) : $scope.query.service || [];
$scope.query.order =
$scope.query.order && lodash_1.isString($scope.query.order) && misc_1.isJSON($scope.query.order) ? JSON.parse($scope.query.order) :
$attrs.queryOrder && misc_1.isJSON($attrs.queryOrder) ? JSON.parse($attrs.queryOrder) :
$attrs.queryOrder || $scope.query.order || null;
$scope.query.page ||= null;
$scope.query.perPage = $scope.query.perPage ||
($attrs.queryPerPage && lodash_1.isString($attrs.queryPerPage) ? parseInt($attrs.queryPerPage, 10) : null) ||
($attrs.queryPerPage && lodash_1.isNumber($attrs.queryPerPage) ? $attrs.queryPerPage : null) ||
25;
$scope.query.where = $attrs.queryWhere && misc_1.isJSON($attrs.queryWhere) ? JSON.parse($attrs.queryWhere) : $scope.query.where || [];
$scope.query.images ||= { limit: 1 };
$scope.displayPerRow = 2;
$scope.displayPerRowText = 'two';
if ($attrs.displayPerRowText && lodash_1.isString($attrs.displayPerRowText)) {
$scope.displayPerRowText = $attrs.displayPerRowText;
$scope.displayPerRow = $scope.displayPerRowText === 'one' ? 1 : $scope.displayPerRowText === 'two' ? 2 :
$scope.displayPerRowText === 'three' ? 3 : $scope.displayPerRowText === 'four' ? 4 : 2;
}
else if ($attrs.displayPerRow && (lodash_1.isString($attrs.displayPerRow) || lodash_1.isNumber($attrs.displayPerRow))) {
$scope.displayPerRow = lodash_1.isString($attrs.displayPerRow) ? parseInt($attrs.displayPerRow, 10) : $attrs.displayPerRow;
$scope.displayPerRowText = $scope.displayPerRow === 1 ? 'one' : $scope.displayPerRow === 2 ? 'two' :
$scope.displayPerRow === 3 ? 'three' : $scope.displayPerRow === 4 ? 'four' : 'two';
}
$scope.displayOrderOptions = $attrs.displayOrderOptions && misc_1.isJSON($attrs.displayOrderOptions) ?
JSON.parse($attrs.displayOrderOptions) : true;
$scope.displayPager =
$attrs.displayPager ? (misc_1.isJSON($attrs.displayPager) ? JSON.parse($attrs.displayPager) :
$attrs.displayPager) : true;
$scope.hideDisclaimer = $attrs.hideDisclaimer && misc_1.isJSON($attrs.hideDisclaimer) ?
JSON.parse($attrs.hideDisclaimer) : false;
if (lodash_1.isArray($scope.query.where)) {
delete $scope.query.where;
}
const startingQuery = $scope.query.where || {};
startingQuery.Status ??= ['Active', 'Contract'];
startingQuery.ListingType ??= ['House', 'Condo'];
$scope.query.where = lodash_1.extend(Idx.getDefaultWhereOptions(), startingQuery || {});
defaultQuery = JSON.parse(JSON.stringify($scope.query.where));
lastQuery = {};
if ($scope.query.order) {
defaultQuery.Order = $scope.query.order;
}
$scope.orderOptions ??= [
{ name: 'Highest Price', value: ['-BestPrice'] },
{ name: 'Lowest Price', value: ['BestPrice'] },
{ name: 'Recently Updated', value: ['-ModificationTimestamp'] },
{ name: 'Recently Sold', value: ['-CloseDate'] },
{ name: 'Status + Price', value: ['Status', '-BestPrice'] },
{ name: 'Status + Recent', value: ['Status', '-ModificationTimestamp'] }
];
$scope.googleApiKey = $attrs.googleApiKey || null;
$scope.contactName = $attrs.contactName || null;
$scope.contactEmail = $attrs.contactEmail || null;
$scope.contactPhone = $attrs.contactPhone || null;
$scope.mapMarkers = [];
Idx.registerListInstance($scope.elementId, moduleName, $scope);
let urlQuery = {
Listing: {},
Search: {}
};
if ($scope.urlLoad) {
Idx.setUrlOptions('Search', JSON.parse(JSON.stringify(defaultQuery)));
urlQuery = Idx.getOptionsFromUrl();
if (urlQuery.hasOwnProperty('Listing') &&
urlQuery.Listing.hasOwnProperty('service') &&
urlQuery.Listing.ListingKey) {
$scope.displayModelDetails(urlQuery.Listing);
}
$scope.Idx.ensureItemsAreArrays($scope.query.where, [
'City',
'eCity',
'CountyOrParish',
'eCountyOrParish',
'MLSAreaMajor',
'eMLSAreaMajor',
'Neighborhood',
'eNeighborhood',
'PostalCode',
'OfficeNumber',
'AgentLicense',
'ListingId'
]);
}
if ($scope.searchOnLoad) {
const searchQuery = {
where: lodash_1.clone(urlQuery.Search)
};
await $scope.search(searchQuery, false, false);
}
$scope.$applyAsync(() => {
$scope.initialized = true;
Idx.emit('init', $scope);
});
};
this.$onInit = () => {
$scope.Idx = Idx;
$scope.collection = new collection_1.Collection({});
let initNow = true;
if (Object.prototype.hasOwnProperty.call($attrs.$attr, 'initNow')) {
initNow = misc_1.isJSON($attrs.initNow) ? JSON.parse($attrs.initNow) : false;
}
if (initNow) {
init().then();
return;
}
const stopWatchingInitNow = $scope.$watch('$ctrl.initNow', (initNowCtrl) => {
if (initNowCtrl !== true) {
return;
}
if (!$scope.initialized) {
init().then();
}
stopWatchingInitNow();
});
};
$scope.$watch('collection.models', () => {
if ($scope.collection.completed) {
Idx.emit('collectionUpdated', $scope, $scope.collection);
}
});
$scope.getOtherPresetFilterCount = () => {
const currentWhere = $scope.query.where;
let filterCounts = lodash_1.compact(lodash_1.union(currentWhere.OfficeNumber, currentWhere.AgentLicense, currentWhere.ListingId)).length;
if (currentWhere.OpenHouseOnly) {
filterCounts++;
}
return filterCounts;
};
$scope.resetLocationQuery = () => {
$scope.query.where.Location = '';
$scope.query.where.eLocation = '';
$scope.query.where.City = [];
$scope.query.where.eCity = [];
$scope.query.where.CountyOrParish = [];
$scope.query.where.eCountyOrParish = [];
$scope.query.where.MLSAreaMajor = [];
$scope.query.where.eMLSAreaMajor = [];
$scope.query.where.Neighborhood = [];
$scope.query.where.eNeighborhood = [];
$scope.query.where.PostalCode = [];
$scope.query.where.ListingId = [];
$scope.query.where.AgentLicense = [];
$scope.query.where.OfficeNumber = [];
};
$scope.getPageModels = () => {
const listings = [];
const models = $scope.collection.models;
models.slice(($scope.query.perPage * ($scope.query.page - 1)), ($scope.query.perPage * $scope.query.page)).forEach((listing) => {
listings.push(listing);
});
return listings;
};
$scope.scrollToModel = (model) => {
$anchorScroll(`${$scope.elementId}_${model._id}`);
};
$scope.hasQueryChanged = () => !lodash_1.isEqual(lodash_1.clone(lastQuery), lodash_1.clone($scope.query));
$scope.search = $scope.searchProperties = async (query, refresh, updateUrl) => $q(async (resolve) => {
if ($scope.collection.pending) {
$scope.query = lodash_1.cloneDeep(lastQuery);
resolve([]);
return;
}
query ??= lodash_1.clone($scope.query) || {};
query.where ??= {};
let urlWhere = lodash_1.clone(query.where) || {};
updateUrl = updateUrl === false ? updateUrl : $scope.urlLoad === false ? $scope.urlLoad : true;
if (Object.keys(query.where).length > 0) {
delete ($scope.query.where);
$scope.query.where = query.where;
}
else {
urlWhere = lodash_1.clone($scope.query.where) || {};
}
if (!lodash_1.isEmpty(query.where.Location) ||
!lodash_1.isEmpty(query.where.eLocation)) {
query.where.City = [];
query.where.eCity = [];
query.where.UnparsedAddress = '';
query.where.Neighborhood = [];
query.where.eNeighborhood = [];
query.where.CityRegion = [];
query.where.eCityRegion = [];
query.where.PostalCode = [];
query.where.MLSAreaMajor = [];
query.where.eMLSAreaMajor = [];
query.where.SubdivisionName = [];
query.where.eSubdivisionName = [];
}
if (query.where.page) {
query.page = query.where.page;
delete query.where.page;
}
if (query.where.Page) {
query.page = query.where.Page;
delete query.where.Page;
}
if (query.page) {
$scope.query.page = query.page;
}
if (refresh) {
$scope.query.page = 1;
}
if ($scope.query.page) {
urlWhere.Page = $scope.query.page;
}
if (urlWhere.Page <= 1) {
delete (urlWhere.Page);
}
if (query.where.order) {
query.order = query.where.order;
delete query.where.order;
}
if (query.where.Order) {
query.order = query.where.Order;
delete query.where.Order;
}
if (query.order) {
$scope.query.order = query.order;
}
if ($scope.query.order && $scope.query.order.length > 0) {
urlWhere.Order = $scope.query.order;
}
if (query.hasOwnProperty('service') &&
!lodash_1.isNil(query.service)) {
$scope.query.service = query.service;
}
if ($scope.hasQueryChanged()) {
Idx.setUrlOptions('Search', urlWhere);
if (updateUrl) {
Idx.refreshUrlOptions(defaultQuery);
}
Idx.emit('searching', $scope, lodash_1.clone($scope.query));
try {
const results = await Idx.fetchProperties($scope.elementId, 'collection', $scope.query, refresh);
lastQuery = lodash_1.cloneDeep($scope.query);
Idx.emit('searched', $scope, lodash_1.clone($scope.query));
resolve(results);
}
catch (e) {
console.error('Unable to fetchProperties:', e);
}
}
});
$scope.pageChange = async (pageNumber, ev) => {
if ($scope.collection.pending) {
return;
}
Idx.emit('pageChanging', $scope, lodash_1.clone($scope.query.page));
if (ev) {
ev.preventDefault();
}
$scope.query.page = pageNumber;
$anchorScroll($scope.elementId);
await $scope.search();
Idx.emit('pageChanged', $scope, lodash_1.clone($scope.query.page));
};
$scope.pageNext = async (ev) => {
if ($scope.collection.pending) {
return;
}
if (!$scope.query.page) {
$scope.query.page = 1;
}
if ($scope.collection.completed && $scope.query.page < $scope.collection.meta.data.totalPages) {
if (lodash_1.isString($scope.query.page)) {
$scope.query.page = parseInt($scope.query.page, 10);
}
await $scope.pageChange($scope.query.page + 1, ev);
}
};
$scope.pagePrevious = async (ev) => {
if ($scope.collection.pending) {
return;
}
if (!$scope.query.page) {
$scope.query.page = 1;
}
if ($scope.collection.completed && $scope.query.page > 1) {
if (lodash_1.isString($scope.query.page)) {
$scope.query.page = parseInt($scope.query.page, 10);
}
const prev = $scope.query.page - 1 || 1;
await $scope.pageChange(prev, ev);
}
};
$scope.orderChange = async (order, ev) => {
if ($scope.collection.pending) {
return;
}
Idx.emit('orderChanging', $scope, lodash_1.clone(order));
if (ev) {
ev.preventDefault();
}
$scope.query.order = order;
await $scope.search(null, true, true);
Idx.emit('orderChanged', $scope, lodash_1.clone(order));
};
$scope.getOrderOptions = () => {
const options = {};
$scope.orderOptions.forEach((orderOption) => {
switch (orderOption.name) {
case 'Recently Sold': {
if ($scope.query.where.Status &&
$scope.query.where.Status.includes('Closed')) {
options[orderOption.name] = orderOption.value;
}
break;
}
case 'Status': {
if ($scope.query.where.Status &&
$scope.query.where.Status.length > 1) {
options[orderOption.name] = orderOption.value;
}
break;
}
default: {
options[orderOption.name] = orderOption.value;
}
}
});
return options;
};
$scope.getOrderName = () => {
let name;
if ($scope.query.order !== '' &&
!lodash_1.isEmpty($scope.query.order)) {
for (const index in $scope.orderOptions) {
if ($scope.orderOptions.hasOwnProperty(index) &&
lodash_1.isEqual($scope.orderOptions[index].value, $scope.query.order)) {
name = $scope.orderOptions[index].name;
break;
}
}
}
return name;
};
$scope.getDetailsURL = (property) => $scope.detailsLinkUrl + '#!/Listing/' + property._ServiceId + '/' + property.ListingKey + '/';
$scope.getStreetAddress = (property) => $scope.Idx.getStreetAddress(property);
$scope.getGoogleMapsKey = () => {
return $scope.googleApiKey || Idx.getGoogleMapsKey();
};
$scope.getMLSVariables = (reset) => {
if (!mlsVariables || Object.keys(mlsVariables).length === 0 || reset) {
mlsVariables = {};
let mlsServicesRequested = null;
if ($scope.query &&
(lodash_1.isNumber($scope.query.service) ||
!lodash_1.isEmpty($scope.query.service))) {
if (!lodash_1.isArray($scope.query.service)) {
$scope.query.service = [$scope.query.service];
}
mlsServicesRequested = $scope.query.service;
}
Idx.getMLSVariables(mlsServicesRequested).forEach((service) => {
mlsVariables[service.id] = service;
});
}
return Object.values(mlsVariables);
};
$scope.getMLSName = (serviceId) => {
$scope.getMLSVariables();
let name = 'MLS';
if (mlsVariables[serviceId]) {
name = mlsVariables[serviceId].name;
}
return name;
};
$scope.getMLSLogo = (serviceId, size = 'default') => {
$scope.getMLSVariables();
let logo;
if (mlsVariables[serviceId]) {
logo = lodash_1.get(mlsVariables[serviceId].logo, size) || lodash_1.get(mlsVariables[serviceId].logo, 'default');
}
return logo;
};
$scope.highlightModel = (model, timeout) => {
timeout ??= 0;
model._unmapped ??= {};
$scope.$applyAsync(() => {
model._unmapped._highlight = true;
});
if (timeout > 0) {
$timeout(() => {
$scope.unhighlightModel(model);
}, timeout);
}
};
$scope.unhighlightModel = (model) => {
if (model) {
model._unmapped ??= {};
$scope.$applyAsync(() => {
model._unmapped._highlight = false;
});
}
};
$scope.displayModelDetails = (model, ev) => {
if (ev) {
ev.preventDefault();
}
if ($scope.detailsLinkPopup === true) {
const templateOptions = {
'element-id': 'property_detail_popup_' + model.ListingKey,
service: model._ServiceId,
'listing-key': model.ListingKey,
'default-list-options': JSON.stringify(defaultQuery),
'page-title': true,
'url-load': $scope.urlLoad
};
if ($scope.getGoogleMapsKey()) {
templateOptions['google-api-key'] = $scope.getGoogleMapsKey();
}
if ($scope.contactName) {
templateOptions['contact-name'] = $scope.contactName;
}
if ($scope.contactEmail) {
templateOptions['contact-email'] = $scope.contactEmail;
}
if ($scope.contactPhone) {
templateOptions['contact-phone'] = $scope.contactPhone;
}
if ($scope.detailsHideVariables.length > 0) {
templateOptions['hide-variables'] = JSON.stringify($scope.detailsHideVariables);
}
if ($scope.preferredStatus) {
templateOptions['preferred-status'] = $scope.preferredStatus;
}
if ($scope.detailsTemplate) {
templateOptions.template = $scope.detailsTemplate;
}
let template = `<md-dialog class="stratus-idx-property-list-dialog" aria-label="${$scope.getStreetAddress(model)} Details">` +
`<div class="popup-close-button-container">` +
`<div aria-label="Close Popup" class="close-button" data-ng-click="closePopup()" aria-label="Close Details Popup"></div>` +
`</div>` +
'<stratus-idx-property-details ';
lodash_1.forEach(templateOptions, (optionValue, optionKey) => {
template += `data-${optionKey}='${optionValue}'`;
});
template +=
'></stratus-idx-property-details>' +
'</md-dialog>';
$mdDialog.show({
template,
parent: angular_1.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
fullscreen: true,
scope: $scope,
preserveScope: true,
controller: ($scope, $mdDialog) => {
$scope.closePopup = () => {
if ($mdDialog) {
$mdDialog.hide();
Idx.setUrlOptions('Listing', {});
if ($scope.urlLoad) {
Idx.refreshUrlOptions(defaultQuery);
}
Idx.setPageTitle();
$timeout(() => Idx.unregisterDetailsInstance('property_detail_popup', 'property'), 10);
}
};
}
})
.then(() => {
}, () => {
Idx.setUrlOptions('Listing', {});
if ($scope.urlLoad) {
Idx.refreshUrlOptions(defaultQuery);
}
Idx.setPageTitle();
$timeout(() => Idx.unregisterDetailsInstance('property_detail_popup', 'property'), 10);
});
}
else {
$window.open($scope.getDetailsURL(model), $scope.detailsLinkTarget);
}
};
$scope.on = (emitterName, callback) => Idx.on($scope.elementId, emitterName, callback);
$scope.remove = () => {
};
},
templateUrl: ($attrs) => `${localDir}${$attrs.template || componentName}.component${min}.html`
};
}
};
});
//# sourceMappingURL=list.component.js.map