Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ import {HttpClientModule} from '@angular/common/http'
export const AppModule = ({providers, shellRouter}: {providers:any, shellRouter: Router}) => {
@NgModule({
declarations: [
AppComponent,
AutoAssetSrcDirective
AppComponent
],
exports: [AutoAssetSrcDirective],
imports: [
AutoAssetSrcDirective,
BrowserModule,
CommonModule,
HttpClientModule,
TranslateModule.forRoot({})
],
exports: [AutoAssetSrcDirective],
providers: [...providers, {provide: SHELL_ROUTER, useValue: shellRouter}],
bootstrap: []
})
Expand Down Expand Up @@ -52,4 +52,3 @@ export const AppModule = ({providers, shellRouter}: {providers:any, shellRouter:
}
return AppModule
}

4 changes: 4 additions & 0 deletions src/app/custom1-module/customComponentMappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { PayFinesComponent } from '../pay-fines/pay-fines.component';
import { TrafficResultLimitComponent } from '../traffic-result-limit/traffic-result-limit.component';
import { PickupFilterComponent } from '../pickup-filter/pickup-filter.component';
import { NdeViewItReorderComponent } from '../nde-view-it-reorder/nde-view-it-reorder.component';
import { NdeRequestReorderComponent } from '../nde-request-reorder/nde-request-reorder.component';
import { FilterAssistPanelComponent } from '../filter-assist-panel/filter-assist-panel.component';

// Define the map
export const selectorComponentMap = new Map<string, any>([
Expand All @@ -15,4 +17,6 @@ export const selectorComponentMap = new Map<string, any>([
['nde-search-no-results-before', TrafficResultLimitComponent],
['nde-formly-general-wrapper-bottom', PickupFilterComponent],
['nde-full-display-service-container-before', NdeViewItReorderComponent],
['nde-search-result-item-container-after', NdeRequestReorderComponent],
['nde-filters-group-before', FilterAssistPanelComponent],
]);
92 changes: 92 additions & 0 deletions src/app/filter-assist-panel/config/external-sources.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { SearchTarget } from '../models/search-target.model';

/**
* Helper function to extract and format search queries for external sources
* Converts Primo query format to simple search terms
* @param queries Array of Primo-formatted query strings
* @returns URL-encoded search string
*/
function buildSearchQuery(queries: string[]): string {
try {
let fullSearchQuery = '';

// Process each query element
queries.forEach((queryElement) => {
// Primo query format: "field,operator,searchTerm,boolean"
// Example: "any,contains,test search,AND"

const firstCommaIndex = queryElement.indexOf(',');
const secondCommaIndex = queryElement.indexOf(',', firstCommaIndex + 1);
let searchStr = queryElement.slice(secondCommaIndex + 1);

// Remove trailing boolean operators (,AND or ,OR)
if (searchStr.endsWith(',AND') || searchStr.endsWith(',OR')) {
const finalComma = searchStr.lastIndexOf(',');
searchStr = searchStr.slice(0, finalComma);
}

// Append to full query with space separator
fullSearchQuery = fullSearchQuery.concat(searchStr + ' ');
});

// Trim and encode for URL
return encodeURIComponent(fullSearchQuery.trim());
} catch (e) {
console.error('Error building search query:', e);
return '';
}
}

/**
* Configuration array of external search sources
* Each source can be clicked from the filter panel to search with current query
*/
export const EXTERNAL_SEARCH_SOURCES: SearchTarget[] = [
{
name: 'WorldCat',
nameHe: 'WorldCat',
url: 'https://kansasstateuniversity.on.worldcat.org/search?queryString=kw:',
img: 'assets/images/external-sources/worldcat-logo.png',
img_2: 'assets/images/external-sources/worldcat-logo.png',
alt: 'Worldcat',
mapping: (queries: string[], filters: string[]): string => {
return buildSearchQuery(queries);
}
},
{
name: 'Google Scholar',
nameHe: 'Google Scholar',
url: 'https://scholar.google.com/scholar?q=',
img: 'assets/images/external-sources/logo-googlescholar.png',
img_2: 'assets/images/external-sources/logo-googlescholar.png',
alt: 'Google Scholar',
mapping: (queries: string[], filters: string[]): string => {
return buildSearchQuery(queries);
}
},
{
name: 'EBSCO',
nameHe: 'EBSCO',
url: 'https://research.ebsco.com/c/b2utja/search/results?q=',
img: 'assets/images/external-sources/ebsco-logo-color-screen.png',
img_2: '',
alt: 'EBSCO',
mapping: (queries: string[], filters: string[]): string => {
return buildSearchQuery(queries);
}
}
// Crossref is commented out in the original - can be added later if needed
/*
{
name: 'Crossref',
nameHe: 'Crossref',
url: 'https://search.crossref.org/?from_ui=yes&q=',
img: 'assets/images/external-sources/crossref_logo_16_16.png',
img_2: 'assets/images/external-sources/crossref_logo_16_16.png',
alt: 'Crossref',
mapping: (queries: string[], filters: string[]): string => {
return buildSearchQuery(queries);
}
}
*/
];
49 changes: 49 additions & 0 deletions src/app/filter-assist-panel/filter-assist-panel.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<section
class="external-search-panel"
[attr.dir]="textDirection"
*ngIf="shouldRender && hasSearchQuery()"
role="complementary"
aria-label="External search options">

<h3 class="external-search-panel__title">
{{ panelTitle }}
</h3>

<ul class="external-search-panel__list" role="list">
<li
*ngFor="let source of externalSources"
class="external-search-panel__item">

<a
[href]="buildExternalUrl(source)"
target="_blank"
rel="noopener noreferrer"
class="external-search-panel__link"
[attr.aria-label]="'Search in ' + getSourceName(source) + ' (opens in new window)'">

<img
autoAssetSrc
[src]="source.img"
[alt]="source.alt"
class="external-search-panel__icon"
width="16"
height="16">

<span class="external-search-panel__name">
{{ getSourceName(source) }}
</span>

<svg
class="external-search-panel__external-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="12"
height="12"
fill="currentColor"
aria-hidden="true">
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/>
</svg>
</a>
</li>
</ul>
</section>
129 changes: 129 additions & 0 deletions src/app/filter-assist-panel/filter-assist-panel.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
.external-search-panel {
background: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 12px 16px;
margin-bottom: 16px;
font-family: 'Roboto', 'Helvetica Neue', Arial, sans-serif;
color: #424242;

// Title styling
&__title {
margin: 0 0 12px;
font-size: 0.875rem;
font-weight: 500;
color: #616161;
text-transform: uppercase;
letter-spacing: 0.5px;
}

// List container
&__list {
list-style: none;
margin: 0;
padding: 0;
}

// Individual list item
&__item {
margin: 0;
padding: 0;

&:not(:last-child) {
margin-bottom: 2px;
}
}

// Link styling
&__link {
display: flex;
align-items: center;
padding: 4px 12px;
text-decoration: none;
border-radius: 4px;
transition:
background-color 0.2s ease,
color 0.2s ease;
font-size: 0.875rem;
gap: 8px;
}

// Icon (logo) styling
&__icon {
flex-shrink: 0;
width: 16px;
height: 16px;
object-fit: contain;
vertical-align: middle;
}

// Source name text
&__name {
flex-grow: 1;
font-weight: 400;
line-height: 1.4;
}

// External link icon (arrow)
&__external-icon {
flex-shrink: 0;
opacity: 0.6;
transition: opacity 0.2s ease;

.external-search-panel__link:hover & {
opacity: 1;
}
}

// RTL support
&[dir='rtl'] {
.external-search-panel__link {
// Reverse flex direction for RTL
direction: rtl;
}

.external-search-panel__external-icon {
// Flip the external icon for RTL
transform: scaleX(-1);
}
}

// Responsive design for mobile
@media (max-width: 768px) {
padding: 10px 12px;

&__title {
font-size: 0.8125rem;
margin-bottom: 10px;
}

&__link {
padding: 6px 10px;
font-size: 0.8125rem;
}
}

// Dark mode support (if NDE implements it)
/* @media (prefers-color-scheme: dark) {
background: #2c2c2c;
border-color: #444;
color: #e0e0e0;

&__title {
color: #b0b0b0;
}

&__link {
color: #64b5f6;

&:hover {
background-color: #383838;
color: #90caf9;
}

&:active {
background-color: #1e3a5f;
}
}
} */
}
Loading
Loading