This commit is contained in:
2019-08-04 21:12:36 +02:00
parent 3e895cb113
commit 8854f3beb6
39 changed files with 265 additions and 410 deletions

View File

@@ -1,21 +1,21 @@
import {SongsComponent} from './components/songs/songs.component';
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{
path: 'songs',
component: SongsComponent
},
{
path: '',
redirectTo: 'songs',
pathMatch: 'full'
pathMatch: 'full',
redirectTo: 'songs'
},
{
path: 'songs',
loadChildren: () => import('./songs/songs.module').then(_ => _.SongsModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
exports: [RouterModule]
})
export class AppRoutingModule {

View File

@@ -0,0 +1,4 @@
:root {
display: block;
padding: 10px;
}

View File

@@ -18,28 +18,11 @@ import {MatRadioModule} from '@angular/material/radio';
import {MatSelectModule} from '@angular/material/select';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {TableComponent} from './components/songs/table/table.component';
import {SongsComponent} from './components/songs/songs.component';
import {SongComponent} from './components/songs/song/song.component';
import {SongEditComponent} from './components/songs/song-edit/song-edit.component';
import {SongNewComponent} from './components/songs/song-new/song-new.component';
import {SongFormComponent} from './components/songs/song-form/song-form.component';
import {SongFilesComponent} from './components/songs/song-files/song-files.component';
import {FileUploadModule} from 'ng2-file-upload';
import {SongFileEditComponent} from './components/songs/song-file-edit/song-file-edit.component';
@NgModule({
declarations: [
AppComponent,
SongsComponent,
TableComponent,
SongComponent,
SongEditComponent,
SongNewComponent,
SongFormComponent,
SongFilesComponent,
SongFileEditComponent
AppComponent
],
imports: [
BrowserModule,

View File

@@ -1,71 +0,0 @@
import {switchMap} from 'rxjs/operators';
import {ChangeDetectorRef, Component} from '@angular/core';
import {Song} from 'src/app/models/song.model';
import {SongsService} from 'src/app/data/songs.service';
import {DownloadService} from 'src/app/data/download.service';
import {faDownload, faEdit, faFileUpload, faLongArrowAltLeft, faTrash} from '@fortawesome/free-solid-svg-icons';
import {FileuploadFactory} from 'src/app/services/fileupload.factory';
import {FileUploader} from 'ng2-file-upload';
@Component({
selector: 'app-song-files',
templateUrl: './song-files.component.html',
styleUrls: ['./song-files.component.less']
})
export class SongFilesComponent {
public song: Song;
public selectedSongId = 0;
public faFileUpload = faFileUpload;
public faTrash = faTrash;
public faArrow = faLongArrowAltLeft;
public faDownload = faDownload;
public faEdit = faEdit;
public columns = ['name', 'action'];
public newFileUploader: FileUploader;
public fileEditId: number;
public fileOverNew = false;
constructor(
private downloadService: DownloadService,
private fileuploadFactory: FileuploadFactory,
private songService: SongsService,
change: ChangeDetectorRef
) {
songService.selectedSong.subscribe(_ => {
if (_) {
this.selectedSongId = _.ID;
this.song = _;
this.newFileUploader = FileuploadFactory.provideForNewFiles(_.ID);
this.newFileUploader.onCompleteItem = () =>
songService.selectSong(_.ID).subscribe();
this.newFileUploader.onProgressItem = () => change.markForCheck;
} else {
this.selectedSongId = 0;
this.song = null;
this.newFileUploader = null;
}
change.markForCheck();
});
}
public onClickDownload(fileId: number, filename): void {
this.downloadService.get(this.selectedSongId, fileId, filename);
}
public onFileOverNew(hover: boolean): void {
this.fileOverNew = hover;
}
public onClickEdit(fileId: number): void {
this.fileEditId = fileId;
}
public onClickDelete(fileId: number): void {
const songId = this.song.ID;
this.songService
.deleteFile$(songId, fileId)
.pipe(switchMap(() => this.songService.selectSong(songId)))
.subscribe();
}
}

View File

@@ -1,61 +0,0 @@
import {SongsService} from 'src/app/data/songs.service';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component} from '@angular/core';
import {faEdit, faLongArrowAltLeft} from '@fortawesome/free-solid-svg-icons';
import {Song} from 'src/app/models/song.model';
import {State} from 'src/app/data/state';
@Component({
selector: 'app-song',
templateUrl: './song.component.html',
styleUrls: ['./song.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SongComponent {
public song: Song;
public faArrow = faLongArrowAltLeft;
public faEdit = faEdit;
public selectedSongId = 0;
constructor(
private songService: SongsService,
change: ChangeDetectorRef
) {
songService.selectedSong.subscribe(_ => {
if (_) {
this.selectedSongId = _.ID;
this.song = _;
} else {
this.selectedSongId = 0;
this.song = null;
}
change.markForCheck();
});
}
public get text(): string[] {
return this.song && this.song.Text ? this.song.Text.split(/\r?\n/) : [];
}
public get comments(): string[] {
return this.song && this.song.Comments ? this.song.Comments.split(/\r?\n/) : [];
}
public onBack(): void {
this.songService.resetSelectedSong();
}
public onClickEdit(): void {
this.songService.state.next(State.edit);
}
public renderSongType(songType: string) {
switch (songType) {
case 'Praise':
return {name: 'Lobpreis', color: '#99FFB8'};
case 'Worship':
return {name: 'Anbetung', color: '#C999FF'};
default:
return null;
}
}
}

View File

@@ -1,9 +0,0 @@
<div class="songs-container">
<app-table></app-table>
<div class="song-container">
<app-song-edit *ngIf="(songsService.state | async) === State.edit"></app-song-edit>
<app-song-new *ngIf="(songsService.state | async) === State.new"></app-song-new>
<app-song *ngIf="(songsService.state | async) === State.read"></app-song>
<app-song-files *ngIf="(songsService.state | async) === State.read"></app-song-files>
</div>
</div>

View File

@@ -3,7 +3,7 @@ import {Observable} from 'rxjs';
import {map, tap} from 'rxjs/operators';
import {base} from './urls';
export class OdataService {
export class ODataBaseService {
private url: string;
constructor(private odataService: ODataService, private entity: string) {
@@ -21,14 +21,14 @@ export class OdataService {
public get$<TResponse>(
id: number,
properties: string[],
select: string[],
expands: string[]
): Observable<TResponse> {
const query = new ODataQuery(this.odataService, this.url)
.entitySet(this.entity)
.entityKey(id)
.expand(expands.map(_ => new Expand(_)))
.select(properties);
.select(select);
const get = query.get().pipe(map(_ => _.toEntity<TResponse>()));
return get;

View File

@@ -2,19 +2,21 @@ import {SongsService} from 'src/app/data/songs.service';
import {Injectable} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {switchMap} from 'rxjs/operators';
import {Song} from '../models/song.model';
import {Song} from '../songs/models/song.model';
import {Subscription} from 'rxjs';
import {File} from '../songs/models/file.model';
@Injectable({
providedIn: 'root'
})
export class EditSongService {
constructor(private songsService: SongsService) {
}
public initSongEditForm(attachSync: boolean): FormGroup {
public initSongEditForm(attachSync: boolean, _song: Song): FormGroup {
const song = attachSync
? this.songsService.selectedSong.value
? _song
: this.defaultValues();
const form = new FormGroup({
Number: new FormControl(song.Number, {
@@ -45,10 +47,7 @@ export class EditSongService {
return form;
}
public initFileEditForm(songId: number, fileId: number): { form: FormGroup, changeSubscription: Subscription } {
const file = this.songsService.selectedSong.value.Files.filter(
_ => _.ID === fileId
)[0];
public initFileEditForm(songId: number, file: File): { form: FormGroup, changeSubscription: Subscription } {
const form = new FormGroup({
Name: new FormControl(file.Name, {
updateOn: 'blur',
@@ -60,8 +59,7 @@ export class EditSongService {
});
const changeSubscription = form.valueChanges.pipe(
switchMap(_ => this.songsService.updateFile$(songId, fileId, _.Name, _.FileType)),
switchMap(() => this.songsService.selectSong(songId))
switchMap(_ => this.songsService.updateFile$(songId, file.ID, _.Name, _.FileType)),
).subscribe();
return {form: form, changeSubscription: changeSubscription};
@@ -73,7 +71,6 @@ export class EditSongService {
form.controls[control].valueChanges
.pipe(
switchMap(value => this.songsService.patch$(song.ID, control, value)),
switchMap(() => this.songsService.selectSong(song.ID))
)
.subscribe();
});

View File

@@ -1,22 +1,21 @@
import {HttpClient} from '@angular/common/http';
import {FileType} from '../models/files-types.model.ts';
import {Injectable} from '@angular/core';
import {ODataService} from 'odata-v4-ng';
import {OdataService} from './odata.service';
import {Song} from '../models/song.model';
import {ODataBaseService} from './ODataBaseService';
import {Song} from '../songs/models/song.model';
import {BehaviorSubject, Observable} from 'rxjs';
import {switchMap, tap} from 'rxjs/operators';
import {tap} from 'rxjs/operators';
import {State} from './state';
import {base} from './urls';
import {FileType} from '../songs/models/files-types.model';
@Injectable({
providedIn: 'root'
})
export class SongsService extends OdataService {
export class SongsService extends ODataBaseService {
public state = new BehaviorSubject<State>(State.list);
public songs: BehaviorSubject<Song[]> = new BehaviorSubject<Song[]>([]);
public selectedSong: BehaviorSubject<Song> = new BehaviorSubject<Song>(null);
constructor(odataService: ODataService, private httpClient: HttpClient) {
super(odataService, 'songs');
@@ -30,40 +29,6 @@ export class SongsService extends OdataService {
return list;
}
public loadSongListAndGoTo$(id: number): Observable<Song> {
const properties = ['ID', 'Name', 'Number', 'SongType', 'Key', 'Tempo'];
const list = this.list$<Song>(properties).pipe(
tap(_ => {
this.songs.next(_);
}),
switchMap(() => this.selectSong(id))
);
return list;
}
public selectSong(id: number): Observable<Song> {
this.state.next(State.read);
const filter = this.songs.value.filter(_ => _.ID === id);
const song = filter.length === 1 ? filter[0] : null;
if (!song) {
return;
}
const get = this.get$<Song>(id, ['Text', 'Comments'], ['Files']).pipe(tap(_ => {
song.Text = _.Text;
song.Comments = _.Comments;
song.Files = _.Files;
this.selectedSong.next(song);
}));
return get;
}
public resetSelectedSong() {
this.state.next(State.list);
this.selectedSong.next(null);
}
public patch$(id: number, control: string, value: any): Observable<boolean> {
const patch = super.patch$(id, control, value).pipe(
@@ -72,7 +37,6 @@ export class SongsService extends OdataService {
const song = songs.filter(_ => _.ID === id)[0];
song[control] = value;
this.songs.next(songs);
this.selectedSong.next(song);
})
);
@@ -80,9 +44,7 @@ export class SongsService extends OdataService {
}
public saveNewSong$(values: any): Observable<Song> {
const newSong = super
.post$<Song>(values)
.pipe(switchMap(_ => this.loadSongListAndGoTo$(_.ID)));
const newSong = super.post$<Song>(values);
return newSong;
}
@@ -93,16 +55,7 @@ export class SongsService extends OdataService {
name: string,
fileType: FileType
): Observable<any> {
const url =
base +
'/api/songs/' +
songId +
'/files/' +
fileId +
'/edit?Name=' +
name +
'&FileType=' +
fileType;
const url = `${base}/api/songs/${songId}/files/${fileId}/edit?Name=${name}&FileType=${fileType}`;
const get = this.httpClient.get(url);
return get;
}
@@ -111,13 +64,7 @@ export class SongsService extends OdataService {
songId: number,
fileId: number
): Observable<any> {
const url =
base +
'/api/songs/' +
songId +
'/files/' +
fileId +
'/delete';
const url = `${base}/api/songs/${songId}/files/${fileId}/delete`;
const get = this.httpClient.get(url);
return get;
}

View File

@@ -0,0 +1,6 @@
<div class="songs-container">
<app-table></app-table>
<div class="song-container">
<router-outlet></router-outlet>
</div>
</div>

View File

@@ -3,6 +3,5 @@
}
.song-container {
padding: 10px;
flex-flow: column;
}

View File

@@ -4,11 +4,11 @@
>
<div class="table-container">
<button
(click)="onClickNew()"
class="button-new"
mat-icon-button
matTooltip="neuen Titel anlegen"
matTooltipPosition="left"
[routerLink]="'/songs/new'"
>
<fa-icon [icon]="faNew"></fa-icon>
</button>
@@ -65,10 +65,10 @@
<tr *matHeaderRowDef="columns | async; sticky: true" mat-header-row></tr>
<tr
(click)="onClick(row.ID)"
*matRowDef="let row; columns: columns | async"
[class.selected]="selectedSongId === row.ID"
[routerLink]="'/songs/' + row.ID"
mat-row
routerLinkActive="selected"
></tr>
</table>
</div>

View File

@@ -1,10 +1,26 @@
table {
border-radius: 8px;
background: #fffe;
tr.selected {
background-color: #0002;
}
tr:hover {
cursor: pointer;
background-color: #0001;
td {
color: #ff9900;
}
}
td.mat-cell {
padding: 0 5px;
}
}
.table-container {
//height: 100%;
overflow: auto;
position: relative;
}
@@ -23,3 +39,4 @@ table {
}

View File

@@ -1,4 +1,4 @@
import {SongsService} from '../../../data/songs.service';
import {SongsService} from '../../../../data/songs.service';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component} from '@angular/core';
import {State} from 'src/app/data/state';
import {faFileMedical} from '@fortawesome/free-solid-svg-icons';
@@ -12,7 +12,6 @@ import {map} from 'rxjs/operators';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TableComponent {
public selectedSongId = 0;
public State = State;
public faNew = faFileMedical;
public columnsFull = ['Number', 'Name', 'Key', 'SongType', 'Tempo'];
@@ -22,11 +21,6 @@ export class TableComponent {
public songsService: SongsService,
private change: ChangeDetectorRef
) {
songsService.selectedSong.subscribe(_ => {
this.selectedSongId = _ ? _.ID : 0;
this.change.markForCheck();
}
);
}
public get columns(): Observable<string[]> {
@@ -43,16 +37,4 @@ export class TableComponent {
return null;
}
}
public onClick(id: number): void {
this.songsService.selectSong(id).subscribe();
this.change.detectChanges();
}
public onClickNew(): void {
this.songsService.selectSong(null).subscribe();
this.songsService.state.next(State.new);
this.change.detectChanges();
}
}

View File

@@ -1,4 +1,4 @@
import {FileType} from './files-types.model.ts';
import {FileType} from './files-types.model';
export interface File {
ID: number;

View File

@@ -2,7 +2,7 @@
<mat-card *ngIf="form" class="mat-elevation-z8">
<mat-card-header>
<div mat-card-avatar>
<button (click)="onBack()" color="warn" mat-icon-button>
<button [routerLink]="'/songs/'+ songId +'/read'" color="warn" mat-icon-button>
<fa-icon [icon]="faArrow"></fa-icon>
</button>
</div>
@@ -14,11 +14,5 @@
<mat-card-content>
<app-song-form [form]="form"></app-song-form>
</mat-card-content>
<!-- <mat-card-actions>
<button mat-button (click)="onClickDownload()">Herunterladen</button>
<button mat-button (click)="onClickEdit()">
<fa-icon [icon]="faEdit"></fa-icon> Bearbeiten
</button>
</mat-card-actions> -->
</mat-card>
</div>

View File

@@ -1,9 +1,9 @@
import {SongsService} from 'src/app/data/songs.service';
import {FormGroup} from '@angular/forms';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core';
import {EditSongService} from 'src/app/data/edit-song.service';
import {faLongArrowAltLeft} from '@fortawesome/free-solid-svg-icons';
import {State} from 'src/app/data/state';
import {ActivatedRoute} from '@angular/router';
import {Song} from '../../../models/song.model';
@Component({
selector: 'app-song-edit',
@@ -14,21 +14,16 @@ import {State} from 'src/app/data/state';
export class SongEditComponent implements OnInit {
public form: FormGroup = null;
public faArrow = faLongArrowAltLeft;
public songId: number;
constructor(
private editSongService: EditSongService,
private songsService: SongsService,
private change: ChangeDetectorRef
) {
private editSongService: EditSongService, private route: ActivatedRoute) {
}
ngOnInit() {
this.form = this.editSongService.initSongEditForm(true);
this.change.markForCheck();
}
public onBack(): void {
this.songsService.state.next(State.read);
this.route.data.subscribe((data: { song: Song }) => {
this.songId = data.song.ID;
this.form = this.editSongService.initSongEditForm(true, data.song);
});
}
}

View File

@@ -1,9 +1,9 @@
import {EditSongService} from '../../../data/edit-song.service';
import {EditSongService} from '../../../../data/edit-song.service';
import {FormGroup} from '@angular/forms';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core';
import {faLongArrowAltLeft, faSave} from '@fortawesome/free-solid-svg-icons';
import {State} from 'src/app/data/state';
import {SongsService} from 'src/app/data/songs.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-song-new',
@@ -19,22 +19,18 @@ export class SongNewComponent implements OnInit {
constructor(
private editSongService: EditSongService,
private songsService: SongsService,
private change: ChangeDetectorRef
private router: Router
) {
}
ngOnInit() {
this.form = this.editSongService.initSongEditForm(false);
this.change.markForCheck();
}
public onBack(): void {
this.songsService.state.next(State.list);
this.songsService.resetSelectedSong();
this.form = this.editSongService.initSongEditForm(false, null);
}
public onClickAdd(): void {
this.songsService.saveNewSong$(this.form.value).subscribe();
this.songsService.saveNewSong$(this.form.value).subscribe(song => {
this.router.navigateByUrl('/songs/' + song.ID + '/read');
});
}
}

View File

@@ -1,17 +1,18 @@
import {SongsService} from '../../../data/songs.service';
import {FileType} from '../../../models/files-types.model.ts';
import {FormGroup} from '@angular/forms';
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
import {EditSongService} from 'src/app/data/edit-song.service';
import {Subscription} from 'rxjs';
import {FileType} from '../../../../models/files-types.model';
import {File} from '../../../../models/file.model';
@Component({
selector: 'app-song-file-edit',
templateUrl: './song-file-edit.component.html',
styleUrls: ['./song-file-edit.component.less']
templateUrl: './song-files-edit.component.html',
styleUrls: ['./song-files-edit.component.less']
})
export class SongFileEditComponent implements OnInit, OnDestroy {
@Input() fileId: number;
export class SongFilesEditComponent implements OnInit, OnDestroy {
@Input() file: File;
@Input() songId: number;
@Output() back = new EventEmitter();
public form: FormGroup;
public subscription: Subscription;
@@ -23,15 +24,13 @@ export class SongFileEditComponent implements OnInit, OnDestroy {
];
constructor(
private editSongService: EditSongService,
private songService: SongsService
) {
private editSongService: EditSongService) {
}
public ngOnInit(): void {
const form = this.editSongService.initFileEditForm(
this.songService.selectedSong.value.ID,
this.fileId
this.songId,
this.file,
);
this.form = form.form;
this.subscription = form.changeSubscription;

View File

@@ -1,4 +1,4 @@
<div *ngIf="song" class="song-detail-container files">
<div class="song-detail-container files">
<mat-card class="mat-elevation-z8">
<mat-card-content>
<table [dataSource]="song.Files" class="mat-elevation-z8" mat-table>
@@ -11,7 +11,8 @@
<app-song-file-edit
(back)="onClickEdit(null)"
*ngIf="fileEditId === element.ID"
[fileId]="element.ID"
[file]="element"
[songId]="song.ID"
></app-song-file-edit>
</td>
</ng-container>

View File

@@ -0,0 +1,56 @@
import {Component, Input, OnInit} from '@angular/core';
import {Song} from 'src/app/songs/models/song.model';
import {SongsService} from 'src/app/data/songs.service';
import {DownloadService} from 'src/app/data/download.service';
import {faDownload, faEdit, faFileUpload, faLongArrowAltLeft, faTrash} from '@fortawesome/free-solid-svg-icons';
import {FileuploadFactory} from 'src/app/songs/services/fileupload.factory';
import {FileUploader} from 'ng2-file-upload';
@Component({
selector: 'app-song-files',
templateUrl: './files.component.html',
styleUrls: ['./files.component.less']
})
export class SongFilesComponent implements OnInit {
@Input() public song: Song;
public faFileUpload = faFileUpload;
public faTrash = faTrash;
public faArrow = faLongArrowAltLeft;
public faDownload = faDownload;
public faEdit = faEdit;
public columns = ['name', 'action'];
public newFileUploader: FileUploader;
public fileEditId: number;
public fileOverNew = false;
constructor(
private downloadService: DownloadService,
private fileuploadFactory: FileuploadFactory,
private songService: SongsService
) {
}
public ngOnInit(): void {
this.newFileUploader = FileuploadFactory.provideForNewFiles(this.song.ID);
}
public onClickDownload(fileId: number, filename): void {
this.downloadService.get(this.song.ID, fileId, filename);
}
public onFileOverNew(hover: boolean): void {
this.fileOverNew = hover;
}
public onClickEdit(fileId: number): void {
this.fileEditId = fileId;
}
public onClickDelete(fileId: number): void {
const songId = this.song.ID;
this.songService
.deleteFile$(songId, fileId)
.subscribe();
}
}

View File

@@ -1,8 +1,8 @@
<div *ngIf="song" class="song-detail-container">
<div class="song-detail-container">
<mat-card class="mat-elevation-z8">
<mat-card-header>
<div mat-card-avatar>
<button (click)="onBack()" color="warn" mat-icon-button>
<button color="warn" mat-icon-button routerLink="/songs">
<fa-icon [icon]="faArrow"></fa-icon>
</button>
</div>
@@ -23,7 +23,7 @@
<p *ngFor="let line of comments">{{ line }}</p>
</mat-card-content>
<mat-card-actions>
<button (click)="onClickEdit()" mat-button>
<button [routerLink]="'/songs/' + song.ID + '/edit'" mat-button>
<fa-icon [icon]="faEdit"></fa-icon>
bearbeiten
</button>

View File

@@ -0,0 +1,34 @@
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {faEdit, faLongArrowAltLeft} from '@fortawesome/free-solid-svg-icons';
import {Song} from 'src/app/songs/models/song.model';
@Component({
selector: 'app-song-read',
templateUrl: './read.component.html',
styleUrls: ['./read.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SongReadComponent {
@Input() public song: Song;
public faArrow = faLongArrowAltLeft;
public faEdit = faEdit;
public get text(): string[] {
return this.song && this.song.Text ? this.song.Text.split(/\r?\n/) : [];
}
public get comments(): string[] {
return this.song && this.song.Comments ? this.song.Comments.split(/\r?\n/) : [];
}
public renderSongType(songType: string) {
switch (songType) {
case 'Praise':
return {name: 'Lobpreis', color: '#99FFB8'};
case 'Worship':
return {name: 'Anbetung', color: '#C999FF'};
default:
return null;
}
}
}

View File

@@ -1,4 +1,4 @@
import {base} from '../data/urls';
import {base} from '../../data/urls';
import {Injectable} from '@angular/core';
import {FileUploader} from 'ng2-file-upload';
@@ -8,7 +8,7 @@ import {FileUploader} from 'ng2-file-upload';
export class FileuploadFactory {
public static provideForNewFiles(songId: number): FileUploader {
const uploader = new FileUploader({
url: base + '/api/songs/' + songId + '/files',
url: `${base}/api/songs/${songId}/files`,
autoUpload: true,
isHTML5: true
});

View File

@@ -1,16 +1,20 @@
/* You can add global styles to this file, and also import other style files */
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
body {
margin: 0px;
}
html {
background-image: url(https://images.unsplash.com/photo-1476136236990-838240be4859?ixlib=rb-1.2.1&auto=format&fit=crop&w=2167&q=80);
}
body {
margin: 0;
app-root {
padding: 10px;
display: block;
}
.page-container {
padding: 20px;
padding: 10px;
box-sizing: border-box;
overflow: hidden;
border-radius: 8px;
@@ -32,24 +36,6 @@ html {
border-top-left-radius: 8px;
}
tbody {
tr.selected {
background-color: #0002;
}
tr:hover {
cursor: pointer;
background-color: #0001;
td {
color: #ff9900;
}
}
td.mat-cell {
padding: 0 5px;
}
}
&.pinned {
padding: 0;
@@ -57,16 +43,16 @@ html {
border-radius: 0;
th.mat-header-cell:first-of-type {
border-top-left-radius: 0px;
border-top-left-radius: 0;
}
th.mat-header-cell:last-of-type {
border-top-right-radius: 0px;
border-top-right-radius: 0;
}
.mat-table thead {
border-top-right-radius: 0px;
border-top-left-radius: 0px;
border-top-right-radius: 0;
border-top-left-radius: 0;
}
}
}
@@ -119,4 +105,4 @@ html {
}
}
}