diff --git a/WEB/src/app/songs/modules/edit/edit-routing.module.ts b/WEB/src/app/songs/modules/edit/edit-routing.module.ts
new file mode 100644
index 0000000..6de2523
--- /dev/null
+++ b/WEB/src/app/songs/modules/edit/edit-routing.module.ts
@@ -0,0 +1,16 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {SongEditComponent} from './song-edit/song-edit.component';
+
+const routes: Routes = [{
+ path: '',
+ pathMatch: 'full',
+ component: SongEditComponent
+}];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class EditRoutingModule {
+}
diff --git a/WEB/src/app/songs/modules/edit/edit.module.ts b/WEB/src/app/songs/modules/edit/edit.module.ts
new file mode 100644
index 0000000..879db45
--- /dev/null
+++ b/WEB/src/app/songs/modules/edit/edit.module.ts
@@ -0,0 +1,44 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+
+import {EditRoutingModule} from './edit-routing.module';
+import {SongFormModule} from '../widget-modules/song-form/song-form.module';
+import {SongEditComponent} from './song-edit/song-edit.component';
+import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {FileUploadModule} from 'ng2-file-upload';
+import {
+ MatButtonModule,
+ MatCardModule,
+ MatChipsModule,
+ MatInputModule,
+ MatSelectModule,
+ MatTableModule,
+ MatTooltipModule
+} from '@angular/material';
+
+
+@NgModule({
+ declarations: [
+ SongEditComponent
+ ],
+ imports: [
+ CommonModule,
+ EditRoutingModule,
+ SongFormModule,
+ FontAwesomeModule,
+ FormsModule,
+ ReactiveFormsModule,
+ FileUploadModule,
+
+ MatCardModule,
+ MatChipsModule,
+ MatSelectModule,
+ MatInputModule,
+ MatTableModule,
+ MatButtonModule,
+ MatTooltipModule
+ ]
+})
+export class EditModule {
+}
diff --git a/WEB/src/app/songs/modules/new/new-routing.module.ts b/WEB/src/app/songs/modules/new/new-routing.module.ts
new file mode 100644
index 0000000..d925b60
--- /dev/null
+++ b/WEB/src/app/songs/modules/new/new-routing.module.ts
@@ -0,0 +1,16 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {SongNewComponent} from './song-new/song-new.component';
+
+const routes: Routes = [{
+ path: '',
+ pathMatch: 'full',
+ component: SongNewComponent
+}];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class NewRoutingModule {
+}
diff --git a/WEB/src/app/songs/modules/new/new.module.ts b/WEB/src/app/songs/modules/new/new.module.ts
new file mode 100644
index 0000000..37c6f78
--- /dev/null
+++ b/WEB/src/app/songs/modules/new/new.module.ts
@@ -0,0 +1,43 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+
+import {NewRoutingModule} from './new-routing.module';
+import {SongFormModule} from '../widget-modules/song-form/song-form.module';
+import {SongNewComponent} from './song-new/song-new.component';
+import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {FileUploadModule} from 'ng2-file-upload';
+import {
+ MatButtonModule,
+ MatCardModule,
+ MatChipsModule,
+ MatInputModule,
+ MatSelectModule,
+ MatTableModule,
+ MatTooltipModule
+} from '@angular/material';
+
+@NgModule({
+ declarations: [
+ SongNewComponent
+ ],
+ imports: [
+ CommonModule,
+ NewRoutingModule,
+ SongFormModule,
+ FontAwesomeModule,
+ FormsModule,
+ ReactiveFormsModule,
+ FileUploadModule,
+
+ MatCardModule,
+ MatChipsModule,
+ MatSelectModule,
+ MatInputModule,
+ MatTableModule,
+ MatButtonModule,
+ MatTooltipModule
+ ]
+})
+export class NewModule {
+}
diff --git a/WEB/src/app/songs/modules/read/read-routing.module.ts b/WEB/src/app/songs/modules/read/read-routing.module.ts
new file mode 100644
index 0000000..ebadd2b
--- /dev/null
+++ b/WEB/src/app/songs/modules/read/read-routing.module.ts
@@ -0,0 +1,16 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {SongComponent} from './song/song.component';
+
+const routes: Routes = [{
+ path: '',
+ pathMatch: 'full',
+ component: SongComponent
+}];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class ReadRoutingModule {
+}
diff --git a/WEB/src/app/songs/modules/read/read.module.ts b/WEB/src/app/songs/modules/read/read.module.ts
new file mode 100644
index 0000000..5df4d4d
--- /dev/null
+++ b/WEB/src/app/songs/modules/read/read.module.ts
@@ -0,0 +1,50 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+
+import {ReadRoutingModule} from './read-routing.module';
+import {SongFormModule} from '../widget-modules/song-form/song-form.module';
+import {SongComponent} from './song/song.component';
+import {SongReadComponent} from './read/read.component';
+import {SongFilesEditComponent} from './files/edit/song-files-edit.component';
+import {SongFilesComponent} from './files/files.component';
+import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+import {
+ MatButtonModule,
+ MatCardModule,
+ MatChipsModule,
+ MatInputModule,
+ MatSelectModule,
+ MatTableModule,
+ MatTooltipModule
+} from '@angular/material';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {FileUploadModule} from 'ng2-file-upload';
+
+
+@NgModule({
+ declarations: [
+ SongComponent,
+ SongReadComponent,
+ SongFilesEditComponent,
+ SongFilesComponent
+ ],
+ imports: [
+ CommonModule,
+ ReadRoutingModule,
+ SongFormModule,
+ FontAwesomeModule,
+ FormsModule,
+ ReactiveFormsModule,
+ FileUploadModule,
+
+ MatCardModule,
+ MatChipsModule,
+ MatSelectModule,
+ MatInputModule,
+ MatTableModule,
+ MatButtonModule,
+ MatTooltipModule
+ ]
+})
+export class ReadModule {
+}
diff --git a/WEB/src/app/songs/modules/read/song/song.component.html b/WEB/src/app/songs/modules/read/song/song.component.html
new file mode 100644
index 0000000..b75e3e0
--- /dev/null
+++ b/WEB/src/app/songs/modules/read/song/song.component.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/WEB/src/app/songs/modules/read/song/song.component.spec.ts b/WEB/src/app/songs/modules/read/song/song.component.spec.ts
new file mode 100644
index 0000000..4cb9908
--- /dev/null
+++ b/WEB/src/app/songs/modules/read/song/song.component.spec.ts
@@ -0,0 +1,25 @@
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {SongComponent} from './song.component';
+
+describe('SongComponent', () => {
+ let component: SongComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [SongComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SongComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/WEB/src/app/songs/modules/read/song/song.component.ts b/WEB/src/app/songs/modules/read/song/song.component.ts
new file mode 100644
index 0000000..336d9fa
--- /dev/null
+++ b/WEB/src/app/songs/modules/read/song/song.component.ts
@@ -0,0 +1,19 @@
+import {Component} from '@angular/core';
+import {ActivatedRoute} from '@angular/router';
+import {Song} from '../../../models/song.model';
+import {Observable} from 'rxjs';
+import {map} from 'rxjs/operators';
+
+@Component({
+ selector: 'app-song',
+ templateUrl: './song.component.html',
+})
+export class SongComponent {
+
+ constructor(private route: ActivatedRoute) {
+ }
+
+ public get song(): Observable {
+ return this.route.data.pipe(map((data: { song: Song }) => data.song));
+ }
+}
diff --git a/WEB/src/app/songs/modules/widget-modules/song-form/song-form.module.ts b/WEB/src/app/songs/modules/widget-modules/song-form/song-form.module.ts
new file mode 100644
index 0000000..3165691
--- /dev/null
+++ b/WEB/src/app/songs/modules/widget-modules/song-form/song-form.module.ts
@@ -0,0 +1,29 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {SongFormComponent} from './song-form.component';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {MatInputModule, MatRadioModule, MatSelectModule} from '@angular/material';
+import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+
+
+@NgModule({
+ declarations: [
+ SongFormComponent
+ ],
+ imports: [
+ CommonModule,
+ FormsModule,
+ ReactiveFormsModule,
+ FontAwesomeModule,
+
+ MatInputModule,
+ MatSelectModule,
+ MatRadioModule,
+
+ ],
+ exports: [
+ SongFormComponent
+ ]
+})
+export class SongFormModule {
+}
diff --git a/WEB/src/app/songs/song-resolver.ts b/WEB/src/app/songs/song-resolver.ts
new file mode 100644
index 0000000..6a3a742
--- /dev/null
+++ b/WEB/src/app/songs/song-resolver.ts
@@ -0,0 +1,28 @@
+import {Injectable} from '@angular/core';
+import {Song} from './models/song.model';
+import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
+import {Observable} from 'rxjs';
+import {ODataBaseService} from '../data/ODataBaseService';
+import {ODataService} from 'odata-v4-ng';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SongResolver extends ODataBaseService implements Resolve {
+
+ constructor(odataService: ODataService) {
+ super(odataService, 'songs');
+ }
+
+ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
+ const id = +route.params.songId;
+ const get$ = this.get$(
+ id,
+ ['ID', 'Name', 'Text', 'Comments', 'SongType', 'Key', 'Tempo'],
+ ['Files']
+ );
+
+ return get$;
+ }
+
+}
diff --git a/WEB/src/app/songs/songs-routing.module.ts b/WEB/src/app/songs/songs-routing.module.ts
new file mode 100644
index 0000000..5142261
--- /dev/null
+++ b/WEB/src/app/songs/songs-routing.module.ts
@@ -0,0 +1,48 @@
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {SongsComponent} from './components/songs/songs.component';
+import {SongResolver} from './song-resolver';
+
+
+const routes: Routes = [
+ {
+ path: '',
+ component: SongsComponent,
+ children: [
+ {
+ path: 'new',
+ loadChildren: () => import('./modules/new/new.module').then(_ => _.NewModule)
+ },
+ {
+ path: ':songId',
+ resolve: {
+ song: SongResolver
+ },
+ runGuardsAndResolvers: 'always',
+ children: [
+ {
+ path: '',
+ redirectTo: 'read',
+ pathMatch: 'full',
+ },
+ {
+ path: 'read',
+ loadChildren: () => import('./modules/read/read.module').then(_ => _.ReadModule)
+ },
+ {
+ path: 'edit',
+ loadChildren: () => import('./modules/edit/edit.module').then(_ => _.EditModule)
+ }
+
+ ]
+ }
+ ]
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class SongsRoutingModule {
+}
diff --git a/WEB/src/app/songs/songs.module.ts b/WEB/src/app/songs/songs.module.ts
new file mode 100644
index 0000000..f7dd546
--- /dev/null
+++ b/WEB/src/app/songs/songs.module.ts
@@ -0,0 +1,24 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+
+import {SongsRoutingModule} from './songs-routing.module';
+import {SongsComponent} from './components/songs/songs.component';
+import {TableComponent} from './components/songs/table/table.component';
+import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+import {MatButtonModule, MatChipsModule, MatTableModule} from '@angular/material';
+
+
+@NgModule({
+ declarations: [SongsComponent, TableComponent],
+ imports: [
+ CommonModule,
+ SongsRoutingModule,
+ FontAwesomeModule,
+
+ MatTableModule,
+ MatChipsModule,
+ MatButtonModule
+ ]
+})
+export class SongsModule {
+}