diff --git a/app/app.component.html b/app/app.component.html index 7bae7f8..846f041 100644 --- a/app/app.component.html +++ b/app/app.component.html @@ -1,9 +1,11 @@
\ No newline at end of file +
diff --git a/app/app.module.ts b/app/app.module.ts index 9c16251..159d6bd 100644 --- a/app/app.module.ts +++ b/app/app.module.ts @@ -11,6 +11,8 @@ import { TopicsComponent } from "./pages/faq/topics.components"; import { QuestionsComponent } from "./pages/faq/questions.component"; import { FAQService } from "./services/faq.service"; import { ModalModule } from 'ngx-bootstrap'; +import { CollapseModule } from 'ngx-bootstrap'; +import { AccordionModule } from 'ngx-bootstrap'; import { TopicsFormComponent } from "./pages/faq/topics-form.component"; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ModalFormComponent } from "./pages/modal-form.component"; @@ -25,6 +27,8 @@ import { NewPageHelpContentComponent } from "./pages/helpcontent/new-page-help-c import { CKEditorModule } from 'ng2-ckeditor'; import { PageContentFormComponent } from "./pages/helpcontent/page-help-content-form.component"; import { EditPageHelpContentComponent } from "./pages/helpcontent/edit-page-help-content.component"; +import { SelectEntitiesComponent } from "./pages/helpcontent/selectEntities.component"; +import { EntityFormComponent } from "./pages/helpcontent/entity-form.component"; @NgModule({ imports: [ @@ -33,6 +37,8 @@ import { EditPageHelpContentComponent } from "./pages/helpcontent/edit-page-help HttpModule, JsonpModule, ModalModule.forRoot(), + CollapseModule.forRoot(), + AccordionModule.forRoot(), FormsModule, ReactiveFormsModule, JWBootstrapSwitchModule, @@ -52,7 +58,9 @@ import { EditPageHelpContentComponent } from "./pages/helpcontent/edit-page-help PageHelpContentsComponent, NewPageHelpContentComponent, PageContentFormComponent, - EditPageHelpContentComponent + EditPageHelpContentComponent, + SelectEntitiesComponent, + EntityFormComponent ], providers: [ FAQService, @@ -62,4 +70,4 @@ import { EditPageHelpContentComponent } from "./pages/helpcontent/edit-page-help bootstrap: [ AppComponent ] }) -export class AppModule { } \ No newline at end of file +export class AppModule { } diff --git a/app/app.routing.ts b/app/app.routing.ts index 676f409..a33d204 100644 --- a/app/app.routing.ts +++ b/app/app.routing.ts @@ -7,6 +7,7 @@ import { Routes, RouterModule } from '@angular/router'; import { DashboardComponent } from "./dashboard.component"; import { TopicsComponent } from "./pages/faq/topics.components"; import { QuestionsComponent } from "./pages/faq/questions.component"; +import { SelectEntitiesComponent } from "./pages/helpcontent/selectEntities.component"; import { PagesComponent } from "./pages/helpcontent/pages.component"; import { PageHelpContentsComponent } from "./pages/helpcontent/page-help-contents.component"; import { NewPageHelpContentComponent } from "./pages/helpcontent/new-page-help-content.component"; @@ -30,6 +31,10 @@ const appRoutes: Routes = [ path: 'questions', component: QuestionsComponent, }, + { + path: 'selectEntities', + component: SelectEntitiesComponent, + }, { path: 'pages', component: PagesComponent, @@ -43,7 +48,8 @@ const appRoutes: Routes = [ component: NewPageHelpContentComponent, }, { - path: 'pageContents/edit/:id', + //path: 'pageContents/edit/:id', + path: 'pageContents/edit', component: EditPageHelpContentComponent, } ]; @@ -51,4 +57,4 @@ const appRoutes: Routes = [ export const appRoutingProviders: any[] = [ ]; -export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes); \ No newline at end of file +export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes); diff --git a/app/dashboard.component.html b/app/dashboard.component.html index abd622b..c60bae7 100644 --- a/app/dashboard.component.html +++ b/app/dashboard.component.html @@ -5,12 +5,12 @@ -
Dashboard
+
Research Community Administration Dashboard

- A list of tools to help the administrator of the OpenMinTeD to manage FAQs, help texts, etc... + A list of tools to help the administrator of the OpenAIRE-Connect to manage FAQs, help texts, etc...

diff --git a/app/domain/community.ts b/app/domain/community.ts new file mode 100644 index 0000000..48d1ca0 --- /dev/null +++ b/app/domain/community.ts @@ -0,0 +1,13 @@ +import {Page} from './page'; + +export interface Community { + _id: string; + name: string; + entities: string[]; + pages: Page[]; +} + +// export interface CheckCommunity { +// community : Community; +// checked : boolean; +// } diff --git a/app/domain/entity.ts b/app/domain/entity.ts new file mode 100644 index 0000000..c7d3a84 --- /dev/null +++ b/app/domain/entity.ts @@ -0,0 +1,10 @@ +export class Entity { + _id: string; + name: string; + isEnabled :boolean; +} + +export interface CheckEntity { + entity : Entity; + checked : boolean; +} diff --git a/app/domain/page-help-content.ts b/app/domain/page-help-content.ts index 4defe03..086c800 100644 --- a/app/domain/page-help-content.ts +++ b/app/domain/page-help-content.ts @@ -2,10 +2,12 @@ * Created by stefania on 7/13/17. */ import { Page } from "./page"; +import { Community } from "./community"; export interface PageHelpContent { _id: string; page: Page | string; + community: Community | string; placement : string; order: number; content: string; @@ -21,4 +23,4 @@ export interface PageHelpContentFilterOptions { id : string; active : Boolean; text : RegExp; -} \ No newline at end of file +} diff --git a/app/domain/page.ts b/app/domain/page.ts index a78b48a..5d849a3 100644 --- a/app/domain/page.ts +++ b/app/domain/page.ts @@ -1,13 +1,14 @@ -/** - * Created by stefania on 7/13/17. - */ +import { Entity } from './entity'; + export interface Page { _id: string; route: string; name: string; + isEnabled :boolean; + entities: Entity[];// | string[]; } export interface CheckPage { page : Page; checked : boolean; -} \ No newline at end of file +} diff --git a/app/pages/helpcontent/edit-page-help-content.component.html b/app/pages/helpcontent/edit-page-help-content.component.html index dc093ab..9cd9eb5 100644 --- a/app/pages/helpcontent/edit-page-help-content.component.html +++ b/app/pages/helpcontent/edit-page-help-content.component.html @@ -12,7 +12,7 @@
{{errorMessage}}
- +
Update page content
diff --git a/app/pages/helpcontent/edit-page-help-content.component.ts b/app/pages/helpcontent/edit-page-help-content.component.ts index 52eebe5..0df3487 100644 --- a/app/pages/helpcontent/edit-page-help-content.component.ts +++ b/app/pages/helpcontent/edit-page-help-content.component.ts @@ -18,6 +18,8 @@ export class EditPageHelpContentComponent implements OnInit, OnDestroy{ @ViewChild(PageContentFormComponent) public formComponent : PageContentFormComponent; + private communityId: string; + private sub: Subscription; private pageHelpContent: PageHelpContent; @@ -31,9 +33,11 @@ export class EditPageHelpContentComponent implements OnInit, OnDestroy{ ngOnInit() { - this.sub = this.route.params.subscribe(params => { - let id = params['id']; - this._helpContentService.getPageHelpContent(id as string).subscribe( + this.sub = this.route.queryParams.subscribe(params => { + //let id = params['id']; + let pageContentId = params['pageContentId']; + this.communityId = params['communityId']; + this._helpContentService.getPageHelpContent(pageContentId as string).subscribe( pageHelpContent => this.updateForm(pageHelpContent), error => this.handleError('System error retrieving page help content', error)); }); @@ -65,4 +69,4 @@ export class EditPageHelpContentComponent implements OnInit, OnDestroy{ } } -} \ No newline at end of file +} diff --git a/app/pages/helpcontent/entity-form.component.html b/app/pages/helpcontent/entity-form.component.html new file mode 100644 index 0000000..d055686 --- /dev/null +++ b/app/pages/helpcontent/entity-form.component.html @@ -0,0 +1,32 @@ +
+
+ + +
+ + + + + + + + +
+ + + diff --git a/app/pages/helpcontent/entity-form.component.ts b/app/pages/helpcontent/entity-form.component.ts new file mode 100644 index 0000000..1fe497f --- /dev/null +++ b/app/pages/helpcontent/entity-form.component.ts @@ -0,0 +1,34 @@ +import {Component, OnInit, Input} from '@angular/core'; +import {FormGroup, FormBuilder, Validators} from "@angular/forms"; + + +@Component({ + selector: 'entity-form', + templateUrl: './entity-form.component.html', +}) + +export class EntityFormComponent implements OnInit{ + + @Input('group') + myForm: FormGroup; + + constructor(private _fb: FormBuilder){} + + ngOnInit(): void { + } + + public get form() { + return this._fb.group({ + name : ['', Validators.required], + _id : '' + }); + } + + public reset() { + this.myForm.patchValue({ + name : '', + _id : '' + }); + } + +} diff --git a/app/pages/helpcontent/new-page-help-content.component.html b/app/pages/helpcontent/new-page-help-content.component.html index e6f5640..d1487eb 100644 --- a/app/pages/helpcontent/new-page-help-content.component.html +++ b/app/pages/helpcontent/new-page-help-content.component.html @@ -12,7 +12,7 @@
{{errorMessage}}
- + Save page content
diff --git a/app/pages/helpcontent/new-page-help-content.component.ts b/app/pages/helpcontent/new-page-help-content.component.ts index 28f488c..508b2ef 100644 --- a/app/pages/helpcontent/new-page-help-content.component.ts +++ b/app/pages/helpcontent/new-page-help-content.component.ts @@ -19,15 +19,23 @@ export class NewPageHelpContentComponent { private errorMessage : string = null; + private communityId: string; + constructor( private route: ActivatedRoute, private router: Router, private _helpContentService: HelpContentService) {} + ngOnInit() { + this.route.queryParams.subscribe(params => { + this.communityId = params['communityId']; + }); + } + private saveCustom() { this.errorMessage = null; - + if(this.formComponent.myForm.valid) { let pageHelpContent : PageHelpContent = this.formComponent.myForm.value; this._helpContentService.savePageHelpContent(pageHelpContent).subscribe( @@ -43,4 +51,4 @@ export class NewPageHelpContentComponent { this.errorMessage = message + ' (Server responded: ' + error + ')'; } -} \ No newline at end of file +} diff --git a/app/pages/helpcontent/page-form.component.html b/app/pages/helpcontent/page-form.component.html index d88ab2c..4981533 100644 --- a/app/pages/helpcontent/page-form.component.html +++ b/app/pages/helpcontent/page-form.component.html @@ -7,8 +7,106 @@ + + + + + + + + + + + + + + + + + +
+ +
+ +
{{entity.name}}, 
+ + +
+ + + + + + + + {{entity.name}} + +
+
+
+ + + + + + + + + + + - \ No newline at end of file + diff --git a/app/pages/helpcontent/page-form.component.ts b/app/pages/helpcontent/page-form.component.ts index 0ea990c..dfec562 100644 --- a/app/pages/helpcontent/page-form.component.ts +++ b/app/pages/helpcontent/page-form.component.ts @@ -2,8 +2,11 @@ * Created by stefania on 7/13/17. */ import {Component, OnInit, Input} from '@angular/core'; -import {FormGroup, FormBuilder, Validators} from "@angular/forms"; - +import {FormGroup, FormArray, FormBuilder, Validators} from "@angular/forms"; +import { CollapseDirective } from 'ngx-bootstrap/collapse'; +//import { AccordionDirective } from 'ngx-bootstrap/accordion'; +import {Entity} from '../../domain/entity'; +import { HelpContentService } from "../../services/help-content.service"; @Component({ selector: 'page-form', @@ -14,17 +17,73 @@ export class PageFormComponent implements OnInit{ @Input('group') myForm: FormGroup; + @Input('selectedCommunityId') + public selectedCommunityId: string; - constructor(private _fb: FormBuilder){} + public errorMessage: string; - ngOnInit(): void { + public allEntities: Map = new Map(); + private gotEntities: boolean = false; + + constructor(public _fb: FormBuilder, private _helpContentService: HelpContentService){} + + ngOnInit(): void {} + + public toggle() { + this.myForm.value.isCollapsed = !this.myForm.value.isCollapsed; + + if(!this.myForm.value.isCollapsed) { + let includedEntities: Set = new Set(); + for(let entityName of this.myForm.value.entities) { + includedEntities.add(entityName._id); + } + + let allEntities = this.allEntities; + + let self = this; + allEntities.forEach(function (status, entity, map) { + if(includedEntities.has(entity._id)) { + self.allEntities.set(entity, true); + } else { + self.allEntities.set(entity, false); + } + }); + + + if(!this.gotEntities) { + this.gotEntities = true; + this.getEntities(includedEntities); + } + } + } + + public getEntities(includedEntities: Set) { + let self = this; + this._helpContentService.getEntities().subscribe( + entities => { + for(let entity of entities) { + if(includedEntities.has(entity._id)) { + self.allEntities.set(entity, true); + } else { + self.allEntities.set(entity, false); + } + } + }, + error => this.handleError('System error retrieving community entities', error)); + } + + public getKeys( map) { + return Array.from(map.keys()); } public get form() { return this._fb.group({ route : ['', Validators.required], name : ['', Validators.required], - _id : '' + //isEnabled: ['', Validators.required], + entities: this._fb.array([]), + _id : '', + isCollapsed: [true] }); } @@ -32,8 +91,64 @@ export class PageFormComponent implements OnInit{ this.myForm.patchValue({ route : '', name : '', - _id : '' + //isEnabled: '', + //entities: this._fb.array([]), + _id : '', + isCollapsed: [true] }); + + this.setEntities([]); } -} \ No newline at end of file + public get entities(): FormArray { + return this.myForm.get('entities') as FormArray; + }; + + setEntities(entities: Entity[]) { + const entityFGs = entities.map(entity => this._fb.group(entity)); + const entityFormArray = this._fb.array(entityFGs); + this.myForm.setControl('entities', entityFormArray); + } + + addEntity() { + this.myForm.value.entities.push(this._fb.group(new Entity())); + } + + public toggleEntity(status : boolean, id : string, entity: Entity) { + let index: number = -1; + for(let i=0; i= 0) { + this.myForm.value.entities.splice(index, 1); + console.info("delete : "+this.myForm.value.entities.length); + } + } +/* + this._helpContentService.toggleEntityOfPage(this.myForm.value._id,id,status).subscribe( + () => { + + }, + error => this.handleError('System error changing the status of the enity of page', error) + ); +*/ + } + + handleError(message: string, error) { + if(error == null) { + this.reset(); + } + this.errorMessage = message + ' (Server responded: ' + error + ')'; + } +} diff --git a/app/pages/helpcontent/page-help-content-form.component.ts b/app/pages/helpcontent/page-help-content-form.component.ts index a3bd785..a8f986d 100644 --- a/app/pages/helpcontent/page-help-content-form.component.ts +++ b/app/pages/helpcontent/page-help-content-form.component.ts @@ -16,6 +16,8 @@ export class PageContentFormComponent implements OnInit{ @Input('group') myForm: FormGroup; + @Input('communityId') + communityId: string; private availablePages : Page[] = []; private errorMessage: string; @@ -26,7 +28,7 @@ export class PageContentFormComponent implements OnInit{ ngOnInit() { this.myForm = this.form; - this._helpContentService.getPages().subscribe( + this._helpContentService.getCommunityPages(this.communityId).subscribe( pages => this.availablePages = pages, error => this.handleError('System error retrieving pages', error)); } @@ -34,6 +36,7 @@ export class PageContentFormComponent implements OnInit{ public get form() { return this._fb.group({ page : ['',Validators.required], + community : this.communityId, placement : ['', Validators.required], content : ['', Validators.required], order : ['1', Validators.required], @@ -45,6 +48,7 @@ export class PageContentFormComponent implements OnInit{ public reset() { this.myForm.patchValue({ page : '', + community : this.communityId, placement : '', content : [''], order : '1', @@ -57,4 +61,4 @@ export class PageContentFormComponent implements OnInit{ handleError(message: string, error) { this.errorMessage = message + ' (Server responded: ' + error + ')'; } -} \ No newline at end of file +} diff --git a/app/pages/helpcontent/page-help-contents.component.html b/app/pages/helpcontent/page-help-contents.component.html index 1a6f311..e785451 100644 --- a/app/pages/helpcontent/page-help-contents.component.html +++ b/app/pages/helpcontent/page-help-contents.component.html @@ -11,7 +11,8 @@ - New Page Content + + New Page Content
@@ -23,15 +24,29 @@
+
+
+ +
@@ -81,6 +97,9 @@
{{check.pageHelpContent.page.name}}
+
+
{{check.pageHelpContent.community.name}}
+
{{check.pageHelpContent.placement}}
@@ -92,11 +111,11 @@
-
- +
+
-
+
{{check.pageHelpContent.content}}
@@ -124,4 +143,3 @@ Are you sure you want to delete the selected page content(s)? - diff --git a/app/pages/helpcontent/page-help-contents.component.ts b/app/pages/helpcontent/page-help-contents.component.ts index 3d10375..0679ad7 100644 --- a/app/pages/helpcontent/page-help-contents.component.ts +++ b/app/pages/helpcontent/page-help-contents.component.ts @@ -8,6 +8,7 @@ import { HelpContentService } from "../../services/help-content.service"; import { PageHelpContent, CheckPageHelpContent, PageHelpContentFilterOptions } from "../../domain/page-help-content"; import { Page } from "../../domain/page"; import {Router} from "@angular/router"; +import { Community } from "../../domain/community"; @Component({ selector: 'page-help-contents', @@ -45,16 +46,31 @@ export class PageHelpContentsComponent implements OnInit { public counter = {all : 0, active : 0, inactive : 0}; + public communities: Community[] = []; + + public selectedCommunityId: string; + ngOnInit() { - this.getPages(); - this.getPageHelpContents(); + this.getCommunities(); // this.formGroup = this.formComponent.form; } constructor(private _helpService: HelpContentService, private router : Router) {} - getPages() { - this._helpService.getPages().subscribe( + getCommunities() { + let self = this; + this._helpService.getCommunities().subscribe( + communities => { + self.communities = communities; + self.selectedCommunityId = self.communities[0]._id; + this.getPages(self.selectedCommunityId); + this.getPageHelpContents(self.selectedCommunityId); + }, + error => this.handleError('System error retrieving communities', error)); + } + + getPages(community_id: string) { + this._helpService.getCommunityPages(community_id).subscribe( pages => this.pages = pages, error => this.handleError('System error retrieving pages', error)); } @@ -72,12 +88,13 @@ export class PageHelpContentsComponent implements OnInit { this.counter.all = this.counter.active + this.counter.inactive; } - getPageHelpContents() { + getPageHelpContents(community_id: string) { let self = this; - this._helpService.getPageHelpContents().subscribe( + this._helpService.getCommunityPageHelpContents(community_id).subscribe( pageHelpContents => { self.pageHelpContents = pageHelpContents as Array; self.counter.all = self.pageHelpContents.length; + self.pageHelpContentsCheckboxes = []; self.pageHelpContents.forEach(_ => { self.pageHelpContentsCheckboxes.push({pageHelpContent : _, checked : false}); }); @@ -132,14 +149,16 @@ export class PageHelpContentsComponent implements OnInit { } public editPageHelpContent(_id : string) { - this.router.navigate(['/pageContents/edit/', _id]); + //this.router.navigate(['/pageContents/edit/', _id]); + this.router.navigate( ['/pageContents/edit/'], { queryParams: { "pageContentId": _id, "communityId": this.selectedCommunityId } } ); } public togglePageHelpContents(status : boolean, ids : string[]) { this._helpService.togglePageHelpContents(ids,status).subscribe( - ret => { - for(let id of ret) { + () => { + for(let id of ids) { let i = this.pageHelpContentsCheckboxes.findIndex(_ => _.pageHelpContent._id == id); + console.info(i); this.pageHelpContentsCheckboxes[i].pageHelpContent.isActive=status; } this.countPageHelpContents(); @@ -219,4 +238,14 @@ export class PageHelpContentsComponent implements OnInit { } this.errorMessage = message + ' (Server responded: ' + error + ')'; } -} \ No newline at end of file + + public filterByCommunity(event: any) { + this.selectedCommunityId = event.target.value; + this.applyCommunityFilter(this.selectedCommunityId); + } + + public applyCommunityFilter(community_id: string) { + this.getPages(community_id); + this.getPageHelpContents(community_id); + } +} diff --git a/app/pages/helpcontent/pages.component.html b/app/pages/helpcontent/pages.component.html index 1b954aa..56c3697 100644 --- a/app/pages/helpcontent/pages.component.html +++ b/app/pages/helpcontent/pages.component.html @@ -38,11 +38,24 @@
+ +
+ +
+ @@ -51,12 +64,26 @@
-
+
{{check.page.route}}
-
+
{{check.page.name}}
+
+ +
+ +
+
+ +
+
+
+
+ {{entity.name}}, +
+
@@ -78,13 +105,15 @@
- + [isModalShown]="isModalShown" (emmitObject)="pageSavedSuccessfully($event)" (emmitError)="handleError($event)" + [selectedCommunityId]="selectedCommunityId"> + - - + + diff --git a/app/pages/helpcontent/pages.component.ts b/app/pages/helpcontent/pages.component.ts index ae22037..9867d86 100644 --- a/app/pages/helpcontent/pages.component.ts +++ b/app/pages/helpcontent/pages.component.ts @@ -8,6 +8,7 @@ import { ModalFormComponent } from "../modal-form.component"; import { DeleteConfirmationDialogComponent } from "../delete-confirmation-dialog.component"; import { PageFormComponent } from "./page-form.component"; import { CheckPage, Page } from "../../domain/page"; +import { Community } from "../../domain/community"; @Component({ selector: 'pages', @@ -39,18 +40,25 @@ export class PagesComponent implements OnInit { private searchText : RegExp = new RegExp(''); + public communities: Community[] = []; + + public selectedCommunityId: string; + ngOnInit() { - this.getPages(); + this.getCommunities(); + this.formGroup = this.formComponent.form; } constructor(private _helpContentService: HelpContentService) {} - getPages() { + getPages(community_id: string) { let self = this; - this._helpContentService.getPages().subscribe( + this._helpContentService.getCommunityPages(community_id).subscribe( pages => { self.pages = pages; + self.pagesCheckboxes = []; + pages.forEach(_ => { self.pagesCheckboxes.push({page : _, checked : false}); }); @@ -58,6 +66,17 @@ export class PagesComponent implements OnInit { error => this.handleError('System error retrieving pages', error)); } + getCommunities() { + let self = this; + this._helpContentService.getCommunities().subscribe( + communities => { + self.communities = communities; + self.getPages(self.communities[0]._id); + self.selectedCommunityId = self.communities[0]._id; + }, + error => this.handleError('System error retrieving communities', error)); + } + public showModal():void { this.modal.showModal(); } @@ -67,6 +86,7 @@ export class PagesComponent implements OnInit { } public applyCheck(flag : boolean) { + console.info("applyCheck "+flag); this.pagesCheckboxes.forEach(_ => _.checked = flag); } @@ -101,15 +121,23 @@ export class PagesComponent implements OnInit { public editPage(i : number) { let page : Page = this.pagesCheckboxes[i].page; this.formGroup.patchValue(page); + const entityFGs = page.entities.map(entity => this.formComponent._fb.group(entity)); + const entityFormArray = this.formComponent._fb.array(entityFGs); + this.formGroup.setControl('entities', entityFormArray); + console.info(this.formGroup.value); this.updateModal.showModal(); } public pageSavedSuccessfully(page: Page) { this.pagesCheckboxes.push({page : page, checked : false}); + console.info("checkboxes length: "+this.pagesCheckboxes.length); this.applyCheck(false); } public pageUpdatedSuccessfully(page : Page) { + console.info(page._id); + console.info(this.pagesCheckboxes.find(checkItem => (checkItem.page._id == page._id))); + console.info(page.entities); this.pagesCheckboxes.find(checkItem => checkItem.page._id==page._id).page = page; this.applyCheck(false); } @@ -137,4 +165,33 @@ export class PagesComponent implements OnInit { } this.errorMessage = message + ' (Server responded: ' + error + ')'; } -} \ No newline at end of file + + + + public filterByCommunity(event: any) { + this.selectedCommunityId = event.target.value; + this.applyCommunityFilter(this.selectedCommunityId); + } + + public applyCommunityFilter(community_id: string) { + this.getPages(community_id); + } + + public togglePage(status : boolean, id : string) { + this._helpContentService.togglePage(this.selectedCommunityId,id,status).subscribe( + () => { + // for(let id of ret) { + // let i = this.pagesCheckboxes.findIndex(_ => _.page._id == id); + // this.pagesCheckboxes[i].page.isEnabled=status; + // } + //this.countPageHelpContents(); + let i = this.pagesCheckboxes.findIndex(_ => _.page._id == id); + this.pagesCheckboxes[i].page.isEnabled=status; + this.applyCheck(false); + }, + error => this.handleError('System error changing the status of the selected page(s)', error) + ); + } + + +} diff --git a/app/pages/helpcontent/selectEntities.component.html b/app/pages/helpcontent/selectEntities.component.html new file mode 100644 index 0000000..9d1fa3e --- /dev/null +++ b/app/pages/helpcontent/selectEntities.component.html @@ -0,0 +1,97 @@ +
+
+ + +
+
+
+ + + +
+
+
+
+ +
+ +
+ +
+
+
+ + + +
+ + +
+
No entities found
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + Are you sure you want to delete the selected entity(-ies)? + diff --git a/app/pages/helpcontent/selectEntities.component.ts b/app/pages/helpcontent/selectEntities.component.ts new file mode 100644 index 0000000..aca4dd6 --- /dev/null +++ b/app/pages/helpcontent/selectEntities.component.ts @@ -0,0 +1,180 @@ +import { Component, ViewChild, OnInit } from '@angular/core'; +import { HelpContentService } from "../../services/help-content.service"; +import { FormGroup } from "@angular/forms"; +import { ModalFormComponent } from "../modal-form.component"; +import { DeleteConfirmationDialogComponent } from "../delete-confirmation-dialog.component"; +import { EntityFormComponent } from "./entity-form.component"; +import { CheckEntity, Entity } from "../../domain/entity"; +import { Community } from "../../domain/community"; + +@Component({ + selector: 'selectEntities', + templateUrl: './selectEntities.component.html', +}) + +export class SelectEntitiesComponent implements OnInit { + + // @ViewChild(ModalFormComponent) + @ViewChild('saveModal') + public modal:ModalFormComponent; + + @ViewChild('updateModal') + public updateModal:ModalFormComponent; + + @ViewChild('deleteConfirmationModal') + public deleteConfirmationModal : DeleteConfirmationDialogComponent; + + @ViewChild(EntityFormComponent) + public formComponent : EntityFormComponent; + + public entitiesCheckboxes : CheckEntity[] = []; + + public entities : Entity[] = []; + + public errorMessage: string; + + public formGroup : FormGroup; + + private searchText : RegExp = new RegExp(''); + + public communities: Community[] = []; + + public selectedCommunityId: string; + + ngOnInit() { + this.getCommunities(); + + this.formGroup = this.formComponent.form; + } + + constructor(private _helpContentService: HelpContentService) {} + + getCommunities() { + let self = this; + this._helpContentService.getCommunities().subscribe( + communities => { + self.communities = communities; + self.getEntities(self.communities[0]._id); + self.selectedCommunityId = self.communities[0]._id; + }, + error => this.handleError('System error retrieving communities', error)); + } + + getEntities(community_id: string) { + let self = this; + this._helpContentService.getCommunityEntities(community_id).subscribe( + entities => { + self.entities = entities; + self.entitiesCheckboxes = []; + + entities.forEach(_ => { + self.entitiesCheckboxes.push({entity : _, checked : false}); + }); + }, + error => this.handleError('System error retrieving entities', error)); + } + + public showModal():void { + this.modal.showModal(); + } + + public toggleCheckBoxes(event) { + this.entitiesCheckboxes.forEach(_ => _.checked = event.target.checked); + } + + public applyCheck(flag : boolean) { + console.info("applyCheck "+flag); + this.entitiesCheckboxes.forEach(_ => _.checked = flag); + } + + public getSelectedEntities() : string[] { + return this.entitiesCheckboxes.filter(entity => entity.checked == true).map(checkedEntity => checkedEntity.entity).map(res => res._id); + } + + private deleteEntitiesFromArray(ids : string[]) : void { + for(let id of ids) { + let i = this.entitiesCheckboxes.findIndex(_ => _.entity._id == id); + this.entitiesCheckboxes.splice(i, 1); + } + } + + public confirmDeleteEntity(id : string) { + this.deleteConfirmationModal.ids = [id]; + this.deleteConfirmationModal.showModal(); + } + + public confirmDeleteSelectedEntities() { + this.deleteConfirmationModal.ids = this.getSelectedEntities(); + this.deleteConfirmationModal.showModal(); + } + + public confirmedDeleteEntities(ids : string[]) { + this._helpContentService.deleteEntities(ids).subscribe( + _ => this.deleteEntitiesFromArray(ids), + error => this.handleError('System error deleting the selected entities', error) + ); + } + + public editEntity(i : number) { + let entity : Entity = this.entitiesCheckboxes[i].entity; + this.formGroup.patchValue(entity); + this.updateModal.showModal(); + } + + public entitySavedSuccessfully(entity: Entity) { + this.entitiesCheckboxes.push({entity : entity, checked : false}); + this.applyCheck(false); + } + + public entityUpdatedSuccessfully(entity : Entity) { + this.entitiesCheckboxes.find(checkItem => checkItem.entity._id==entity._id).entity = entity; + this.applyCheck(false); + } + + public filterBySearch(text : string) { + this.searchText = new RegExp(text,'i'); + this.applyFilter(); + } + + public applyFilter() { + this.entitiesCheckboxes = []; + this.entities.filter(item => this.filterEntities(item)).forEach( + _ => this.entitiesCheckboxes.push({entity: _, checked: false}) + ); + } + + public filterEntities(entity : Entity) : boolean { + let textFlag = this.searchText.toString() == '' || (entity.name).match(this.searchText) != null; + return textFlag; + } + + handleError(message: string, error) { + if(error == null) { + this.formComponent.reset(); + } + this.errorMessage = message + ' (Server responded: ' + error + ')'; + } + + + + public filterByCommunity(event: any) { + this.selectedCommunityId = event.target.value; + this.applyCommunityFilter(this.selectedCommunityId); + } + + public applyCommunityFilter(community_id: string) { + this.getEntities(community_id); + } + + public toggleEntity(status : boolean, id : string) { + this._helpContentService.toggleEntity(this.selectedCommunityId,id,status).subscribe( + () => { + let i = this.entitiesCheckboxes.findIndex(_ => _.entity._id == id); + this.entitiesCheckboxes[i].entity.isEnabled=status; + this.applyCheck(false); + }, + error => this.handleError('System error changing the status of the selected entity(-ies)', error) + ); + } + + } diff --git a/app/pages/modal-form.component.html b/app/pages/modal-form.component.html index da71c67..9b12991 100644 --- a/app/pages/modal-form.component.html +++ b/app/pages/modal-form.component.html @@ -19,4 +19,4 @@
-
\ No newline at end of file +
diff --git a/app/pages/modal-form.component.ts b/app/pages/modal-form.component.ts index 3c4b3cd..f735a57 100644 --- a/app/pages/modal-form.component.ts +++ b/app/pages/modal-form.component.ts @@ -9,6 +9,7 @@ import { Topic } from "../domain/topic"; import { Question } from "../domain/question"; import { HelpContentService } from "../services/help-content.service"; import { Page } from "../domain/page"; +import { Entity } from "../domain/entity"; @Component({ selector: 'modal-form', @@ -37,6 +38,9 @@ export class ModalFormComponent { @Input() public type : string = 'topic'; + @Input() + public selectedCommunityId: string; + public errorMessage : string = null; @Output() emmitObject: EventEmitter = new EventEmitter(); @@ -56,7 +60,7 @@ export class ModalFormComponent { this.emmitError.emit(null); this.errorMessage = null; } - + public saveCustom(obj : any) { if(!this.formGroup.valid) { this.errorMessage = "Please fill in all required fields marked with *" @@ -73,13 +77,31 @@ export class ModalFormComponent { error => this.emmitError.emit(error) ); } else if (this.type == 'page') { - this._helpService.savePage( obj).subscribe( - data => this.emmitObject.emit(data), - error => this.emmitError.emit(error) - ); + if(this.saveText == 'Update') { + this._helpService.updatePage( obj).subscribe( + data => this.emmitObject.emit(data), + error => this.emmitError.emit(error) + ); + } else if(this.saveText == 'Save') { + this._helpService.savePage( obj).subscribe( + data => this.emmitObject.emit(data), + error => this.emmitError.emit(error) + ); + } + } else if (this.type == 'entity') { + if(this.saveText == 'Update') { + this._helpService.updateEntity( obj).subscribe( + data => this.emmitObject.emit(data), + error => this.emmitError.emit(error) + ); + } else if(this.saveText == 'Save') { + this._helpService.saveEntity( obj).subscribe( + data => this.emmitObject.emit(data), + error => this.emmitError.emit(error) + ); + } } this.hideModal(); } } } - diff --git a/app/services/help-content.service.ts b/app/services/help-content.service.ts index 4a6b1d0..3f5552b 100644 --- a/app/services/help-content.service.ts +++ b/app/services/help-content.service.ts @@ -5,7 +5,10 @@ import { Injectable } from '@angular/core'; import { Http, Response, Headers, RequestOptions } from '@angular/http'; import { Observable } from 'rxjs/Rx'; import { Page } from "../domain/page"; -import {PageHelpContent} from "../domain/page-help-content"; +import { PageHelpContent } from "../domain/page-help-content"; +import { Community } from "../domain/community"; +import { Entity } from "../domain/entity"; + @Injectable() export class HelpContentService { @@ -29,14 +32,86 @@ export class HelpContentService { .catch(this.handleError); } + getCommunities() { + return this.http.get(this._helpContentUrl + 'community') + .map(res => > res.json()) + .catch(this.handleError); + } + + getCommunityPages(community_id: string) { + return this.http.get(this._helpContentUrl + 'community/'+community_id+'/pages') + .map(res => > res.json()) + .catch(this.handleError); + } + + getEntities() { + return this.http.get(this._helpContentUrl + 'entity') + .map(res => > res.json()) + .catch(this.handleError); + } + + getCommunityEntities(community_id: string) { + return this.http.get(this._helpContentUrl + 'community/'+community_id+'/entities') + .map(res => > res.json()) + .catch(this.handleError); + } + + + saveEntity(entity: Entity) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + HelpContentService.removeNulls(entity); + + return this.http.post(this._helpContentUrl + 'entity/save', JSON.stringify(entity), options) + .map(res => res.json()) + .catch(this.handleError); + } + + updateEntity(entity: Entity) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + HelpContentService.removeNulls(entity); + + return this.http.post(this._helpContentUrl + 'entity/update', JSON.stringify(entity), options) + .map(res => res.json()) + .catch(this.handleError); + } + + toggleEntity(selectedCommunityId: string, id : string,status : boolean) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + return this.http.post(this._helpContentUrl + 'community/'+selectedCommunityId+'/entity/toggle?status='+ status.toString()+'&entityId='+id.toString(), options) + .catch(this.handleError); + } + + + deleteEntities(ids : string[]) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + return this.http.post(this._helpContentUrl + 'entity/delete',JSON.stringify(ids), options) + .catch(this.handleError); + } + + + toggleEntityOfPage(pageId: string, entityId : string,status : boolean) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + return this.http.post(this._helpContentUrl + 'page/'+pageId+'/entity/toggle?status='+ status.toString()+'&entityId='+entityId.toString(), options) + .catch(this.handleError); + } + savePage(page: Page) { - console.log("savePage",page); let headers = new Headers({'Content-Type': 'application/json'}); let options = new RequestOptions({headers: headers}); HelpContentService.removeNulls(page); - return this.http.post(this._helpContentUrl + 'page', JSON.stringify(page), options) + return this.http.post(this._helpContentUrl + 'page/save', JSON.stringify(page), options) .map(res => res.json()) .catch(this.handleError); } @@ -47,11 +122,20 @@ export class HelpContentService { HelpContentService.removeNulls(page); - return this.http.put(this._helpContentUrl + 'page', JSON.stringify(page), options) + return this.http.post(this._helpContentUrl + 'page/update', JSON.stringify(page), options) .map(res => res.json()) .catch(this.handleError); } + togglePage(selectedCommunityId: string, id : string,status : boolean) { + let headers = new Headers({'Content-Type': 'application/json'}); + let options = new RequestOptions({headers: headers}); + + return this.http.post(this._helpContentUrl + 'community/'+selectedCommunityId+'/page/toggle?status='+ status.toString()+'&pageId='+id.toString(), options) + .catch(this.handleError); + } + + deletePages(ids : string[]) { let headers = new Headers({'Content-Type': 'application/json'}); let options = new RequestOptions({headers: headers}); @@ -66,6 +150,12 @@ export class HelpContentService { .catch(this.handleError); } + getCommunityPageHelpContents(community_id: string) { + return this.http.get(this._helpContentUrl + 'pagehelpcontent/community/'+community_id) + .map(res => > res.json()) + .catch(this.handleError); + } + getPageHelpContent(id : string) { return this.http.get(this._helpContentUrl + 'pagehelpcontent/' + id) .map(res => res.json()) @@ -108,7 +198,7 @@ export class HelpContentService { let options = new RequestOptions({headers: headers}); return this.http.post(this._helpContentUrl + 'pagehelpcontent/toggle?status='+ status.toString(), JSON.stringify(ids), options) - .map( res => res.json()) + //.map( res => res.json()) .catch(this.handleError); } @@ -118,5 +208,5 @@ export class HelpContentService { console.error(error); return Observable.throw(error.json().error || 'Server error'); } - -} \ No newline at end of file + +} diff --git a/imgs/OA CONNECT_A.png b/imgs/OA CONNECT_A.png new file mode 100644 index 0000000..08fd7cd Binary files /dev/null and b/imgs/OA CONNECT_A.png differ diff --git a/imgs/OA CONNECT_B.png b/imgs/OA CONNECT_B.png new file mode 100644 index 0000000..e3d95b8 Binary files /dev/null and b/imgs/OA CONNECT_B.png differ diff --git a/imgs/add-icon.png b/imgs/add-icon.png new file mode 100644 index 0000000..bd93323 Binary files /dev/null and b/imgs/add-icon.png differ diff --git a/imgs/delete-icon.png b/imgs/delete-icon.png new file mode 100644 index 0000000..b64cc5f Binary files /dev/null and b/imgs/delete-icon.png differ diff --git a/styles.css b/styles.css index 3094323..57bf7b2 100644 --- a/styles.css +++ b/styles.css @@ -8,8 +8,10 @@ } #sidebar-default { - background: #00b9b4 none repeat scroll 0 0; - border-right: 1px solid #18aba6; + /*background: #00b9b4 none repeat scroll 0 0;*/ + background: #00a0de none repeat scroll 0 0; + /*border-right: 1px solid #18aba6;*/ + border-right: 1px solid #008ec5; position: fixed; width: 260px; } @@ -22,12 +24,15 @@ } #sidebar-default .menu-section ul li a:hover, #sidebar-default .menu-section ul li a.toggled { - background: #18aba6 none repeat scroll 0 0; + /*background: #18aba6 none repeat scroll 0 0;*/ + background: #008ec5 none repeat scroll 0 0; } #sidebar-default .menu-section ul li a.active { /*background: #ff6600 none repeat scroll 0 0;*/ - background: #003f3c none repeat scroll 0 0; + /*background: #003f3c none repeat scroll 0 0;*/ + /*background: #05007A none repeat scroll 0 0;*/ + background: #e2d442 none repeat scroll 0 0; } #sidebar-default .menu-section h3 { @@ -120,8 +125,10 @@ /***********************************************/ .btn-primary { - background-color: #00b9b4; - border-color: #18aba6; + /*background-color: #00b9b4;*/ + background-color: #00a0de; + /*border-color: #18aba6;*/ + border-color: #008ec5; color: #fff; } @@ -741,7 +748,8 @@ a { #faqTopics #content .page-title, #faqQuestions #content .page-title, #pages #content .page-title, -#pageContents #content .page-title { +#pageContents #content .page-title, +#entities #content .entity-title { border-right: 1px solid #e6e6e6; bottom: 0; color: #7e7e7e; @@ -774,7 +782,8 @@ a { #faqQuestions #content .content-wrapper .contentPanel .alert, #harvestHistory #content .content-wrapper .contentPanel .alert, #pages #content .content-wrapper .contentPanel .alert, -#pageContents #content .content-wrapper .contentPanel .alert { +#pageContents #content .content-wrapper .contentPanel .alert, +#entities #content .content-wrapper .contentPanel .alert { margin-left: -10px; margin-right: -10px; } @@ -975,6 +984,14 @@ a { width: 360px; } +#entities #content form.search { + float: left; + margin-left: 150px; + position: relative; + top: -2px; + width: 360px; +} + #dataProviders #content form.search { float: left; margin-left: 220px; @@ -990,7 +1007,8 @@ a { #faqTopics #content form.search input[type="text"], #faqQuestions #content form.search input[type="text"], #pages #content form.search input[type="text"], -#pageContents #content form.search input[type="text"] { +#pageContents #content form.search input[type="text"], +#entities #content form.search input[type="text"]{ border: 0 none; border-radius: 3px; padding: 6px 15px 6px 37px; @@ -1010,7 +1028,8 @@ a { #faqTopics #content form.search input[type="submit"], #faqQuestions #content form.search input[type="submit"], #pages #content form.search input[type="submit"], -#pageContents #content form.search input[type="submit"] { +#pageContents #content form.search input[type="submit"], +#entities #content form.search input[type="submit"] { position: absolute; visibility: hidden; } @@ -1040,8 +1059,8 @@ a { #pageContents #content .content-wrapper .page-controls .filters .links, #harvestHistory #content .content-wrapper .page-controls .filters .links, #harvest #content .content-wrapper .page-controls .filters .links { - float: left; - margin-left: -5px; + /*float: left; + margin-left: -5px;*/ } #users #content .content-wrapper .page-controls .filters .links .filterLabel, @@ -1502,6 +1521,3 @@ table.dataTable td input.edit { content:"*"; color:red; } - - -