started component

This commit is contained in:
tidusjar 2022-07-31 21:59:53 +01:00
commit 5b55135256
18 changed files with 998 additions and 65 deletions

View file

@ -16,5 +16,6 @@ namespace Ombi.Core.Models.Requests
public string Overview { get; set; }
public DateTime ReleaseDate { get; set; }
public bool Approved { get; set; }
public string MediaId { get; set; }
}
}

View file

@ -65,7 +65,8 @@ namespace Ombi.Core.Services
Type = RequestType.Movie,
Approved = item.Approved,
UserId = item.RequestedUserId,
Username = item.RequestedUser.UserAlias
Username = item.RequestedUser.UserAlias,
MediaId = item.TheMovieDbId.ToString(),
});
}
@ -82,7 +83,8 @@ namespace Ombi.Core.Services
Title = item.Title,
Type = RequestType.Album,
UserId = item.RequestedUserId,
Username = item.RequestedUser.UserAlias
Username = item.RequestedUser.UserAlias,
MediaId = item.ForeignAlbumId,
});
}
@ -101,7 +103,8 @@ namespace Ombi.Core.Services
Title = item.ParentRequest.Title,
Type = RequestType.TvShow,
UserId = item.RequestedUserId,
Username = item.RequestedUser.UserAlias
Username = item.RequestedUser.UserAlias,
MediaId = item.ParentRequest.ExternalProviderId.ToString()
});
}

View file

@ -6,11 +6,16 @@ module.exports = {
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
"@storybook/addon-interactions",
"@storybook/preset-scss",
],
"framework": "@storybook/angular",
"core": {
"builder": "@storybook/builder-webpack5"
},
"staticDirs": ['../../wwwroot/images']
"staticDirs": [
'../../wwwroot/images',
'../../wwwroot/translations',
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
]
}

View file

