From a244301ef79878828506dc2931da2b4aaca00772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilmar=20T=C3=BCrk?= Date: Mon, 25 Nov 2024 21:21:11 +0200 Subject: [PATCH 1/5] Refactor topic-form component --- .../components/topic-form/topic-form.component.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/app/topic/components/topic-form/topic-form.component.ts b/src/app/topic/components/topic-form/topic-form.component.ts index f7e8624d2..add900b78 100644 --- a/src/app/topic/components/topic-form/topic-form.component.ts +++ b/src/app/topic/components/topic-form/topic-form.component.ts @@ -122,7 +122,7 @@ export class TopicFormComponent { groups$: Observable = of([]); groupsList = []; loadMembers$ = new BehaviorSubject(undefined); - members$: Observable = of([]); + members$: Observable = of([]); loadInvite$ = new BehaviorSubject(undefined); invites$: Observable = of([]); topicGroups = []; @@ -231,7 +231,7 @@ export class TopicFormComponent { return fragment } ), tap((fragment) => { - if (fragment === 'settings' && !this.TopicService.canDelete(this.topic)) { + if (fragment === 'settings' && !this.TopicService.canDelete(this.topic)) { const infoDialog = this.dialog.open(TopicSettingsDisabledDialogComponent); infoDialog.afterClosed().subscribe(() => { this.selectTab('info') @@ -314,11 +314,7 @@ export class TopicFormComponent { isNextDisabled(tabSelected: string | void) { - if (tabSelected === 'preview' && !this.TopicService.canDelete(this.topic)) { - return true; - } else if (!this.topic.title || !this.topic.description) { - return true; - } else if (tabSelected === 'discussion' && !this.discussion.question) { + if ((tabSelected === 'preview' && !this.TopicService.canDelete(this.topic)) || !this.topic.title || !this.topic.description || (tabSelected === 'discussion' && !this.discussion.question)) { return true; } @@ -492,7 +488,7 @@ export class TopicFormComponent { saveAsDraft() { if (this.topic.status === this.TopicService.STATUSES.draft) { - const updateTopic = Object.assign({}, this.topic); + const updateTopic = { ...this.topic }; if (!updateTopic.intro?.length) { updateTopic.intro = null; } From a2dd97d43bc6b2d7dd81580864486854dc610ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilmar=20T=C3=BCrk?= Date: Mon, 25 Nov 2024 22:56:42 +0200 Subject: [PATCH 2/5] FIX https://github.com/citizenos/citizenos-fe/issues/1684 --- .../edit-idea/edit-idea.component.html | 4 +- .../ideation-create.component.ts | 26 +++++--- src/app/services/topic.service.ts | 12 ++-- .../topic-edit-disabled-dialog.component.html | 1 - ...pic-edit-disabled-dialog.component.spec.ts | 4 +- .../topic-form/topic-form.component.ts | 38 +++++++++--- .../topic-settings-locked.component.html | 58 +++++++++++++++++ .../topic-settings-locked.component.scss | 29 +++++++++ .../topic-settings-locked.component.spec.ts | 38 ++++++++++++ .../topic-settings-locked.component.ts | 10 +++ src/app/topic/topic.component.html | 12 ++-- src/app/topic/topic.component.ts | 62 +++++++++---------- src/app/topic/topic.module.ts | 6 +- .../vote-create/vote-create.component.ts | 27 ++++---- src/assets/i18n/en.json | 7 +++ 15 files changed, 251 insertions(+), 83 deletions(-) create mode 100644 src/app/topic/components/topic-settings-locked/topic-settings-locked.component.html create mode 100644 src/app/topic/components/topic-settings-locked/topic-settings-locked.component.scss create mode 100644 src/app/topic/components/topic-settings-locked/topic-settings-locked.component.spec.ts create mode 100644 src/app/topic/components/topic-settings-locked/topic-settings-locked.component.ts diff --git a/src/app/ideation/components/edit-idea/edit-idea.component.html b/src/app/ideation/components/edit-idea/edit-idea.component.html index 82eb3df41..a6b8fbeaf 100644 --- a/src/app/ideation/components/edit-idea/edit-idea.component.html +++ b/src/app/ideation/components/edit-idea/edit-idea.component.html @@ -50,7 +50,7 @@
-
diff --git a/src/app/topic/components/topic-edit-disabled-dialog/topic-edit-disabled-dialog.component.spec.ts b/src/app/topic/components/topic-edit-disabled-dialog/topic-edit-disabled-dialog.component.spec.ts index b792e3971..622675267 100644 --- a/src/app/topic/components/topic-edit-disabled-dialog/topic-edit-disabled-dialog.component.spec.ts +++ b/src/app/topic/components/topic-edit-disabled-dialog/topic-edit-disabled-dialog.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TopicEditDisabledDialogComponent } from './topic-edit-disabled-dialog.component'; +import { TranslateModule, TranslatePipe } from '@ngx-translate/core'; describe('TopicEditDisabledDialogComponent', () => { let component: TopicEditDisabledDialogComponent; @@ -8,7 +9,8 @@ describe('TopicEditDisabledDialogComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - declarations: [TopicEditDisabledDialogComponent] + declarations: [TopicEditDisabledDialogComponent], + imports: [TranslateModule.forRoot(), TranslatePipe] }); fixture = TestBed.createComponent(TopicEditDisabledDialogComponent); component = fixture.componentInstance; diff --git a/src/app/topic/components/topic-form/topic-form.component.ts b/src/app/topic/components/topic-form/topic-form.component.ts index add900b78..6750e7d51 100644 --- a/src/app/topic/components/topic-form/topic-form.component.ts +++ b/src/app/topic/components/topic-form/topic-form.component.ts @@ -25,6 +25,8 @@ import { Attachment } from 'src/app/interfaces/attachment'; import { TopicAttachmentService } from '@services/topic-attachment.service'; import { GroupMemberTopicService } from '@services/group-member-topic.service'; import { TopicDiscussionService } from '@services/topic-discussion.service'; +import { TopicEditDisabledDialogComponent } from '../topic-edit-disabled-dialog/topic-edit-disabled-dialog.component'; +import { TopicSettingsLockedComponent } from '../topic-settings-locked/topic-settings-locked.component'; @Component({ selector: 'topic-form', @@ -80,11 +82,11 @@ export class TopicFormComponent { } else { const contentChilds = content.nativeElement.children[2]?.children; let h = 0; - for (let i = 0; i < contentChilds.length; i++) { - h += contentChilds[i].offsetHeight; + for (const child of contentChilds) { + h += child.offsetHeight; if (h >= 320) { this.readMoreButton.next(true); - i = contentChilds.length; + break; } } } @@ -231,7 +233,26 @@ export class TopicFormComponent { return fragment } ), tap((fragment) => { - if (fragment === 'settings' && !this.TopicService.canDelete(this.topic)) { + if (fragment === 'discussion' && !this.TopicService.canEditDescription(this.topic)) { + const infoDialog = dialog.open(TopicSettingsLockedComponent); + infoDialog.afterClosed().subscribe(() => { + if (this.TopicService.canDelete(this.topic)) { + this.selectTab('settings') + } else { + this.selectTab('preview') + } + }); + } + else if (fragment === 'info' && !this.TopicService.canEditDescription(this.topic)) { + const infoDialog = dialog.open(TopicEditDisabledDialogComponent); + infoDialog.afterClosed().subscribe(() => { + if (this.TopicService.canDelete(this.topic)) { + this.selectTab('settings') + } else { + this.selectTab('preview') + } + }); + } else if (fragment === 'settings' && !this.TopicService.canDelete(this.topic)) { const infoDialog = this.dialog.open(TopicSettingsDisabledDialogComponent); infoDialog.afterClosed().subscribe(() => { this.selectTab('info') @@ -541,9 +562,8 @@ export class TopicFormComponent { publish() { this.titleInput?.nativeElement?.parentNode.parentNode.classList.remove('error'); - const isDraft = (this.topic.status === this.TopicService.STATUSES.draft); this.topic.status = this.TopicService.STATUSES.inProgress; - const updateTopic = Object.assign({}, this.topic); + const updateTopic = { ...this.topic }; if (!updateTopic.intro?.length) { updateTopic.intro = null; } @@ -596,7 +616,7 @@ export class TopicFormComponent { } createDiscussion(updateTopicStatus?: boolean) { - const createDiscussion: any = Object.assign({ topicId: this.topic.id, discussionId: this.discussion.id }, this.discussion); + const createDiscussion: any = { topicId: this.topic.id, discussionId: this.discussion.id, ...this.discussion }; this.TopicDiscussionService.save(createDiscussion) .pipe(take(1)) .subscribe({ @@ -605,7 +625,7 @@ export class TopicFormComponent { this.discussion = discussion; if (updateTopicStatus) { const isDraft = (this.topic.status === this.TopicService.STATUSES.draft); - const updateTopic = Object.assign({}, this.topic); + const updateTopic = { ...this.topic }; updateTopic.status = this.TopicService.STATUSES.inProgress; this.TopicService.patch(updateTopic).pipe(take(1)).subscribe({ next: (res) => { @@ -639,7 +659,7 @@ export class TopicFormComponent { updateDiscussion(updateTopicStatus?: boolean) { - const updateDiscussion = Object.assign({ topicId: this.topic.id, discussionId: this.discussion.id }, this.discussion); + const updateDiscussion = { topicId: this.topic.id, discussionId: this.discussion.id , ...this.discussion}; return this.TopicDiscussionService.update(updateDiscussion).pipe(take(1)).subscribe({ next: () => { if (updateTopicStatus) { diff --git a/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.html b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.html new file mode 100644 index 000000000..003e04393 --- /dev/null +++ b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.html @@ -0,0 +1,58 @@ +
+
+
+ +
+
+
+ +
+
+
+ + + + + + +
+
+ +
+
diff --git a/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.scss b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.scss new file mode 100644 index 000000000..e0afe036c --- /dev/null +++ b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.scss @@ -0,0 +1,29 @@ +.dialog { + max-width: 560px; + + .header_with_icon { + gap: 16px; + padding-bottom: 24px; + } + + .dialog_content { + gap: 24px; + } + + .dialog_info { + background-color: var(--color-argument-info-light); + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 20px; + padding: 16px; + gap: 16px; + + .bold { + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: 16px; + } + } +} diff --git a/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.spec.ts b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.spec.ts new file mode 100644 index 000000000..daf2db474 --- /dev/null +++ b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.spec.ts @@ -0,0 +1,38 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TopicSettingsLockedComponent } from './topic-settings-locked.component'; + +describe('TopicSettingsLockedComponent', () => { + let component: TopicSettingsLockedComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [TopicSettingsLockedComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TopicSettingsLockedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should have the correct selector', () => { + const compiled = fixture.nativeElement; + expect(compiled.querySelector('app-topic-settings-locked')).toBeTruthy(); + }); + + it('should have the correct template URL', () => { + const metadata = Reflect.getMetadata('annotations', TopicSettingsLockedComponent)[0]; + expect(metadata.templateUrl).toBe('./topic-settings-locked.component.html'); + }); + + it('should have the correct style URL', () => { + const metadata = Reflect.getMetadata('annotations', TopicSettingsLockedComponent)[0]; + expect(metadata.styleUrls).toContain('./topic-settings-locked.component.scss'); + }); +}); diff --git a/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.ts b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.ts new file mode 100644 index 000000000..ba55200b7 --- /dev/null +++ b/src/app/topic/components/topic-settings-locked/topic-settings-locked.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-topic-settings-locked', + templateUrl: './topic-settings-locked.component.html', + styleUrl: './topic-settings-locked.component.scss' +}) +export class TopicSettingsLockedComponent { + +} diff --git a/src/app/topic/topic.component.html b/src/app/topic/topic.component.html index a18eb4537..254d1607e 100644 --- a/src/app/topic/topic.component.html +++ b/src/app/topic/topic.component.html @@ -152,7 +152,7 @@ + *ngIf="(auth.loggedIn$ | async) && topic.ideationId && TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.ideation, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)">
+ *ngIf="(auth.loggedIn$ | async) && topic.voteId && (TopicService.canDelete(topic) || (TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.voting, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)))">
+ *ngIf="(auth.loggedIn$ | async) && topic.ideationId && TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.ideation, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)">
+ *ngIf="(auth.loggedIn$ | async) && topic.voteId && TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.voting, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)">
+ *ngIf="(auth.loggedIn$ | async) && topic.ideationId && TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.ideation, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)">
+ *ngIf="(auth.loggedIn$ | async) && topic.voteId && TopicService.canEdit(topic) && ([TopicService.STATUSES.draft, TopicService.STATUSES.voting, TopicService.STATUSES.followUp].indexOf(topic.status) > -1)">
@@ -229,9 +219,10 @@
+ (click)="TopicArgumentService.setParam('orderBy', null)" (keypress)="TopicArgumentService.setParam('orderBy', null)">
+ (click)="TopicArgumentService.setParam('orderBy', orderOption)" + (keypress)="TopicArgumentService.setParam('orderBy', orderOption)"> {{'COMPONENTS.TOPIC_ARGUMENTS.FILTER_ARGUMENT_ORDER_BY_' + orderOption | uppercase | translate}}
@@ -248,7 +239,7 @@ [page]="(TopicArgumentService.page$ | async) || 0">
-
+
diff --git a/src/app/topic/components/topic-arguments/topic-arguments.component.ts b/src/app/topic/components/topic-arguments/topic-arguments.component.ts index 662bb3c4f..9571716ca 100644 --- a/src/app/topic/components/topic-arguments/topic-arguments.component.ts +++ b/src/app/topic/components/topic-arguments/topic-arguments.component.ts @@ -1,7 +1,7 @@ import { TopicDiscussionService } from '@services/topic-discussion.service'; import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation, Input, Inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { tap, of, map, take, switchMap, Observable } from 'rxjs'; +import { tap, of, map, take, switchMap } from 'rxjs'; import { Topic } from 'src/app/interfaces/topic'; import { Argument } from 'src/app/interfaces/argument'; import { AuthService } from '@services/auth.service'; @@ -36,14 +36,14 @@ export class TopicArgumentsComponent implements OnInit { focusArgumentSubject = false; filtersSelected = false; constructor( - private Auth: AuthService, + private readonly Auth: AuthService, public TopicService: TopicService, - private dialog: DialogService, - @Inject(ActivatedRoute) private route: ActivatedRoute, + private readonly dialog: DialogService, + @Inject(ActivatedRoute) private readonly route: ActivatedRoute, public translate: TranslateService, - private app: AppService, - private Notification: NotificationService, - private TopicDiscussionService: TopicDiscussionService, + private readonly app: AppService, + private readonly Notification: NotificationService, + private readonly TopicDiscussionService: TopicDiscussionService, public TopicArgumentService: TopicArgumentService) { this.TopicArgumentService.setParam('limit', 5); @@ -54,7 +54,6 @@ export class TopicArgumentsComponent implements OnInit { map((res: any[]) => { let results = res.concat([]); const argArray = []; - let children = {}; const countTree = (parentNode: any, currentNode: any) => { argArray.push(currentNode); if (currentNode.replies.rows.length > 0) { @@ -63,7 +62,7 @@ export class TopicArgumentsComponent implements OnInit { countTree(reply, reply); } else { countTree(parentNode, reply); - const replyClone = Object.assign({}, reply); + const replyClone = { ...reply }; replyClone.replies = []; if (!parentNode.children) parentNode.children = []; parentNode.children.push(replyClone); @@ -121,6 +120,7 @@ export class TopicArgumentsComponent implements OnInit { filterArguments() { this.filtersSelected = true; const types = this.argumentTypes.filter((item: any) => item.checked).map(item => item.type); + this.TopicArgumentService.loadPage(1); this.TopicArgumentService.setParam('types', types); } getArgumentPercentage(count: number) { @@ -169,7 +169,7 @@ export class TopicArgumentsComponent implements OnInit { argumentIdWithVersion = argumentIdWithVersion + this.TopicArgumentService.ARGUMENT_VERSION_SEPARATOR + '0'; } const argumentIdAndVersionRegex = new RegExp('^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4{1}[a-fA-F0-9]{3}-[89abAB]{1}[a-fA-F0-9]{3}-[a-fA-F0-9]{12})' + this.TopicArgumentService.ARGUMENT_VERSION_SEPARATOR + '([0-9]+)$'); // SRC: https://gist.github.com/bugventure/f71337e3927c34132b9a#gistcomment-2238943 - const argumentIdWithVersionSplit = argumentIdWithVersion.match(argumentIdAndVersionRegex); + const argumentIdWithVersionSplit = RegExp(argumentIdAndVersionRegex).exec(argumentIdWithVersion); if (!argumentIdWithVersionSplit) { console.error('Invalid input for _parseCommentIdAndVersion. Provided commentId does not look like UUIDv4 with version appended', argumentIdWithVersion); @@ -206,8 +206,7 @@ export class TopicArgumentsComponent implements OnInit { this.scrollTo(commentElement); commentElement.classList.add('highlight'); setTimeout(() => { - if (commentElement) - commentElement.classList.remove('highlight'); + commentElement.classList.remove('highlight'); }, 2000); } else { // The referenced comment was NOT found on the page displayed. @@ -219,7 +218,7 @@ export class TopicArgumentsComponent implements OnInit { const argumentParameterValues = this._parseArgumentIdAndVersion(argumentIdWithVersion); const argumentId = argumentParameterValues.id; - const argumentVersion = argumentParameterValues.version || 0; + // const argumentVersion = argumentParameterValues.version ?? 0; if (!argumentId) { return console.error('this.goToArgument', 'No argumentId and/or version provided, nothing to do here', argumentIdWithVersion); } @@ -343,7 +342,7 @@ export class TopicArgumentsComponent implements OnInit { } saveDiscussion(discussion: Discussion) { - const saveDiscussion: any = Object.assign({ topicId: this.topic.id, discussionId: discussion.id, deadline: discussion.deadline }); + const saveDiscussion: any = { topicId: this.topic.id, discussionId: discussion.id, deadline: discussion.deadline }; this.TopicDiscussionService.update(saveDiscussion) .pipe(take(1)) .subscribe({ From c825bacf047af7c3ff208dbfc64ebc4d4f6b86f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilmar=20T=C3=BCrk?= Date: Tue, 26 Nov 2024 22:49:11 +0200 Subject: [PATCH 5/5] FIX https://github.com/citizenos/citizenos-fe/issues/1691 --- .../argument-edits.component.html | 2 +- .../argument-edits/argument-edits.component.ts | 17 +++++++++-------- .../components/argument/argument.component.html | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/app/topic/components/argument-edits/argument-edits.component.html b/src/app/topic/components/argument-edits/argument-edits.component.html index c97ffe626..24ce6a9fa 100644 --- a/src/app/topic/components/argument-edits/argument-edits.component.html +++ b/src/app/topic/components/argument-edits/argument-edits.component.html @@ -1,7 +1,7 @@
(); - constructor(private TopicArgumentService: TopicArgumentService, private Notification: NotificationService, private Location: LocationService, private Translate: TranslateService) { } - - ngOnInit(): void { - } - + constructor(private readonly Notification: NotificationService, private readonly Location: LocationService, private readonly Translate: TranslateService) { } copyArgumentLink(event: MouseEvent, version:string) { const id = this.argument.id + '_v' + version; @@ -37,4 +34,8 @@ export class ArgumentEditComponent implements OnInit { this.Notification.inline(this.Translate.instant('VIEWS.TOPICS_TOPICID.ARGUMENT_LNK_COPIED'), event.pageX, event.pageY - 35); }; + + hideEdits() { + this.showEditsChange.emit(false); + } } diff --git a/src/app/topic/components/argument/argument.component.html b/src/app/topic/components/argument/argument.component.html index d366dfc6f..571e627f9 100644 --- a/src/app/topic/components/argument/argument.component.html +++ b/src/app/topic/components/argument/argument.component.html @@ -69,7 +69,7 @@ -