production settings
This commit is contained in:
5
WEB/.firebaserc
Normal file
5
WEB/.firebaserc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"projects": {
|
||||||
|
"default": "worshipgenerator"
|
||||||
|
}
|
||||||
|
}
|
||||||
65
WEB/.gitignore
vendored
Normal file
65
WEB/.gitignore
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
firebase-debug.log*
|
||||||
|
|
||||||
|
# Firebase cache
|
||||||
|
.firebase/
|
||||||
|
|
||||||
|
# Firebase config
|
||||||
|
|
||||||
|
# Uncomment this if you'd like others to create their own Firebase project.
|
||||||
|
# For a team working on the same Firebase project(s), it is recommended to leave
|
||||||
|
# it commented so all members can deploy to the same project(s) in .firebaserc.
|
||||||
|
# .firebaserc
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
11
WEB/firebase.json
Normal file
11
WEB/firebase.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"hosting": {
|
||||||
|
"public": "dist/wgenerator",
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "**",
|
||||||
|
"destination": "/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
|
"deploy": "ng build --prod && firebase deploy",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
import {Expand, ODataQuery, ODataService} from 'odata-v4-ng';
|
import {Expand, ODataQuery, ODataService} from 'odata-v4-ng';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {map, tap} from 'rxjs/operators';
|
import {map, tap} from 'rxjs/operators';
|
||||||
import {base} from './urls';
|
import {environment} from '../../environments/environment';
|
||||||
|
|
||||||
export class ODataBaseService {
|
export class ODataBaseService {
|
||||||
private url: string;
|
private readonly url: string;
|
||||||
|
|
||||||
constructor(private odataService: ODataService, private entity: string) {
|
constructor(private odataService: ODataService, private entity: string) {
|
||||||
this.url = base + '/odata/';
|
this.url = `${environment.api}/odata/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public list$<TResponse>(properties: string[]): Observable<TResponse[]> {
|
public list$<TResponse>(properties: string[], skip: number = null, top: number = null): Observable<{ count: number, data: TResponse[] }> {
|
||||||
const query = new ODataQuery(this.odataService, this.url)
|
const query = new ODataQuery(this.odataService, this.url)
|
||||||
.entitySet(this.entity)
|
.entitySet(this.entity)
|
||||||
|
.countOption(true)
|
||||||
|
.skip(skip)
|
||||||
|
.top(top)
|
||||||
.select(properties);
|
.select(properties);
|
||||||
const get = query.get().pipe(map(_ => _.toPropertyValue<TResponse[]>()));
|
|
||||||
|
const get = query.get().pipe(map(_ => ({
|
||||||
|
count: _.getBodyAsJson()['@odata.count'],
|
||||||
|
data: _.toPropertyValue<TResponse[]>()
|
||||||
|
})));
|
||||||
|
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export class EditSongService {
|
|||||||
|
|
||||||
private firstFreeNumber(): number {
|
private firstFreeNumber(): number {
|
||||||
let number = 0;
|
let number = 0;
|
||||||
const numbers = this.songsService.songs.value.map(_ => _.Number);
|
const numbers = this.songsService.songs.value.data.map(_ => _.Number);
|
||||||
while (numbers.indexOf(++number) !== -1) {
|
while (numbers.indexOf(++number) !== -1) {
|
||||||
}
|
}
|
||||||
return number;
|
return number;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {Song} from '../songs/models/song.model';
|
|||||||
import {BehaviorSubject, Observable} from 'rxjs';
|
import {BehaviorSubject, Observable} from 'rxjs';
|
||||||
import {tap} from 'rxjs/operators';
|
import {tap} from 'rxjs/operators';
|
||||||
import {State} from './state';
|
import {State} from './state';
|
||||||
import {base} from './urls';
|
|
||||||
import {FileType} from '../songs/models/files-types.model';
|
import {FileType} from '../songs/models/files-types.model';
|
||||||
|
import {environment} from '../../environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -15,26 +15,25 @@ import {FileType} from '../songs/models/files-types.model';
|
|||||||
export class SongsService extends ODataBaseService {
|
export class SongsService extends ODataBaseService {
|
||||||
public state = new BehaviorSubject<State>(State.list);
|
public state = new BehaviorSubject<State>(State.list);
|
||||||
|
|
||||||
public songs: BehaviorSubject<Song[]> = new BehaviorSubject<Song[]>([]);
|
public songs = new BehaviorSubject<{ count: number, data: Song[] }>({count: 0, data: []});
|
||||||
|
|
||||||
constructor(odataService: ODataService, private httpClient: HttpClient) {
|
constructor(odataService: ODataService, private httpClient: HttpClient) {
|
||||||
super(odataService, 'songs');
|
super(odataService, 'songs');
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadSongList$(): Observable<Song[]> {
|
public loadSongList$(page: number, pageSize: number): Observable<{ count: number, data: Song[] }> {
|
||||||
const properties = ['ID', 'Name', 'Number', 'SongType', 'Key', 'Tempo'];
|
const properties = ['ID', 'Name', 'Number', 'SongType', 'Key', 'Tempo'];
|
||||||
const list = this.list$<Song>(properties).pipe(
|
const list = this.list$<Song>(properties, page * pageSize, pageSize).pipe(
|
||||||
tap(_ => this.songs.next(_))
|
tap(_ => this.songs.next(_))
|
||||||
);
|
);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public patch$(id: number, control: string, value: any): Observable<boolean> {
|
public patch$(id: number, control: string, value: any): Observable<boolean> {
|
||||||
const patch = super.patch$(id, control, value).pipe(
|
const patch = super.patch$(id, control, value).pipe(
|
||||||
tap(() => {
|
tap(() => {
|
||||||
const songs = this.songs.value;
|
const songs = this.songs.value;
|
||||||
const song = songs.filter(_ => _.ID === id)[0];
|
const song = songs.data.filter(_ => _.ID === id)[0];
|
||||||
song[control] = value;
|
song[control] = value;
|
||||||
this.songs.next(songs);
|
this.songs.next(songs);
|
||||||
})
|
})
|
||||||
@@ -55,7 +54,7 @@ export class SongsService extends ODataBaseService {
|
|||||||
name: string,
|
name: string,
|
||||||
fileType: FileType
|
fileType: FileType
|
||||||
): Observable<any> {
|
): Observable<any> {
|
||||||
const url = `${base}/api/songs/${songId}/files/${fileId}/edit?Name=${name}&FileType=${fileType}`;
|
const url = `${environment.api}/api/songs/${songId}/files/${fileId}/edit?Name=${name}&FileType=${fileType}`;
|
||||||
const get = this.httpClient.get(url);
|
const get = this.httpClient.get(url);
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
@@ -64,7 +63,7 @@ export class SongsService extends ODataBaseService {
|
|||||||
songId: number,
|
songId: number,
|
||||||
fileId: number
|
fileId: number
|
||||||
): Observable<any> {
|
): Observable<any> {
|
||||||
const url = `${base}/api/songs/${songId}/files/${fileId}/delete`;
|
const url = `${environment.api}/api/songs/${songId}/files/${fileId}/delete`;
|
||||||
const get = this.httpClient.get(url);
|
const get = this.httpClient.get(url);
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
// export const base = 'http://192.168.178.20/API';
|
|
||||||
export const base = 'http://test.benjamin-ifland.de';
|
|
||||||
@@ -13,6 +13,6 @@ export class SongsComponent {
|
|||||||
constructor(
|
constructor(
|
||||||
public songsService: SongsService
|
public songsService: SongsService
|
||||||
) {
|
) {
|
||||||
songsService.loadSongList$().subscribe();
|
songsService.loadSongList$(0, 15).subscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<fa-icon [icon]="faNew"></fa-icon>
|
<fa-icon [icon]="faNew"></fa-icon>
|
||||||
</button>
|
</button>
|
||||||
<table
|
<table
|
||||||
[dataSource]="songsService.songs | async"
|
[dataSource]="(songsService.songs | async).data"
|
||||||
class="mat-elevation-z8"
|
class="mat-elevation-z8"
|
||||||
mat-table
|
mat-table
|
||||||
>
|
>
|
||||||
@@ -72,4 +72,5 @@
|
|||||||
></tr>
|
></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<mat-paginator [length]="(songsService.songs | async).count" [pageSize]="15"></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import {SongsService} from '../../../../data/songs.service';
|
import {SongsService} from '../../../../data/songs.service';
|
||||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component} from '@angular/core';
|
import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ViewChild} from '@angular/core';
|
||||||
import {State} from 'src/app/data/state';
|
import {State} from 'src/app/data/state';
|
||||||
import {faFileMedical} from '@fortawesome/free-solid-svg-icons';
|
import {faFileMedical} from '@fortawesome/free-solid-svg-icons';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {map} from 'rxjs/operators';
|
import {map, switchMap} from 'rxjs/operators';
|
||||||
|
import {MatPaginator} from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-table',
|
selector: 'app-table',
|
||||||
@@ -11,18 +12,28 @@ import {map} from 'rxjs/operators';
|
|||||||
styleUrls: ['./table.component.less'],
|
styleUrls: ['./table.component.less'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class TableComponent {
|
export class TableComponent implements AfterViewInit {
|
||||||
public State = State;
|
public State = State;
|
||||||
public faNew = faFileMedical;
|
public faNew = faFileMedical;
|
||||||
public columnsFull = ['Number', 'Name', 'Key', 'SongType', 'Tempo'];
|
public columnsFull = ['Number', 'Name', 'Key', 'SongType', 'Tempo'];
|
||||||
public columnsPinned = ['Number', 'Name'];
|
public columnsPinned = ['Number', 'Name'];
|
||||||
|
|
||||||
|
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public songsService: SongsService,
|
public songsService: SongsService,
|
||||||
private change: ChangeDetectorRef
|
private ref: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ngAfterViewInit(): void {
|
||||||
|
this.paginator.page.pipe(
|
||||||
|
switchMap(_ => this.songsService.loadSongList$(_.pageIndex, _.pageSize))
|
||||||
|
).subscribe(() => {
|
||||||
|
this.ref.markForCheck();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public get columns(): Observable<string[]> {
|
public get columns(): Observable<string[]> {
|
||||||
return this.songsService.state.pipe(map(_ => _ === State.list ? this.columnsFull : this.columnsPinned));
|
return this.songsService.state.pipe(map(_ => _ === State.list ? this.columnsFull : this.columnsPinned));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {base} from '../../data/urls';
|
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {FileUploader} from 'ng2-file-upload';
|
import {FileUploader} from 'ng2-file-upload';
|
||||||
|
import {environment} from '../../../environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -8,7 +8,7 @@ import {FileUploader} from 'ng2-file-upload';
|
|||||||
export class FileuploadFactory {
|
export class FileuploadFactory {
|
||||||
public static provideForNewFiles(songId: number): FileUploader {
|
public static provideForNewFiles(songId: number): FileUploader {
|
||||||
const uploader = new FileUploader({
|
const uploader = new FileUploader({
|
||||||
url: `${base}/api/songs/${songId}/files`,
|
url: `${environment.api}/api/songs/${songId}/files`,
|
||||||
autoUpload: true,
|
autoUpload: true,
|
||||||
isHTML5: true
|
isHTML5: true
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {SongsRoutingModule} from './songs-routing.module';
|
|||||||
import {SongsComponent} from './components/songs/songs.component';
|
import {SongsComponent} from './components/songs/songs.component';
|
||||||
import {TableComponent} from './components/songs/table/table.component';
|
import {TableComponent} from './components/songs/table/table.component';
|
||||||
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
|
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
|
||||||
import {MatButtonModule, MatChipsModule, MatTableModule} from '@angular/material';
|
import {MatButtonModule, MatChipsModule, MatPaginatorModule, MatTableModule} from '@angular/material';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -17,7 +17,8 @@ import {MatButtonModule, MatChipsModule, MatTableModule} from '@angular/material
|
|||||||
|
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatButtonModule
|
MatButtonModule,
|
||||||
|
MatPaginatorModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SongsModule {
|
export class SongsModule {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true
|
production: true,
|
||||||
|
api: 'https://test.benjamin-ifland.de'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
// The list of file replacements can be found in `angular.json`.
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false
|
production: false,
|
||||||
|
api: 'http://test.benjamin-ifland.de'
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user