+
0"
+ class="search">
+
+
+
+
+
+
+
+
-
-
-
-
+ search
+ 0"
+ [disableRipple]="true"
+ mat-icon-button
+ (click)="searchTermControl.reset()"
+ matSuffix>
+ close
+
+
-
-
diff --git a/libs/route-pages/blog/src/pages/blog-page/blog-page.component.scss b/libs/route-pages/blog/src/pages/blog-page/blog-page.component.scss
index 13faf2e6a..44bd795fa 100644
--- a/libs/route-pages/blog/src/pages/blog-page/blog-page.component.scss
+++ b/libs/route-pages/blog/src/pages/blog-page/blog-page.component.scss
@@ -15,7 +15,7 @@ $bp-large: 1024px;
}
.first-articles {
- width: 30%;
+ width: 32%;
display: none;
flex-direction: column;
max-height: 100%;
@@ -35,4 +35,86 @@ $bp-large: 1024px;
::ng-deep .pink_swiper .swiper-slide {
padding-top: 0;
+}
+
+.search {
+ width: 32%;
+}
+
+::ng-deep .cdk-overlay-pane {
+ .mat-mdc-autocomplete-panel {
+ background-color: #515151;
+ padding-top: 0;
+ padding-bottom: 16px;
+ max-height: 306px
+ }
+
+ .mat-mdc-optgroup {
+ color: #E3E3E3;
+ }
+
+ .mat-mdc-optgroup-label {
+ min-height: auto;
+ margin-bottom: 8px;
+ margin-top: 16px;
+ }
+
+ .mat-mdc-option {
+ background-color: #343434;
+ margin: 0 16px 4px;
+ color: #E3E3E3;
+ border-radius: 4px;
+ }
+
+ .mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple) {
+ padding: 10px 12px;
+ }
+
+ .mat-mdc-option:hover:not(.mdc-list-item--disabled) {
+ background-color: rgba(226, 78, 99, 1) !important;
+ color: rgba(255, 255, 255, 1) !important;
+ }
+
+ .mat-mdc-option:focus:not(.mdc-list-item--disabled) {
+ background-color: rgba(226, 78, 99, 1) !important;
+ color: rgba(255, 255, 255, 1) !important;
+ }
+
+ .mat-mdc-option:active:not(.mdc-list-item--disabled) {
+ background-color: rgba(226, 78, 99, 1) !important;
+ color: rgba(255, 255, 255, 1) !important;
+ }
+
+ .mat-mdc-option:focus.mdc-list-item, .mat-mdc-option.mat-mdc-option-active.mdc-list-item {
+ background-color: rgba(226, 78, 99, 1) !important;
+ color: rgba(255, 255, 255, 1) !important;
+ }
+}
+
+::ng-deep .mat-icon {
+ color: #8C8C8C;
+}
+
+::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) {
+ background-color: #515151 !important;
+}
+
+::ng-deep .mdc-text-field__input:focus {
+ box-shadow: none;
+}
+
+::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) .mdc-line-ripple::after {
+ border-bottom-color: transparent !important;
+}
+
+::ng-deep .mat-mdc-autocomplete-trigger {
+ color: rgba(255, 255, 255, 1) !important;
+}
+
+::ng-deep .mdc-text-field--filled:not(.mdc-text-field--disabled) .mdc-text-field__input {
+ caret-color: white !important;
+}
+
+::ng-deep .mat-mdc-input-element::placeholder{
+ color: #8C8C8C !important;
}
\ No newline at end of file
diff --git a/libs/route-pages/blog/src/pages/blog-page/blog-page.component.ts b/libs/route-pages/blog/src/pages/blog-page/blog-page.component.ts
index d03b7ae92..658aa1352 100644
--- a/libs/route-pages/blog/src/pages/blog-page/blog-page.component.ts
+++ b/libs/route-pages/blog/src/pages/blog-page/blog-page.component.ts
@@ -1,12 +1,19 @@
import { Component, OnDestroy } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
-import { filter } from 'rxjs/operators';
+import { filter, map } from 'rxjs/operators';
import { forkJoin, Subscription } from 'rxjs';
import { GetArticlesService, IArticle, titleRefactoring } from '@valor-software/common-docs';
import SwiperCore, { Pagination, SwiperOptions } from 'swiper';
+import { FormControl } from '@angular/forms';
+import { Domains } from '../../models';
SwiperCore.use([Pagination]);
+interface GroupedArticles {
+ tag: string;
+ articles: IArticle[];
+}
+
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'blog-page',
@@ -30,6 +37,9 @@ export class BlogPageComponent implements OnDestroy {
}
};
+ groupedAndFilteredArticles: GroupedArticles[] = [];
+ searchTermControl = new FormControl('');
+
constructor(
private readonly router: Router,
private readonly getArticlesServ: GetArticlesService,
@@ -43,14 +53,14 @@ export class BlogPageComponent implements OnDestroy {
}));
}
- getFirstProjects
(value: Type[]): Type[] {
- return value.slice(0, 4);
- }
-
getRouteLink(link: string): any {
return titleRefactoring(link);
}
+ navigateToArticle(title: string): void {
+ this.router.navigate(['..', 'articles', this.getRouteLink(title)]);
+ }
+
ngOnDestroy() {
this.$generalSubscription.unsubscribe();
}
@@ -65,14 +75,55 @@ export class BlogPageComponent implements OnDestroy {
this.firstArticles = this.getFirstProjects(res);
this.activeArticle = this.firstArticles[0];
this.filterFirstItems();
+ this._observeSearchValueChanges();
}
})
);
}
+ private getFirstProjects(value: Type[]): Type[] {
+ return value.slice(0, 4);
+ }
+
private filterFirstItems() {
if (this.activeArticle) {
this.firstArticles = this.firstArticles?.filter(item => item !== this.activeArticle);
}
}
+
+ private _filterAndGroupArticles(articles: IArticle[], searchTerm: string): GroupedArticles[] {
+ if (!searchTerm || searchTerm.length === 0) {
+ return [];
+ }
+
+ const filteredArticles = articles.filter(article =>
+ article.title.toLowerCase().includes(searchTerm?.toLowerCase())
+ );
+ const groupedByTag: Map = new Map();
+
+ filteredArticles.forEach(article => {
+ article.domains.forEach(domain => {
+ const existingArticles = groupedByTag.get(domain) || [];
+ groupedByTag.set(domain, [...existingArticles, article]);
+ });
+ });
+
+ return Array.from(groupedByTag.entries()).map(
+ ([tag, articles]) => ({
+ tag: Domains[tag] || tag,
+ articles
+ })
+ );
+ }
+
+ private _observeSearchValueChanges(): void {
+ this.$generalSubscription.add(
+ this.searchTermControl.valueChanges.pipe(
+ map(term => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.groupedAndFilteredArticles = this._filterAndGroupArticles(this.articles, term!);
+ })
+ ).subscribe()
+ );
+ }
}
\ No newline at end of file
diff --git a/libs/route-pages/blog/src/pipes/highlight.pipe.ts b/libs/route-pages/blog/src/pipes/highlight.pipe.ts
new file mode 100644
index 000000000..5555e7ef1
--- /dev/null
+++ b/libs/route-pages/blog/src/pipes/highlight.pipe.ts
@@ -0,0 +1,23 @@
+import { Pipe, PipeTransform } from '@angular/core';
+import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
+
+@Pipe({
+ name: 'highlightMatchingLetters',
+})
+export class HighlightMatchingLettersPipe implements PipeTransform {
+ constructor(private readonly domSanitizer: DomSanitizer) {
+ }
+
+ transform(value: string, searchTerm: string | null): SafeHtml {
+ if (!searchTerm || !value) {
+ return this.domSanitizer.bypassSecurityTrustHtml(value);
+ }
+
+ const regex = new RegExp(searchTerm, 'gi');
+ const highlightedValue = value.replace(regex,
+ match => `${match} `
+ );
+
+ return this.domSanitizer.bypassSecurityTrustHtml(highlightedValue);
+ }
+}
\ No newline at end of file
diff --git a/libs/route-pages/blog/src/pipes/index.ts b/libs/route-pages/blog/src/pipes/index.ts
new file mode 100644
index 000000000..05c679a62
--- /dev/null
+++ b/libs/route-pages/blog/src/pipes/index.ts
@@ -0,0 +1,2 @@
+export * from './highlight.pipe';
+export * from './domain-name.pipe';
diff --git a/libs/route-pages/blog/tsconfig.lib.json b/libs/route-pages/blog/tsconfig.lib.json
index 5aebe84f5..754fdf6e7 100644
--- a/libs/route-pages/blog/tsconfig.lib.json
+++ b/libs/route-pages/blog/tsconfig.lib.json
@@ -7,7 +7,7 @@
"declarationMap": true,
"inlineSources": true,
"types": [],
- "lib": ["dom", "es2018"],
+ "lib": ["dom", "ES2019"],
"useDefineForClassFields": false
},
"exclude": [
diff --git a/package.json b/package.json
index 8729b076a..4fd6618d6 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"asciidoctor": "^2.2.6",
"glob": "^8.0.3",
"img-comparison-slider": "^7.6.0",
+ "material-icons": "^1.13.12",
"ng-recaptcha": "^9.0.0",
"ngx-cookie-service": "^15.0.0",
"rxjs": "~6.6.3",
@@ -95,4 +96,4 @@
"typescript": "5.0.4",
"xmlbuilder": "^15.1.1"
}
-}
\ No newline at end of file
+}
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 2dfbea4d7..784c2dcfe 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -11,7 +11,7 @@
"target": "es2015",
"module": "esnext",
"lib": [
- "es2017",
+ "ES2019",
"dom"
],
"types": [
diff --git a/yarn.lock b/yarn.lock
index 5130c2faf..8d7bdf842 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9259,6 +9259,11 @@ marked@^4.0.12:
resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
+material-icons@^1.13.12:
+ version "1.13.12"
+ resolved "https://registry.yarnpkg.com/material-icons/-/material-icons-1.13.12.tgz#eed4082bf0426642edeb027e75397e3064adc536"
+ integrity sha512-/2YoaB79IjUK2B2JB+vIXXYGtBfHb/XG66LvoKVM5ykHW7yfrV5SP6d7KLX6iijY6/G9GqwgtPQ/sbhFnOURVA==
+
mdn-data@2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"