@salesforcedevs/dw-components
Advanced tools
Comparing version
{ | ||
"name": "@salesforcedevs/dw-components", | ||
"version": "1.3.323", | ||
"version": "1.3.324-alpha", | ||
"description": "Lightning web components for https://developer.salesforce.com", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
import { api, LightningElement } from "lwc"; | ||
import qs from "query-string"; | ||
import uniqBy from "lodash.uniqby"; | ||
import orderBy from "lodash.orderby"; | ||
import cloneDeep from "lodash.clonedeep"; | ||
import { DropdownItem, CodeSample } from "typings/custom"; | ||
import { CodeSample } from "typings/custom"; | ||
import { toJson } from "dxUtils/normalizers"; | ||
import { track } from "dxUtils/analytics"; | ||
const PRODUCT_FILTER_ALL_PRODUCTS = "all products"; | ||
const WAIT_TIME = 500; | ||
const DEFAULT_BUTTON_TEXT = "Explore on GitHub"; | ||
export default class CodeSamplesGrid extends LightningElement { | ||
private searchTerm = ""; | ||
private selectedProductFilter: string[] | null = null; | ||
private selectedTypeFilter: string[] | null = null; | ||
private selectedSourceFilter: string[] | null = null; | ||
private page = 1; | ||
private pageSize = 9; | ||
private startingRecord = 1; | ||
private endingRecord = 24; | ||
private totalRecountCount = 0; | ||
private totalPages = 1; | ||
private _featuredCodeSample?: CodeSample = undefined; | ||
private _samplesList: CodeSample[] = []; | ||
private _typesFiltersList: DropdownItem[] = []; | ||
private _sourceFiltersList: DropdownItem[] = []; | ||
private _productFiltersList: DropdownItem[] = []; | ||
private matchDesktop!: MediaQueryList; | ||
private matchMobile!: MediaQueryList; | ||
private matchMobileSmall!: MediaQueryList; | ||
private deviceType: "desktop" | "mobile" | "mobile-small" = "desktop"; | ||
private _searchTimeout?: number; | ||
private target = "_blank"; | ||
@@ -38,92 +15,7 @@ private isDesktop = "(min-width: 1024px)"; | ||
private isMobileSmall = "(max-width: 400px)"; | ||
private showSourcesFilter = false; | ||
private filteredItemsSelected: boolean = false; | ||
private filtersDefaultValue = { | ||
selectedSourceFilter: [] as string[], | ||
selectedTypeFilter: [] as string[], | ||
selectedProductFilter: [] as string[], | ||
searchTerm: "", | ||
page: "1" | ||
}; | ||
connectedCallback(): void { | ||
this.matchDesktop = window.matchMedia(this.isDesktop); | ||
this.matchDesktop.addEventListener("change", this.handleView); | ||
this.matchMobile = window.matchMedia(this.isMobile); | ||
this.matchMobile.addEventListener("change", this.handleView); | ||
this.matchMobileSmall = window.matchMedia(this.isMobileSmall); | ||
this.matchMobileSmall.addEventListener("change", this.handleView); | ||
window.addEventListener("popstate", this.handleURLStateChange); | ||
if (this.matchDesktop.matches) { | ||
this.deviceType = "desktop"; | ||
} | ||
if (this.matchMobile.matches) { | ||
this.deviceType = "mobile"; | ||
} | ||
if (this.matchMobileSmall.matches) { | ||
this.deviceType = "mobile-small"; | ||
} | ||
this.evaluateQueryParams(false); | ||
console.log(this._samplesList); | ||
} | ||
handleURLStateChange(): void { | ||
this.evaluateQueryParams(true); | ||
this.scrollToTop(); | ||
} | ||
evaluateQueryParams(resetFilters: boolean): void { | ||
let page = "1"; | ||
if (resetFilters) { | ||
this.selectedSourceFilter = | ||
this.filtersDefaultValue.selectedSourceFilter; | ||
this.selectedTypeFilter = | ||
this.filtersDefaultValue.selectedTypeFilter; | ||
this.selectedProductFilter = | ||
this.filtersDefaultValue.selectedProductFilter; | ||
} | ||
const urlParams = new URLSearchParams(window.location.search); | ||
if (urlParams.toString()) { | ||
if (urlParams.has("source")) { | ||
this.selectedSourceFilter = urlParams.getAll("source"); | ||
} | ||
if (urlParams.has("type")) { | ||
this.selectedTypeFilter = urlParams.getAll("type"); | ||
} | ||
if (urlParams.get("service")) { | ||
this.selectedProductFilter = urlParams | ||
.get("service")! | ||
.split(","); | ||
} | ||
if (urlParams.get("filter_text")) { | ||
this.searchTerm = ( | ||
urlParams.get("filter_text") || "" | ||
).toLowerCase(); | ||
} | ||
if (urlParams.has("page")) { | ||
page = urlParams.get("page")!; | ||
} | ||
} | ||
this.calculatePagination(page, true); | ||
} | ||
disconnectedCallback(): void { | ||
this.matchDesktop.removeEventListener("change", this.handleView); | ||
this.matchMobile.removeEventListener("change", this.handleView); | ||
this.matchMobileSmall.removeEventListener("change", this.handleView); | ||
window.removeEventListener("popstate", this.handleURLStateChange); | ||
if (!this.filteredItemsSelected) { | ||
this.selectedProductFilter?.forEach((filter) => { | ||
track(document, "custEv_filterAbandoned", { | ||
click_text: filter, | ||
element_title: "CodeSamplesGrid", | ||
element_type: "filter abandoned", | ||
content_category: "filter" | ||
}); | ||
}); | ||
} | ||
} | ||
@api | ||
@@ -145,8 +37,6 @@ set featuredCodeSample(value: string) { | ||
buttonText: DEFAULT_BUTTON_TEXT, | ||
href: sample.href, | ||
imgSrc: sample.imgSrc, | ||
product: sample.product, | ||
type: sample.type, | ||
// source: sample.source, | ||
source: "none", | ||
githubLink: sample.githubLink, | ||
trailheadLink: sample.trailheadLink, | ||
img: sample.img, | ||
tags: sample.tags, | ||
target: this.target | ||
@@ -160,126 +50,6 @@ })); | ||
@api | ||
set products(value: string) { | ||
const productsFilters = toJson(value).map((sample: string) => ({ | ||
label: sample, | ||
value: sample.toLowerCase() | ||
})); | ||
this._productFiltersList = orderBy( | ||
uniqBy([...productsFilters] as any, "value"), | ||
["value"], | ||
["asc"] | ||
) as any[]; | ||
this.selectedProductFilter = this._productFiltersList.map( | ||
(filter) => filter.value | ||
); | ||
this.filtersDefaultValue.selectedProductFilter = cloneDeep( | ||
this.selectedProductFilter | ||
); | ||
} | ||
get products(): DropdownItem[] { | ||
return this._productFiltersList; | ||
} | ||
@api | ||
set types(value: string) { | ||
const typesFilter = toJson(value).map((sample: string) => ({ | ||
label: sample, | ||
value: sample.toLowerCase() | ||
})); | ||
this._typesFiltersList = orderBy( | ||
uniqBy([...typesFilter] as any, "value"), | ||
["value"], | ||
["asc"] | ||
) as any[]; | ||
this.selectedTypeFilter = this._typesFiltersList.map( | ||
(filter) => filter.value | ||
); | ||
this.filtersDefaultValue.selectedTypeFilter = cloneDeep( | ||
this.selectedTypeFilter | ||
); | ||
} | ||
get types(): DropdownItem[] { | ||
return this._typesFiltersList; | ||
} | ||
@api | ||
set sources(value: string) { | ||
const parsedValues = toJson(value); | ||
this.showSourcesFilter = parsedValues.length > 0; | ||
const sourcesFilter = parsedValues.map((sample: string) => ({ | ||
label: sample, | ||
value: sample.toLowerCase() | ||
})); | ||
this._sourceFiltersList = orderBy( | ||
uniqBy([...sourcesFilter] as any, "value"), | ||
["value"], | ||
["asc"] | ||
) as any; | ||
this.selectedSourceFilter = this._sourceFiltersList.map( | ||
(filter) => filter.value | ||
); | ||
this.filtersDefaultValue.selectedSourceFilter = cloneDeep( | ||
this.selectedSourceFilter | ||
); | ||
} | ||
get sources(): DropdownItem[] { | ||
return this._sourceFiltersList; | ||
} | ||
get filteredSamples(): CodeSample[] { | ||
return this.filterSamples([...this.samples]); | ||
} | ||
get currentPageSamples(): CodeSample[] { | ||
return this.filteredSamples.slice( | ||
this.startingRecord - 1, | ||
this.endingRecord | ||
); | ||
} | ||
get typesList(): DropdownItem[] { | ||
return this._typesFiltersList || []; | ||
} | ||
get productFiltersList(): DropdownItem[] { | ||
return this._productFiltersList || []; | ||
} | ||
get showEmptyState(): boolean { | ||
return !this.filteredSamples.length; | ||
} | ||
get tileColumns(): string { | ||
return this.deviceType === "desktop" ? "three" : "two"; | ||
return this.deviceType === "desktop" ? "two" : "one"; | ||
} | ||
get pagesToShow(): number { | ||
return this.deviceType === "mobile-small" ? 3 : 5; | ||
} | ||
get hidePagination(): boolean { | ||
return this.totalPages < 2; | ||
} | ||
get emptyStateSubtitle() { | ||
return ( | ||
"Sorry, no results were found for your search" + | ||
(this.searchTerm !== "" ? ` "${this.searchTerm}"` : "") | ||
); | ||
} | ||
get emptyStateBody() { | ||
return "Search Tips:"; | ||
} | ||
get emptyStateSuggestions() { | ||
return JSON.stringify([ | ||
"Please consider misspellings", | ||
"Try different search keywords" | ||
]); | ||
} | ||
handleView = (e: MediaQueryListEvent | MediaQueryList): void => { | ||
@@ -300,167 +70,2 @@ if (e.media === this.isDesktop && e.matches) { | ||
}; | ||
goToPage(e: CustomEvent): void { | ||
const page = e.detail; | ||
this.displayRecordsPerPage(page); | ||
this.setSearchParams("page", page ? page.toString() : "1"); | ||
this.scrollToTop(); | ||
} | ||
displayRecordsPerPage(page: number): void { | ||
this.page = page; | ||
this.startingRecord = | ||
page === 1 ? page : (page - 1) * this.pageSize + 1; | ||
this.endingRecord = this.pageSize * page; | ||
this.endingRecord = | ||
this.endingRecord > this.totalRecountCount | ||
? this.totalRecountCount | ||
: this.endingRecord; | ||
} | ||
handleSearchChange(event: CustomEvent): void { | ||
const value = event.detail; | ||
this.searchTerm = value.toLowerCase(); | ||
window.clearTimeout(this._searchTimeout); | ||
this._searchTimeout = window.setTimeout(() => { | ||
this.calculatePagination(); | ||
}, WAIT_TIME); | ||
} | ||
handleSourceFilterChange(event: CustomEvent): void { | ||
this.selectedSourceFilter = event.detail.value; | ||
this.calculatePagination(); | ||
} | ||
handleTypeFilterChange(event: CustomEvent): void { | ||
this.selectedTypeFilter = event.detail.value; | ||
this.calculatePagination(); | ||
} | ||
handleProductFilterChange(event: CustomEvent): void { | ||
if (event.detail.checkedValue === PRODUCT_FILTER_ALL_PRODUCTS) { | ||
if (event.detail.checked) { | ||
this.selectedProductFilter = this.productFiltersList.map( | ||
(filter) => filter.value | ||
); | ||
} else { | ||
this.selectedProductFilter = []; | ||
} | ||
} else { | ||
let newList = event.detail.value; | ||
if (!event.detail.checked) { | ||
newList = newList.filter( | ||
(val: typeof PRODUCT_FILTER_ALL_PRODUCTS) => | ||
val !== PRODUCT_FILTER_ALL_PRODUCTS | ||
); | ||
} | ||
this.selectedProductFilter = newList; | ||
} | ||
this.calculatePagination(); | ||
this.filteredItemsSelected = false; | ||
} | ||
handleLanguageFilterChange(event: CustomEvent): void { | ||
this.selectedTypeFilter = event.detail.value; | ||
this.setSearchParams("type", this.selectedTypeFilter); | ||
} | ||
filterSamples(samples: CodeSample[]): CodeSample[] { | ||
const filtered = samples | ||
.filter((contentItem) => { | ||
const matchesSearchTerm = | ||
contentItem.body.toLowerCase().includes(this.searchTerm) || | ||
contentItem.title.toLowerCase().includes(this.searchTerm); | ||
const matchesProductFilters = | ||
!this.selectedProductFilter || | ||
!this.selectedProductFilter.length || | ||
this.selectedProductFilter.includes( | ||
PRODUCT_FILTER_ALL_PRODUCTS | ||
) || | ||
(typeof contentItem.product === "string" && | ||
this.selectedProductFilter.includes( | ||
contentItem.product.toLowerCase() | ||
)); | ||
const matchesTypeFilters = | ||
!this.selectedTypeFilter || | ||
!this.selectedTypeFilter.length || | ||
(typeof contentItem.type === "string" && | ||
this.selectedTypeFilter.includes( | ||
contentItem.type.toLowerCase() | ||
)); | ||
const matchesSourceFilters = | ||
!this.selectedSourceFilter || | ||
!this.selectedSourceFilter.length || | ||
(typeof contentItem.source === "string" && | ||
this.selectedSourceFilter.includes( | ||
contentItem.source.toLowerCase() | ||
)); | ||
return ( | ||
matchesSearchTerm && | ||
matchesProductFilters && | ||
matchesTypeFilters && | ||
matchesSourceFilters | ||
); | ||
}) | ||
.sort((a: CodeSample, b: CodeSample) => { | ||
return a.title.localeCompare(b.title); | ||
}); | ||
return filtered; | ||
} | ||
calculatePagination(page?: string, skipSetSearchParams = false): void { | ||
if (page) { | ||
this.page = parseInt(page, 10) || 1; | ||
} | ||
this.totalRecountCount = this.filteredSamples.length; | ||
this.totalPages = Math.ceil(this.totalRecountCount / this.pageSize); | ||
this.displayRecordsPerPage(this.page); | ||
if (!skipSetSearchParams) { | ||
this.setSearchParams(); | ||
} | ||
} | ||
scrollToTop(): void { | ||
this.template | ||
.querySelector(".docs-grid-container")! | ||
.scrollIntoView({ behavior: "smooth" }); | ||
} | ||
setSearchParams(key?: string | null, val?: string[] | null): void { | ||
const service = | ||
this.selectedProductFilter!.length === | ||
this.productFiltersList.length | ||
? "" | ||
: this.selectedProductFilter!.join(","); | ||
const params: { [key: string]: any } = { | ||
filter_text: this.searchTerm, | ||
service, | ||
type: this.selectedTypeFilter, | ||
page: this.page.toString(), | ||
source: this.selectedSourceFilter | ||
}; | ||
if (key) { | ||
params[key] = key === "service" ? val!.join(",") : val; | ||
} | ||
for (const _key in params) { | ||
if (!params[_key]) { | ||
delete params[_key]; | ||
} | ||
} | ||
const searchParams = qs.stringify(params); | ||
const newurl = `${window.location.pathname}?${searchParams}`; | ||
window.history.pushState({ path: newurl }, "", newurl); | ||
} | ||
handleReadItClick() { | ||
this.filteredItemsSelected = true; | ||
this.selectedProductFilter?.forEach((filter) => { | ||
track(document, "custEv_filterApplied", { | ||
click_text: filter, | ||
click_url: `${window.location.origin}${filter}`, | ||
element_type: "filter applied", | ||
content_category: "filter" | ||
}); | ||
}); | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
500866
-2.65%9209
-3.14%2
100%