From 059c11afa01f8b127444f714c222ca53158bc41a Mon Sep 17 00:00:00 2001 From: luisa-beerboom <101706784+luisa-beerboom@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:08:50 +0100 Subject: [PATCH] Implement datetimepicker for motion workflow (#3298) --- .../motion-manage-timestamp.component.html | 53 ++++++++ .../motion-manage-timestamp.component.scss | 0 .../motion-manage-timestamp.component.spec.ts | 21 +++ .../motion-manage-timestamp.component.ts | 120 ++++++++++++++++++ .../motion-meta-data.component.html | 9 +- .../motion-detail/motion-detail.module.ts | 10 +- client/src/meta | 2 +- 7 files changed, 209 insertions(+), 6 deletions(-) create mode 100644 client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.html create mode 100644 client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.scss create mode 100644 client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.spec.ts create mode 100644 client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.ts diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.html new file mode 100644 index 0000000000..a3d18c1b4f --- /dev/null +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.html @@ -0,0 +1,53 @@ +

+ {{ title }} + + +

+ +
+
{{ motion[field] | localizedDate }}
+
+ +
+
+ + + +
+ + + access_time + + +
+ +
+
+ +

+ + +

+
diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.scss b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.spec.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.spec.ts new file mode 100644 index 0000000000..3acd06ddb7 --- /dev/null +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MotionManageTimestampComponent } from './motion-manage-timestamp.component'; + +xdescribe(`MotionManageTimestampComponent`, () => { + let component: MotionManageTimestampComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [MotionManageTimestampComponent] + }); + fixture = TestBed.createComponent(MotionManageTimestampComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it(`should create`, () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.ts new file mode 100644 index 0000000000..228a82150c --- /dev/null +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-manage-timestamp/motion-manage-timestamp.component.ts @@ -0,0 +1,120 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { fromUnixTime, getHours, getMinutes, isDate } from 'date-fns'; +import { KeyOfType } from 'src/app/infrastructure/utils/keyof-type'; +import { BaseUiComponent } from 'src/app/ui/base/base-ui-component'; + +import { MotionControllerService } from '../../../../services/common/motion-controller.service'; +import { MotionPermissionService } from '../../../../services/common/motion-permission.service'; +import { ViewMotion } from '../../../../view-models'; + +@Component({ + selector: `os-motion-manage-timestamp`, + templateUrl: `./motion-manage-timestamp.component.html`, + styleUrls: [`./motion-manage-timestamp.component.scss`], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class MotionManageTimestampComponent extends BaseUiComponent { + public get motion(): ViewMotion { + return this._motion; + } + + @Input() + public set motion(value: ViewMotion) { + this._motion = value; + } + + @Input() + public field: KeyOfType; + + @Input() + public title: string; + + public form: UntypedFormGroup; + + /** + * Saves if the users edits the note. + */ + public set isEditMode(value: boolean) { + this._editMode = value; + } + + public get isEditMode(): boolean { + return this._editMode; + } + + private _editMode = false; + + private _motion!: ViewMotion; + + public constructor( + public perms: MotionPermissionService, + private motionController: MotionControllerService, + private fb: UntypedFormBuilder + ) { + super(); + + this.form = this.fb.group({ + date: [``], + time: [``] + }); + + this.form.get(`date`).valueChanges.subscribe(currDate => { + if (isDate(currDate) !== !!this.form.get(`time`).value) { + this.form.get(`time`).setValue(isDate(currDate) ? `00:00` : ``); + } + }); + this.form.get(`time`).valueChanges.subscribe(currTime => { + if (!!currTime !== isDate(this.form.get(`date`).value)) { + this.form.get(`date`).setValue(!!currTime ? new Date() : null); + } + }); + } + + public async onSave(): Promise { + const date: { date: Date | null; time: string } = this.form.value; + const [hours, minutes, ..._] = date.time.split(`:`); + if (date.date) { + date.date.setHours(+hours, +minutes); + } + await this.motionController + .update({ [this.field]: date.date ? Math.floor(date.date.getTime() / 1000) : null }, this.motion) + .resolve(); + this.isEditMode = false; + } + + /** + * Close the edit view. + */ + public onCancel(): void { + this.isEditMode = false; + } + + /** + * Enter the edit mode and reset the form and the data. + */ + public onEdit(): void { + const timestamp = this.motion[this.field]; + const date = timestamp + ? this.getTimes(timestamp) + : { + date: ``, + time: `` + }; + this.form.patchValue(date); + this.isEditMode = true; + } + + public getTimes(timestamp: number): { date: Date; time: string } { + const date = fromUnixTime(timestamp); + const time = getHours(date) + `:` + getMinutes(date); + return { date, time }; + } + + public clearForm(): void { + this.form.patchValue({ + date: ``, + time: `` + }); + } +} diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-meta-data/motion-meta-data.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-meta-data/motion-meta-data.component.html index 4cbc216ee8..943adf600e 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-meta-data/motion-meta-data.component.html +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/components/motion-meta-data/motion-meta-data.component.html @@ -254,10 +254,11 @@

-
-

{{ 'Submission date' | translate }}

-
{{ motion.workflow_timestamp | localizedDate }}
-
+
diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/motion-detail.module.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/motion-detail.module.ts index c59c9bf398..6561913766 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/motion-detail.module.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/motion-detail.module.ts @@ -18,6 +18,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; +import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker'; import { ChipSelectModule } from 'src/app/site/modules/chip-select/chip-select.module'; import { OpenSlidesTranslationModule } from 'src/app/site/modules/translations'; import { MeetingsComponentCollectorModule } from 'src/app/site/pages/meetings/modules/meetings-component-collector'; @@ -25,9 +26,11 @@ import { DirectivesModule } from 'src/app/ui/directives'; import { ActionCardModule } from 'src/app/ui/modules/action-card'; import { ChoiceDialogModule } from 'src/app/ui/modules/choice-dialog'; import { CommaSeparatedListingModule } from 'src/app/ui/modules/comma-separated-listing'; +import { DatepickerModule } from 'src/app/ui/modules/datepicker'; import { EditorModule } from 'src/app/ui/modules/editor'; import { HeadBarModule } from 'src/app/ui/modules/head-bar'; import { IconContainerModule } from 'src/app/ui/modules/icon-container'; +import { OpenSlidesDateAdapterModule } from 'src/app/ui/modules/openslides-date-adapter/openslides-date-adapter.module'; import { SearchSelectorModule } from 'src/app/ui/modules/search-selector'; import { SortingModule } from 'src/app/ui/modules/sorting'; import { PipesModule } from 'src/app/ui/pipes/pipes.module'; @@ -55,6 +58,7 @@ import { MotionFinalVersionComponent } from './components/motion-final-version/m import { MotionHighlightFormComponent } from './components/motion-highlight-form/motion-highlight-form.component'; import { MotionManageMotionMeetingUsersComponent } from './components/motion-manage-motion-meeting-users/motion-manage-motion-meeting-users.component'; import { MotionManagePollsComponent } from './components/motion-manage-polls/motion-manage-polls.component'; +import { MotionManageTimestampComponent } from './components/motion-manage-timestamp/motion-manage-timestamp.component'; import { MotionManageTitleComponent } from './components/motion-manage-title/motion-manage-title.component'; import { MotionMetaDataComponent } from './components/motion-meta-data/motion-meta-data.component'; import { MotionParagraphbasedAmendmentComponent } from './components/motion-paragraphbased-amendment/motion-paragraphbased-amendment.component'; @@ -86,7 +90,8 @@ import { MotionDetailServiceModule } from './services/motion-detail-service.modu MotionPersonalNoteComponent, MotionCommentComponent, MotionFinalVersionComponent, - ParagraphBasedAmendmentComponent + ParagraphBasedAmendmentComponent, + MotionManageTimestampComponent ], imports: [ CommonModule, @@ -129,6 +134,9 @@ import { MotionDetailServiceModule } from './services/motion-detail-service.modu MatInputModule, MatProgressBarModule, ParticipantSearchSelectorModule, + OpenSlidesDateAdapterModule, + NgxMaterialTimepickerModule, + DatepickerModule, // Detail view ScrollingModule, diff --git a/client/src/meta b/client/src/meta index 3aa7942280..d346289040 160000 --- a/client/src/meta +++ b/client/src/meta @@ -1 +1 @@ -Subproject commit 3aa7942280f41c5794c728545061d36f88a22b5d +Subproject commit d3462890400f62c815ebd4607c542de2522d10fa