@ -1,5 +1,8 @@
import { setCompodocJson } from "@storybook/addon-docs/angular";
import docJson from "../documentation.json";
// import '../src/styles/Styles.scss';
import '../src/styles/_imports.scss';
setCompodocJson(docJson);
export const parameters = {

View file

@ -26,12 +26,12 @@
"@angular/platform-server": "^14.0.0",
"@angular/router": "^14.0.0",
"@angularclass/hmr": "^3.0.0",
"@microsoft/signalr": "^6.0.7",
"@auth0/angular-jwt": "^5.0.2",
"@fortawesome/fontawesome-free": "^6.0.0",
"@fullcalendar/core": "^4.2.0",
"@fullcalendar/daygrid": "^4.4.0",
"@fullcalendar/interaction": "^4.2.0",
"@microsoft/signalr": "^6.0.7",
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0",
"@ngxs/devtools-plugin": "^3.7.3",
@ -57,16 +57,16 @@
"popper.js": "^1.14.3",
"primeicons": "^5.0.0",
"primeng": "^13.2.0",
"protractor": "~5.4.0",
"rxjs": "^7.5.4",
"sass-recursive-map-merge": "^1.0.1",
"store": "^2.0.12",
"ts-md5": "^1.2.7",
"tslib": "^1.10.0",
"tslint-angular": "^1.1.2",
"zone.js": "~0.11.4",
"protractor": "~5.4.0",
"ts-node": "~5.0.1",
"tslint": "^5.12.0"
"tslib": "^1.10.0",
"tslint": "^5.12.0",
"tslint-angular": "^1.1.2",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.0.0",
@ -75,17 +75,19 @@
"@angular/language-service": "^14.0.0",
"@babel/core": "^7.18.9",
"@compodoc/compodoc": "^1.1.19",
"@types/node": "^16.11.45",
"@storybook/addon-actions": "^6.5.9",
"@storybook/addon-essentials": "^6.5.9",
"@storybook/addon-interactions": "^6.5.9",
"@storybook/addon-links": "^6.5.9",
"@storybook/angular": "^6.5.9",
"@storybook/builder-webpack5": "^6.5.9",
"@storybook/cli": "^6.5.9",
"@storybook/manager-webpack5": "^6.5.9",
"@storybook/testing-library": "^0.0.13",
"@storybook/preset-scss": "^1.0.3",
"@types/jasmine": "~3.6.7",
"@types/jasminewd2": "~2.0.8",
"@types/node": "^16.11.45",
"babel-loader": "^8.2.5",
"chromatic": "^6.7.1",
"codelyzer": "^6.0.1",

View file

@ -0,0 +1,18 @@
.detailed-container {
width: 400px;
::ng-deep .poster {
border-radius: 10px;
opacity: 1;
display: block;
width: 100%;
height: auto;
transition: .5s ease;
backface-visibility: hidden;
}
}

View file

@ -0,0 +1,41 @@
// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1
import { APP_BASE_HREF } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { Story, Meta, moduleMetadata } from '@storybook/angular';
import { ButtonComponent } from './button.component';
// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export
export default {
title: 'Button Component',
component: ButtonComponent,
decorators: [
moduleMetadata({
providers: [
{
provide: APP_BASE_HREF,
useValue: {}
},
MatButtonModule
]
})
]
} as Meta;
// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args
const Template: Story<ButtonComponent> = (args: ButtonComponent) => ({
props: args,
});
export const Primary = Template.bind({});
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
Primary.args = {
type: 'primary',
text: 'Primary',
};
export const Secondary = Template.bind({});
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
Secondary.args = {
type: 'accent',
text: 'Secondary',
};

View file

@ -0,0 +1,25 @@
import { OmbiCommonModules } from "../modules";
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
import { MatButtonModule } from "@angular/material/button";
@Component({
standalone: true,
selector: 'ombi-button',
imports: [...OmbiCommonModules, MatButtonModule],
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./button.component.scss'],
template: `
<button [id]="id" [type]="type" [class]="class" [data-toggle]="dataToggle" mat-raised-button [data-target]="dataTarget">{{text}}</button>
`
})
export class ButtonComponent {
@Input() public text: string;
@Input() public id: string;
@Input() public type: string;
@Input() public class: string;
@Input('data-toggle') public dataToggle: string;
@Input('data-target') public dataTarget: string;
}

View file

@ -0,0 +1,77 @@
<!-- <div *ngIf="!request">Nothing</div>
<div id="request{{request.requestId}}" class="ombi-card dark-card c" [style.display]="hide ? 'none' : 'block'">
<div class="card-top-info">
<div class="top-left" id="type{{request.requestId}}-{{RequestType[request.requestType]}}">
{{ 'Common.' + RequestType[request.requestType] }}
</div>
</div>
<ombi-image [src]="request.posterPath" [type]="request.requestType" id="cardImage" class="image" alt="{{request.title}}"></ombi-image>
<div [ngClass]="request.posterPath.includes('images/') ? 'middle-show' : 'middle'">
<a class="poster-overlay">
<div class="summary">
<div class="title" id="title{{request.requestId}}">{{request.title}}</div>
<div class="small-text ellipsis" id="overview{{request.requestId}}">{{request.overview}}</div>
</div>
</a>
</div>
<div [ngClass]="request.posterPath.includes('images/') ? 'button-request-container-show' : 'button-request-container'" class="row" *ngIf="!request.available && !request.approved && !request.requested">
<div *ngIf="is4kEnabled && request.requestType === RequestType.movie;then show4K else regular"></div>
<ng-template #show4K>
<div class="button-request poster-overlay">
<button [matMenuTriggerFor]="menu" id="requestButton{{request.requestId}}{{request.requestType}}" mat-raised-button class="btn-ombi full-width poster-request-btn">
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
{{'Common.Request' }}
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="submitRequest(false)">{{'Common.Request' }}</button>
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="submitRequest(true)">{{'Common.Request4K' }}</button>
</mat-menu>
</div>
</ng-template>
<ng-template #regular>
<div class="button-request poster-overlay">
<button id="requestButton{{request.requestId}}{{request.requestType}}" *ngIf="requestable" mat-raised-button class="btn-ombi full-width poster-request-btn" (click)="submitRequest(false)">
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
{{'Common.Request' }}
</button>
</div>
</ng-template>
</div>
</div> -->
<div class="detailed-container">
<div class="row">
<div class="col-5">
<ombi-image [src]="request.posterPath" [type]="request.requestType" class="poster" alt="{{request.title}}">
</ombi-image>
</div>
<div class="col-7">
<div class="row">
<div class="col-12 title">
<h3>{{request.title}}</h3>
</div>
<div class="col-12 overview">
<p>{{request.overview}}</p>
</div>
<div class="col-12">
<span>Requested By: {{request.userName}}</span>
</div>
<div class="col-12">
<span>On: {{request.requestDate | amFromUtc | amLocal | amUserLocale | amDateFormat: 'l LT'}}</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-4">
<button>Request</button>
</div>
</div>
</div>

View file

@ -0,0 +1,18 @@
.detailed-container {
width: 400px;
::ng-deep .poster {
border-radius: 10px;
opacity: 1;
display: block;
width: 100%;
height: auto;
transition: .5s ease;
backface-visibility: hidden;
}
}

View file

@ -0,0 +1,51 @@
// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1
import { APP_BASE_HREF } from '@angular/common';
import { Story, Meta, moduleMetadata } from '@storybook/angular';
import { IRecentlyRequested, RequestType } from '../../interfaces';
import { DetailedCardComponent } from './detailed-card.component';
import { TranslateModule } from "@ngx-translate/core";
import { ImageService } from '../../services/image.service';
// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export
export default {
title: 'Detailed Card Component',
component: DetailedCardComponent,
decorators: [
moduleMetadata({
providers: [
{
provide: APP_BASE_HREF,
useValue: {}
},
],
imports: [
TranslateModule.forRoot(),
]
})
]
} as Meta;
// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args
const Template: Story<DetailedCardComponent> = (args: DetailedCardComponent) => ({
props: args,
});
export const NewMovieRequest = Template.bind({});
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
NewMovieRequest.args = {
request: {
title: 'The Matrix',
approved: false,
available: false,
tvPartiallyAvailable: false,
requestDate: new Date(2022, 1, 1),
userName: 'John Doe',
userId: '12345',
requestType: RequestType.movie,
mediaId: '603',
overview: 'The Matrix is a movie about a group of people who are forced to fight against a powerful computer system that controls them.',
releaseDate: new Date(2020, 1, 1),
posterPath: "https://assets.fanart.tv/fanart/movies/603/movieposter/the-matrix-52256ae1021be.jpg"
} as IRecentlyRequested,
is4kEnabled: false,
};

View file

@ -0,0 +1,48 @@
import { OmbiCommonModules } from "../modules";
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from "@angular/core";
import { IRecentlyRequested, RequestType } from "../../interfaces";
import { ImageComponent } from "../image/image.component";
import { ImageService } from "app/services";
import { Subject, takeUntil } from "rxjs";
import { PipeModule } from "app/pipes/pipe.module";
@Component({
standalone: true,
selector: 'ombi-detailed-card',
imports: [...OmbiCommonModules, ImageComponent, PipeModule],
providers: [ImageService],
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './detailed-card.component.html',
styleUrls: ['./detailed-card.component.scss']
})
export class DetailedCardComponent implements OnInit, OnDestroy {
@Input() public request: IRecentlyRequested;
@Input() public is4kEnabled: boolean = false;
@Output() public onRequest: EventEmitter<boolean> = new EventEmitter<boolean>();
public RequestType = RequestType;
public loading: false;
private $imageSub = new Subject<void>();
constructor(private imageService: ImageService) { }
ngOnInit(): void {
if (!this.request.posterPath) {
this.imageService.getMoviePoster(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = x);
}
}
public submitRequest(is4k: boolean) {
this.onRequest.emit(is4k);
}
public ngOnDestroy() {
this.$imageSub.next();
this.$imageSub.complete();
}
}

View file

@ -1,2 +1,3 @@
export * from "./image-background/image-background.component";
export * from "./image/image.component";
export * from "./image/image.component";
export * from "./detailed-card/detailed-card.component";

View file

@ -1,3 +1,5 @@
import { CommonModule } from "@angular/common";
import { HttpClientModule } from "@angular/common/http";
import { MomentModule } from "ngx-moment";
export const OmbiCommonModules = [ CommonModule ];
export const OmbiCommonModules = [ CommonModule, HttpClientModule, MomentModule ];

View file

@ -0,0 +1,18 @@
import { RequestType } from "./IRequestModel";
export interface IRecentlyRequested {
requestId: number;
requestType: RequestType;
userId: string;
userName: string;
available: boolean;
tvPartiallyAvailable: boolean;
requestDate: Date;
title: string;
overview: string;
releaseDate: Date;
approved: boolean;
mediaId: string;
posterPath: string;
}

View file

@ -21,3 +21,4 @@ export * from "./IVote";
export * from "./IFailedRequests";
export * from "./IHub";
export * from "./ITester";
export * from "./IRecentlyRequested";

View file

@ -44,5 +44,4 @@ export class ImageService extends ServiceHelpers {
public getTvBackground(tvdbid: number): Observable<string> {
return this.http.get<string>(`${this.url}background/tv/${tvdbid}`, { headers: this.headers });
}
}

File diff suppressed because it is too large Load diff