diff --git a/packages/Mediaco-overrides/Carousel-component/carousel.component.html b/packages/Mediaco-overrides/Carousel-component/carousel.component.html new file mode 100644 index 00000000..11caed7a --- /dev/null +++ b/packages/Mediaco-overrides/Carousel-component/carousel.component.html @@ -0,0 +1,15 @@ + diff --git a/packages/Mediaco-overrides/Carousel-component/carousel.component.scss b/packages/Mediaco-overrides/Carousel-component/carousel.component.scss new file mode 100644 index 00000000..a994a019 --- /dev/null +++ b/packages/Mediaco-overrides/Carousel-component/carousel.component.scss @@ -0,0 +1,95 @@ +:host { + display: block; + width: 100%; + min-width: 0; + max-width: 100vw; + overflow: hidden; + contain: content; +} + +.carousel-host-container { + width: 100%; + position: relative; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; + padding: 0 16px; + + h2 { + margin: 0; + font-size: 20px; + font-weight: 500; + } +} + +.carousel-scroll-area { + display: flex; + align-items: center; + width: 100%; + max-width: 100%; + height: 400px; + padding: 0; + overflow-x: auto; + overflow-y: hidden; + scroll-behavior: auto; + box-sizing: border-box; + box-sizing: border-box; + + &::-webkit-scrollbar { + display: none; + } + scrollbar-width: none; +} + +.card-wrapper { + flex: 0 0 200px; + height: 350px; + margin: 0 10px; + transition: + flex-basis 0.1s linear, + min-width 0.1s linear; + will-change: flex-basis, min-width; + min-width: 0; +} + +.inner-material-card { + width: 100%; + height: 100%; + padding: 0 !important; + overflow: hidden; + position: relative; + background: #000; + border-radius: 8px; + + img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; + } + + .card-overlay { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + padding: 16px; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.9)); + color: white; + + h3 { + margin: 0; + font-size: 16px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } +} diff --git a/packages/Mediaco-overrides/Carousel-component/carousel.component.ts b/packages/Mediaco-overrides/Carousel-component/carousel.component.ts new file mode 100644 index 00000000..19d1cee8 --- /dev/null +++ b/packages/Mediaco-overrides/Carousel-component/carousel.component.ts @@ -0,0 +1,133 @@ +import { + Component, + ElementRef, + ViewChildren, + QueryList, + AfterViewInit, + OnDestroy, + NgZone, + Input, + OnChanges, + SimpleChanges, + ViewChild +} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatDialog } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { GalleryGridComponent } from '../gallery-grid/gallery-grid.component'; + +@Component({ + selector: 'app-carousel', + standalone: true, + imports: [CommonModule, MatButtonModule, MatCardModule, MatIconModule], + templateUrl: './carousel.component.html', + styleUrls: ['./carousel.component.scss'] +}) +export class CarouselComponent implements AfterViewInit, OnDestroy, OnChanges { + @Input() data: any[] = []; + @ViewChildren('cardItem') cardItems!: QueryList; + @ViewChild('scrollContainer') scrollContainer!: ElementRef; + + originalItems: any[] = []; + displayItems: any[] = []; + + constructor( + private ngZone: NgZone, + private dialog: MatDialog + ) {} + + ngOnChanges(changes: SimpleChanges) { + if (changes['data'] && this.data) { + this.buildCarouselItems(); + } + } + + buildCarouselItems() { + const mappedData = this.data.map((item, index) => { + return { + title: item.Carouselheading || item.Description || 'Untitled', + img: item.ImageURL, + ...item + }; + }); + this.originalItems = mappedData; + let loopList = [...mappedData]; + // If you have 2 items, we duplicate them until we have at least 12. + const MIN_ITEMS = 12; + if (loopList.length > 0) { + while (loopList.length < MIN_ITEMS) { + loopList = [...loopList, ...loopList]; + } + } + //CREATE 3 SETS: [Left Buffer] [Middle (Active)] [Right Buffer] + this.displayItems = [...loopList, ...loopList, ...loopList]; + } + + ngAfterViewInit() { + this.ngZone.runOutsideAngular(() => { + const container = this.scrollContainer?.nativeElement; + if (container) { + container.addEventListener('scroll', this.onScroll.bind(this)); + setTimeout(() => { + if (container.scrollWidth > 0) { + const singleSetWidth = container.scrollWidth / 3; + container.scrollLeft = singleSetWidth; + this.onScroll({ target: container } as any); + } + }, 50); + } + }); + } + + ngOnDestroy() { + const container = this.scrollContainer?.nativeElement; + if (container) { + container.removeEventListener('scroll', this.onScroll.bind(this)); + } + } + + onScroll(event: Event) { + const container = event.target as HTMLElement; + if (!container) return; + + requestAnimationFrame(() => { + const totalWidth = container.scrollWidth; + const singleSetWidth = totalWidth / 3; + const currentScroll = container.scrollLeft; + + if (currentScroll < 100) { + container.scrollLeft = currentScroll + singleSetWidth; + } else if (currentScroll >= singleSetWidth * 2 - 100) { + container.scrollLeft = currentScroll - singleSetWidth; + } + const containerRect = container.getBoundingClientRect(); + if (containerRect.width === 0) return; + + this.cardItems.forEach(item => { + const el = item.nativeElement; + const rect = el.getBoundingClientRect(); + const cardCenter = rect.left - containerRect.left + rect.width / 2; + const containerCenter = containerRect.width / 2; + const distance = Math.abs(containerCenter - cardCenter); + + const activeZone = 400; + const minWidth = 200; + const maxWidth = 500; + let currentWidth = minWidth; + let opacity = 0.7; + + if (distance < activeZone) { + const factor = 1 - distance / activeZone; + currentWidth = minWidth + (maxWidth - minWidth) * factor; + opacity = 0.7 + 0.3 * factor; + } + + el.style.flexBasis = `${currentWidth}px`; + el.style.minWidth = `${currentWidth}px`; + el.style.opacity = `${opacity}`; + }); + }); + } +} diff --git a/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.html b/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.html new file mode 100644 index 00000000..270722e1 --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.html @@ -0,0 +1,19 @@ +
+
+

All Content

+ +
+ +
+
+ Item Image +

{{ item.Carouselheading }}

+
+
+ +
+ +
+
diff --git a/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.scss b/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.scss new file mode 100644 index 00000000..1b55fd5f --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/gallery-grid-component.scss @@ -0,0 +1,88 @@ +:host { + display: block; + height: 100%; + display: flex; + flex-direction: column; + box-sizing: border-box; +} + +.dialog-content { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} + +.dialog-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 24px; + border-bottom: 1px solid #e0e0e0; + background: #fff; + flex-shrink: 0; + + h2 { + margin: 0; + font-size: 22px; + font-weight: 500; + } +} + +.grid-container { + flex: 1; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 20px; + padding: 24px; + overflow-y: auto; +} + +.grid-item { + border: 1px solid #e0e0e0; + border-radius: 8px; + overflow: hidden; + display: flex; + flex-direction: column; + background: white; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + transition: transform 0.2s; + height: 240px; + + &:hover { + transform: translateY(-4px); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); + } + + img { + width: 100%; + height: 160px; + object-fit: cover; + display: block; + } + + p { + margin: 0; + padding: 16px; + text-align: center; + font-weight: 500; + color: #333; + flex: 1; + display: flex; + align-items: center; + justify-content: center; + } +} + +.grid { + display: grid; + grid-template-columns: 1fr; + gap: 18px; + padding: 12px; + overflow-y: scroll; + + @media (min-width: 900px) { + grid-template-columns: 1fr 1fr; + gap: 22px; + } +} diff --git a/packages/Mediaco-overrides/gallery-grid/gallery-grid.component.ts b/packages/Mediaco-overrides/gallery-grid/gallery-grid.component.ts new file mode 100644 index 00000000..e359cc48 --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/gallery-grid.component.ts @@ -0,0 +1,27 @@ +import { Component, Inject } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatDialogModule, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { TableTemplateCardComponent } from './table-template-card/table-template-card'; + +@Component({ + selector: 'app-gallery-grid', + standalone: true, + imports: [CommonModule, MatDialogModule, MatIconModule, MatButtonModule, TableTemplateCardComponent], + templateUrl: './gallery-grid-component.html', + styleUrls: ['./gallery-grid-component.scss'] +}) +export class GalleryGridComponent { + trackByTitle = (_: number, item: { title: string }) => item.title; + + // Inject the data passed from the parent component + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: { items: any[]; dataPage: string } + ) {} + + close() { + this.dialogRef.close(); + } +} diff --git a/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.html b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.html new file mode 100644 index 00000000..19072243 --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.html @@ -0,0 +1,11 @@ + +
+
+ +
+
+
{{ data.title }}
+
{{ data.description }}
+
+
+
diff --git a/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.scss b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.scss new file mode 100644 index 00000000..9cc7e7aa --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.scss @@ -0,0 +1,88 @@ +.m-card { + border: 1px solid #e0e0e0; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + padding: 14px 16px; + transition: transform 0.2s; + + &:hover { + transform: scale(1.01); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); + } + + &:focus-visible { + outline: 3px solid #7c3aed; + outline-offset: 4px; + } +} + +.m-row { + display: flex; + align-items: center; + gap: 16px; +} + +.m-icon { + min-width: 48px; + min-height: 48px; + border-radius: 12px; + display: grid; + place-items: center; +} + +.m-icon-img { + display: block; + border-radius: 8px; +} + +.m-content { + display: flex; + flex-direction: column; + gap: 4px; +} +.m-title { + font-weight: 600; + color: #111827; +} +.m-desc { + color: #6b7280; + font-size: 14px; +} + +.bg-0 { + background-color: #ede9fe; +} +.bg-1 { + background-color: #fce7f3; +} +.bg-2 { + background-color: #e0f2fe; +} +.bg-3 { + background-color: #ffedd5; +} +.bg-4 { + background-color: #f3e8ff; +} +.bg-5 { + background-color: #d1fae5; +} + +.color-0 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(250deg) saturate(500%); +} +.color-1 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(320deg) saturate(500%); +} +.color-2 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(190deg) saturate(500%); +} +.color-3 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(25deg) saturate(500%); +} +.color-4 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(120deg) saturate(500%); +} +.color-5 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(90deg) saturate(500%); +} diff --git a/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.ts b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.ts new file mode 100644 index 00000000..5849a01c --- /dev/null +++ b/packages/Mediaco-overrides/gallery-grid/table-template-card/table-template-card.ts @@ -0,0 +1,16 @@ +import { CommonModule } from '@angular/common'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; +import { MatCard } from '@angular/material/card'; + +@Component({ + selector: 'table-template-card', + templateUrl: './table-template-card.html', + styleUrls: ['./table-template-card.scss'], + imports: [MatCard, CommonModule], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TableTemplateCardComponent { + @Input() data!: any; + @Input() tabindex = 0; + @Input() index!: number; +} diff --git a/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.html b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.html new file mode 100644 index 00000000..4ca42970 --- /dev/null +++ b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.html @@ -0,0 +1,39 @@ +
+ + +
+
+
+
+ + {{ item.number }} +
+ +
+
+ {{ item.title }} + + {{ item.title_subtext }} +
+
+ {{ item.description }} + + {{ item.description_subtext }} +
+
+
+   + {{ item.rating }} +
+
+
+
+ + +
diff --git a/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.scss b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.scss new file mode 100644 index 00000000..dc332007 --- /dev/null +++ b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.scss @@ -0,0 +1,197 @@ +.info-container { + background: #fff; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.info-item { + display: flex; + align-items: flex-start; + padding: 20px 25px; + position: relative; + + &:not(:last-child)::after { + content: ''; + position: absolute; + bottom: 0; + left: 25px; + right: 25px; + height: 1px; + background-color: #e5e7eb; + } +} + +.header-container { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} + +.icon-wrapper { + width: 48px; + height: 48px; + border-radius: 17px; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} + +.info-item { + transition: background-color 0.3s ease; +} + +.info-item:hover { + background-color: #f6f5f5; +} + +.info-item .icon-wrapper { + transition: transform 0.3s ease; +} + +.info-item:hover .icon-wrapper { + transform: scale(1.1); +} + +.description { + color: #4b5563; + font-size: 14px; + display: flex; + align-items: center; + gap: 8px; +} + +.icon-img { + width: 24px; + height: 24px; + object-fit: contain; +} + +.icon-num { + margin: auto; +} + +.star-icon { + color: #ffc107; +} + +/* Background colors for each icon */ +.bg-0 { + background-color: #ede9fe; +} /* Light purple */ +.bg-1 { + background-color: #fce7f3; +} /* Light pink */ +.bg-2 { + background-color: #e0f2fe; +} /* Light blue */ +.bg-3 { + background-color: #ffedd5; +} /* Light orange */ +.bg-4 { + background-color: #f3e8ff; +} /* Lavender */ +.bg-5 { + background-color: #d1fae5; +} /* Light green */ + +.color-0 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(250deg) saturate(500%); +} /* Dark purple */ +.color-1 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(320deg) saturate(500%); +} /* Dark pink */ +.color-2 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(190deg) saturate(500%); +} /* Dark blue */ +.color-3 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(25deg) saturate(500%); +} /* Dark orange */ +.color-4 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(120deg) saturate(500%); +} /* Dark green */ +.color-5 { + filter: brightness(0) saturate(100%) invert(20%) sepia(80%) hue-rotate(90deg) saturate(500%); +} /* Dark green */ + +.star { + filter: brightness(0) saturate(100%) invert(60%) sepia(92%) saturate(748%) hue-rotate(1deg) brightness(101%); + height: 16px; +} + +.dot { + width: 3px; + height: 3px; + background-color: #9ca3af; + border-radius: 50%; +} + +.content { + display: flex; + flex-direction: column; + justify-content: space-between; + margin-left: 12px; + height: 48px; + width: 400px; +} + +.title-row { + display: flex; + align-items: center; + gap: 8px; +} + +.title { + font-weight: 600; + font-size: 14px; +} + +.sub-text { + color: #9ca3af; + font-size: 12px; +} + +.extra-content { + height: 48px; + display: flex; + align-items: center; +} + +.trending-title { + font-size: 2rem; + font-weight: 500; + color: #222; /* Dark text color */ + position: relative; + display: inline-block; + padding-bottom: 8px; /* Space for underline */ +} + +.trending-title::after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + width: 100%; + height: 4px; /* Thickness of underline */ + background: linear-gradient(to right, #a41a61, #ff4fc3); + /* Dark pink (#d6006e) to lighter pink (#ff4fc3) */ + border-radius: 2px; /* Rounded edges */ +} + +.carousel-constraint-wrapper { + display: block; + width: 100%; + max-width: 100%; + + /* This stops the component from stretching the page, but keeps it visible */ + overflow: hidden; + position: relative; +} +.carousel-footer { + display: flex; + width: 100%; + justify-content: flex-end; + padding: 0 16px 10px 16px; + box-sizing: border-box; +} diff --git a/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.spec.ts b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.spec.ts new file mode 100644 index 00000000..1bb93a1d --- /dev/null +++ b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MediacoListViewComponent } from './mediaco-list-view.component'; + +describe('MediacoListViewComponent', () => { + let component: MediacoListViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MediacoListViewComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(MediacoListViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.ts b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.ts new file mode 100644 index 00000000..d08a02a2 --- /dev/null +++ b/packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component.ts @@ -0,0 +1,173 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Utils } from 'packages/angular-sdk-components/src/public-api'; +import { CarouselComponent } from '../Carousel-component/carousel.component'; +import { GalleryGridComponent } from '../gallery-grid/gallery-grid.component'; +import { MatDialog } from '@angular/material/dialog'; +import { MatButton } from '@angular/material/button'; + +interface ListViewProps { + inheritedProps: any; + title: string | undefined; + // If any, enter additional props that only exist on this component + globalSearch?: boolean; + referenceList?: any; + rowClickAction?: any; + selectionMode?: string; + referenceType?: string; + compositeKeys?: any; + showDynamicFields?: boolean; + presets?: any; + reorderFields: string | boolean; + grouping: string | boolean; + value: any; + readonlyContextList: any; + label?: string; + displayAs?: string; + showRecords: boolean; + viewName?: string; +} + +@Component({ + selector: 'app-mediaco-list-view', + imports: [CommonModule, CarouselComponent, MatButton], + templateUrl: './mediaco-list-view.component.html', + styleUrl: './mediaco-list-view.component.scss', + providers: [Utils] +}) +export class MediacoListViewComponent implements OnInit { + @Input() pConn$: typeof PConnect; + @Input() bInForm$ = true; + @Input() payload; + configProps$: ListViewProps; + template: string; + sourceList: any[]; + referenceDataPage: string; + caseTypeToActivityMap: any; + title: string; + + constructor( + public utils: Utils, + private dialog: MatDialog + ) { + this.caseTypeToActivityMap = { + 'Plan Upgrade': 'Plan Upgrade', + Payment: 'Make Payment', + AddOnPurchase: 'Add-On Services', + 'New Statement': 'New Service', + ProfileUpdated: 'Get Help', + 'Product Demo': 'Purchase Phone' + }; + } + + ngOnInit(): void { + this.configProps$ = this.pConn$.getConfigProps() as ListViewProps; + this.template = this.configProps$.presets[0]?.template; + this.title = this.configProps$.title || ''; + this.getListData(); + } + + getListData() { + this.referenceDataPage = this.configProps$.referenceList; + PCore.getDataPageUtils() + .getDataAsync(this.referenceDataPage, this.pConn$.getContextName()) + .then(({ data }) => { + this.modifyListData(data); + console.log(data); + }); + } + + modifyListData(data: any[]) { + if (this.referenceDataPage === 'D_AccountHistoryList') { + this.sourceList = data.map(item => { + const caseType = this.caseTypeToActivityMap[item.ActivityType]; + return { + icon: this.utils.getImageSrc(this.getIcon(caseType), this.utils.getSDKStaticContentUrl()), + title: item.ActivityType, + title_subtext: this.timeSince(new Date(item.pxUpdateDateTime || item.pxCreateDateTime)), + description: item.Description + }; + }); + return; + } + if (this.referenceDataPage === 'D_TrendingItemsList') { + this.sourceList = data.map((item, index) => { + return { + number: index + 1, + title: item.Name, + description: item.Genere, + description_subtext: item.Views + ' views', + rating: item.Rating + }; + }); + return; + } + if (this.referenceDataPage === 'D_CarouselitemList') { + this.sourceList = data.map(item => { + return { + Carouselheading: item.Carouselheading, + ImageURL: item.ImageURL + }; + }); + return; + } + } + + getIcon(activityType: string): string { + switch (activityType) { + case 'Plan Upgrade': + return 'trending-up'; + case 'Make Payment': + return 'wallet'; + case 'Add-On Services': + return 'monitor'; + case 'New Service': + return 'shopping-cart'; + case 'Get Help': + return 'headphones'; + case 'Purchase Phone': + return 'smartphone'; + default: + return ''; + } + } + + timeSince(date: Date): string { + const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000); + let interval = seconds / 31536000; + if (interval > 1) { + return Math.floor(interval) + 'y ago'; + } + interval = seconds / 2592000; + if (interval > 1) { + return Math.floor(interval) + ' months ago'; + } + interval = seconds / 86400; + if (interval > 1) { + return Math.floor(interval) + 'd ago'; + } + interval = seconds / 3600; + if (interval > 1) { + return Math.floor(interval) + 'h ago'; + } + interval = seconds / 60; + if (interval > 1) { + return Math.floor(interval) + 'm ago'; + } + return Math.floor(seconds) + 's ago'; + } + + openShowAll() { + this.dialog.open(GalleryGridComponent, { + width: '60vw', + height: '70vh', + maxWidth: '95vw', + maxHeight: '95vh', + + data: { + dataPage: this.referenceDataPage, + items: this.sourceList + } + }); + } +} diff --git a/packages/angular-sdk-components/src/lib/_components/designSystemExtension/banner/banner.component.scss b/packages/angular-sdk-components/src/lib/_components/designSystemExtension/banner/banner.component.scss index 5b6d3ea6..b437f705 100644 --- a/packages/angular-sdk-components/src/lib/_components/designSystemExtension/banner/banner.component.scss +++ b/packages/angular-sdk-components/src/lib/_components/designSystemExtension/banner/banner.component.scss @@ -28,6 +28,10 @@ column-gap: calc(2 * 0.5rem); row-gap: calc(2 * 0.5rem); align-items: start; + + & > *:nth-child(2) { + min-width: 0; + } } .background-image-style { diff --git a/packages/angular-sdk-components/src/lib/_components/infra/view/view.component.ts b/packages/angular-sdk-components/src/lib/_components/infra/view/view.component.ts index 2e1d3c1a..442448e1 100644 --- a/packages/angular-sdk-components/src/lib/_components/infra/view/view.component.ts +++ b/packages/angular-sdk-components/src/lib/_components/infra/view/view.component.ts @@ -162,7 +162,7 @@ export class ViewComponent implements OnInit, OnDestroy, OnChanges { this.showLabel$ = this.configProps$.showLabel || isDetailsTemplate(this.templateName$) || this.showLabel$; // label & showLabel within inheritedProps takes precedence over configProps this.label$ = this.inheritedProps$.label || this.label$; - this.showLabel$ = this.inheritedProps$.showLabel || this.showLabel$; + // this.showLabel$ = this.inheritedProps$.showLabel || this.showLabel$; // children may have a 'reference' so normalize the children array this.arChildren$ = ReferenceComponent.normalizePConnArray(this.pConn$.getChildren()); this.visibility$ = this.configProps$.visibility ?? this.visibility$; diff --git a/packages/angular-sdk-components/src/lib/_components/template/default-page/default-page.component.html b/packages/angular-sdk-components/src/lib/_components/template/default-page/default-page.component.html index a976662c..4479c9c1 100644 --- a/packages/angular-sdk-components/src/lib/_components/template/default-page/default-page.component.html +++ b/packages/angular-sdk-components/src/lib/_components/template/default-page/default-page.component.html @@ -24,13 +24,11 @@

{{ title }}

'psdk-grid-filter-narrow-wide': this.layout$ === 'narrow-wide' }" > -
- -
+ diff --git a/packages/angular-sdk-components/src/sdk-local-component-map.ts b/packages/angular-sdk-components/src/sdk-local-component-map.ts index 2f06f1e2..7d1aa1bd 100644 --- a/packages/angular-sdk-components/src/sdk-local-component-map.ts +++ b/packages/angular-sdk-components/src/sdk-local-component-map.ts @@ -1,5 +1,7 @@ // Statically load all "local" components that aren't yet in the npm package +import { MediacoListViewComponent } from 'packages/Mediaco-overrides/mediaco-list-view/mediaco-list-view.component'; + /* import end - DO NOT REMOVE */ // localSdkComponentMap is the JSON object where we'll store the components that are @@ -7,6 +9,7 @@ const localSdkComponentMap = { /* map end - DO NOT REMOVE */ + ListView: MediacoListViewComponent }; export default localSdkComponentMap; diff --git a/projects/angular-test-app/src/assets/icons/headphones.svg b/projects/angular-test-app/src/assets/icons/headphones.svg new file mode 100644 index 00000000..98b393ef --- /dev/null +++ b/projects/angular-test-app/src/assets/icons/headphones.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/angular-test-app/src/assets/icons/monitor.svg b/projects/angular-test-app/src/assets/icons/monitor.svg new file mode 100644 index 00000000..8d8c7af9 --- /dev/null +++ b/projects/angular-test-app/src/assets/icons/monitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/angular-test-app/src/assets/icons/shopping-cart.svg b/projects/angular-test-app/src/assets/icons/shopping-cart.svg new file mode 100644 index 00000000..fedbbae0 --- /dev/null +++ b/projects/angular-test-app/src/assets/icons/shopping-cart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/angular-test-app/src/assets/icons/smartphone.svg b/projects/angular-test-app/src/assets/icons/smartphone.svg new file mode 100644 index 00000000..bb785ab5 --- /dev/null +++ b/projects/angular-test-app/src/assets/icons/smartphone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/angular-test-app/src/assets/icons/trending-up.svg b/projects/angular-test-app/src/assets/icons/trending-up.svg new file mode 100644 index 00000000..b44aef1e --- /dev/null +++ b/projects/angular-test-app/src/assets/icons/trending-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/angular-test-app/src/assets/icons/wallet.svg b/projects/angular-test-app/src/assets/icons/wallet.svg index ffd61049..9d39e59a 100644 --- a/projects/angular-test-app/src/assets/icons/wallet.svg +++ b/projects/angular-test-app/src/assets/icons/wallet.svg @@ -1,4 +1 @@ - - - Wallet - \ No newline at end of file + \ No newline at end of file