Project due date

This commit is contained in:
Adina Țeudan 2020-12-11 19:46:49 +02:00
parent e32003c13e
commit 19f75d78fe
7 changed files with 220 additions and 119 deletions

View File

@ -17,6 +17,7 @@ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { MatMenuModule } from '@angular/material/menu';
import { languageInitializer } from './i18n/language.initializer';
import { LanguageService } from './i18n/language.service';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { MatIconModule } from '@angular/material/icon';
import { IconsModule } from './icons/icons.module';
import { AddEditProjectDialogComponent } from './dialogs/add-edit-project-dialog/add-edit-project-dialog.component';
@ -55,7 +56,7 @@ import { RedRoleGuard } from './auth/red-role.guard';
import { MatListModule } from '@angular/material/list';
import { AssignOwnerDialogComponent } from './dialogs/assign-owner-dialog/assign-owner-dialog.component';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatNativeDateModule } from '@angular/material/core';
import { MatInputModule } from '@angular/material/input';
import { HumanizePipe } from './utils/humanize.pipe';
import { CommentsComponent } from './components/comments/comments.component';
@ -315,6 +316,15 @@ const matImports = [
multi: true,
useFactory: languageInitializer,
deps: [LanguageService]
},
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{
provide: MAT_DATE_FORMATS,
useValue: {
display: {
dateInput: 'DD/MM/YY'
}
}
}
],
bootstrap: [AppComponent]

View File

@ -27,17 +27,24 @@
<textarea formControlName="description" name="description" type="text" rows="5"></textarea>
</div>
<mat-form-field>
<mat-label>{{ 'project-listing.add-edit-dialog.form.due-date' | translate }}</mat-label>
<input matInput [matDatepicker]="picker" formControlName="dueDate" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<div class="due-date">
<mat-checkbox [checked]="hasDueDate" (change)="hasDueDate = !hasDueDate" class="filter-menu-checkbox" color="primary">
{{ 'project-listing.add-edit-dialog.form.due-date' | translate }}
</mat-checkbox>
<div class="red-input-group datepicker-wrapper" *ngIf="hasDueDate">
<input placeholder="dd/mm/yy" [matDatepicker]="picker" formControlName="dueDate" />
<mat-datepicker-toggle matSuffix [for]="picker">
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
</mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</div>
</div>
</div>
<div class="dialog-actions">
<button
[disabled]="projectForm.invalid"
[disabled]="disabled || !changed"
color="primary"
mat-flat-button
translate="project-listing.add-edit-dialog.actions.save"
@ -45,7 +52,7 @@
></button>
<button
[disabled]="projectForm.invalid"
[disabled]="disabled || !changed"
(click)="saveProjectAndAddMembers()"
*ngIf="!project?.projectId"
color="primary"

View File

@ -0,0 +1,14 @@
@import '../../../assets/styles/red-variables';
.due-date {
margin-top: 16px;
min-height: 34px;
display: flex;
flex-direction: row;
align-items: center;
mat-checkbox {
width: fit-content;
margin-right: 16px;
}
}

View File

@ -1,31 +1,61 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Project } from '@redaction/red-ui-http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '../../state/app-state.service';
import { ProjectWrapper } from '../../state/model/project.wrapper';
import * as moment from 'moment';
@Component({
selector: 'redaction-add-edit-project-dialog',
templateUrl: './add-edit-project-dialog.component.html',
styleUrls: ['./add-edit-project-dialog.component.scss']
})
export class AddEditProjectDialogComponent implements OnInit {
projectForm: FormGroup;
export class AddEditProjectDialogComponent {
public projectForm: FormGroup;
public hasDueDate = true;
constructor(
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<AddEditProjectDialogComponent>,
@Inject(MAT_DIALOG_DATA) public project: ProjectWrapper
) {}
ngOnInit(): void {
) {
this.projectForm = this._formBuilder.group({
projectName: [this.project?.projectName, Validators.required],
description: [this.project?.description],
dueDate: [this.project?.dueDate]
});
this.hasDueDate = !!this.project?.dueDate;
}
public get changed() {
if (!this.project) {
return true;
}
for (const key of Object.keys(this.projectForm.getRawValue())) {
if (key === 'dueDate') {
if (this.hasDueDate !== !!this.project.dueDate) {
return true;
}
if (this.hasDueDate && !moment(this.project.dueDate).isSame(moment(this.projectForm.get(key).value))) {
return true;
}
} else if (this.project[key] !== this.projectForm.get(key).value) {
return true;
}
}
return false;
}
public get disabled() {
if (this.hasDueDate && this.projectForm.get('dueDate').value === null) {
return true;
}
return this.projectForm.invalid;
}
async saveProject() {
@ -47,7 +77,7 @@ export class AddEditProjectDialogComponent implements OnInit {
return {
projectName: this.projectForm.get('projectName').value,
description: this.projectForm.get('description').value,
dueDate: this.projectForm.get('dueDate').value
dueDate: this.hasDueDate ? this.projectForm.get('dueDate').value : undefined
};
}

View File

@ -123,4 +123,36 @@
content: ' *';
color: $primary;
}
&.datepicker-wrapper {
position: relative;
display: flex;
margin-top: 0;
width: 120px;
.mat-datepicker-input {
margin-top: 0;
}
.mat-datepicker-toggle {
position: absolute;
right: 0;
color: $accent;
&.mat-datepicker-toggle-active {
color: $primary;
}
.mat-icon-button {
width: 34px;
height: 34px;
line-height: 34px;
}
mat-icon {
width: 14px;
height: 17px;
}
}
}
}

View File

@ -1,106 +1,107 @@
{
"name": "redaction",
"version": "0.0.230",
"private": true,
"license": "MIT",
"scripts": {
"affected": "nx affected",
"affected:apps": "nx affected:apps",
"affected:build": "nx affected:build",
"affected:dep-graph": "nx affected:dep-graph",
"affected:e2e": "nx affected:e2e",
"affected:libs": "nx affected:libs",
"affected:lint": "nx affected:lint",
"affected:test": "nx affected:test",
"build": "nx build",
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
"dep-graph": "nx dep-graph",
"e2e": "nx e2e",
"format": "nx format:write",
"format:check": "nx format:check",
"format:write": "nx format:write",
"help": "nx help",
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
"lint": "nx workspace-lint && nx lint",
"nx": "nx",
"start": "nx serve",
"test": "nx test",
"update": "nx migrate latest",
"workspace-schematic": "nx workspace-schematic"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
"name": "redaction",
"version": "0.0.230",
"private": true,
"license": "MIT",
"scripts": {
"affected": "nx affected",
"affected:apps": "nx affected:apps",
"affected:build": "nx affected:build",
"affected:dep-graph": "nx affected:dep-graph",
"affected:e2e": "nx affected:e2e",
"affected:libs": "nx affected:libs",
"affected:lint": "nx affected:lint",
"affected:test": "nx affected:test",
"build": "nx build",
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
"dep-graph": "nx dep-graph",
"e2e": "nx e2e",
"format": "nx format:write",
"format:check": "nx format:check",
"format:write": "nx format:write",
"help": "nx help",
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
"lint": "nx workspace-lint && nx lint",
"nx": "nx",
"start": "nx serve",
"test": "nx test",
"update": "nx migrate latest",
"workspace-schematic": "nx workspace-schematic"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
}
},
"dependencies": {
"@angular/animations": "~11.0.1",
"@angular/cdk": "~11.0.1",
"@angular/common": "~11.0.1",
"@angular/compiler": "~11.0.1",
"@angular/core": "~11.0.1",
"@angular/forms": "~11.0.1",
"@angular/material": "~11.0.1",
"@angular/material-moment-adapter": "^11.0.2",
"@angular/platform-browser": "~11.0.1",
"@angular/platform-browser-dynamic": "~11.0.1",
"@angular/router": "~11.0.1",
"@angular/service-worker": "~11.0.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@nrwl/angular": "^10.2.0",
"@pdftron/webviewer": "^7.0.1",
"file-saver": "^2.0.2",
"jwt-decode": "^3.0.0",
"keycloak-angular": "^8.0.1",
"keycloak-js": "10.0.2",
"lint-staged": "^10.5.0",
"ng2-ace-editor": "^0.3.9",
"ng2-file-upload": "^1.4.0",
"ngp-sort-pipe": "^0.0.4",
"ngx-color-picker": "^10.1.0",
"ngx-dropzone": "^2.2.2",
"ngx-toastr": "^13.0.0",
"rxjs": "~6.6.0",
"scroll-into-view-if-needed": "^2.2.26",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.2",
"@angular-devkit/build-ng-packagr": "~0.1002.0",
"@angular/cli": "~11.0.2",
"@angular/compiler": "~11.0.1",
"@angular/compiler-cli": "~11.0.1",
"@angular/language-service": "~11.0.2",
"@nrwl/cypress": "10.2.0",
"@nrwl/jest": "10.2.0",
"@nrwl/workspace": "10.2.0",
"@types/cypress": "^1.1.3",
"@types/jasmine": "~3.6.0",
"@types/jest": "26.0.8",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cypress": "^5.6.0",
"cypress-file-upload": "^4.1.1",
"cypress-keycloak": "^1.5.0",
"cypress-keycloak-commands": "^1.2.0",
"cypress-localstorage-commands": "^1.2.4",
"dotenv": "6.2.0",
"eslint": "6.8.0",
"google-translate-api-browser": "^1.1.71",
"husky": "^4.3.0",
"jest": "26.2.2",
"jest-preset-angular": "8.2.1",
"lodash": "^4.17.20",
"moment": "^2.29.1",
"ng-packagr": "^10.1.2",
"prettier": "2.0.4",
"pretty-quick": "^3.1.0",
"superagent": "^6.1.0",
"superagent-promise": "^1.1.0",
"ts-jest": "26.1.4",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
}
},
"dependencies": {
"@angular/animations": "~11.0.1",
"@angular/cdk": "~11.0.1",
"@angular/common": "~11.0.1",
"@angular/compiler": "~11.0.1",
"@angular/core": "~11.0.1",
"@angular/forms": "~11.0.1",
"@angular/material": "~11.0.1",
"@angular/platform-browser": "~11.0.1",
"@angular/platform-browser-dynamic": "~11.0.1",
"@angular/router": "~11.0.1",
"@angular/service-worker": "~11.0.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@nrwl/angular": "^10.2.0",
"@pdftron/webviewer": "^7.0.1",
"file-saver": "^2.0.2",
"jwt-decode": "^3.0.0",
"keycloak-angular": "^8.0.1",
"keycloak-js": "10.0.2",
"lint-staged": "^10.5.0",
"ng2-ace-editor": "^0.3.9",
"ng2-file-upload": "^1.4.0",
"ngp-sort-pipe": "^0.0.4",
"ngx-color-picker": "^10.1.0",
"ngx-dropzone": "^2.2.2",
"ngx-toastr": "^13.0.0",
"rxjs": "~6.6.0",
"scroll-into-view-if-needed": "^2.2.26",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.2",
"@angular-devkit/build-ng-packagr": "~0.1002.0",
"@angular/cli": "~11.0.2",
"@angular/compiler": "~11.0.1",
"@angular/compiler-cli": "~11.0.1",
"@angular/language-service": "~11.0.2",
"@nrwl/cypress": "10.2.0",
"@nrwl/jest": "10.2.0",
"@nrwl/workspace": "10.2.0",
"@types/cypress": "^1.1.3",
"@types/jasmine": "~3.6.0",
"@types/jest": "26.0.8",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cypress": "^5.6.0",
"cypress-file-upload": "^4.1.1",
"cypress-keycloak": "^1.5.0",
"cypress-keycloak-commands": "^1.2.0",
"cypress-localstorage-commands": "^1.2.4",
"dotenv": "6.2.0",
"eslint": "6.8.0",
"google-translate-api-browser": "^1.1.71",
"husky": "^4.3.0",
"jest": "26.2.2",
"jest-preset-angular": "8.2.1",
"lodash": "^4.17.20",
"moment": "^2.29.1",
"ng-packagr": "^10.1.2",
"prettier": "2.0.4",
"pretty-quick": "^3.1.0",
"superagent": "^6.1.0",
"superagent-promise": "^1.1.0",
"ts-jest": "26.1.4",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
}
}

View File

@ -286,6 +286,13 @@
resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-11.0.2.tgz#b9a97a9bdd3d10ac2335eb94bacf8ab5514aeeb5"
integrity sha512-Cfam/NEP8hKkcqBVGlkBVuPkojZukmVOxdtsFIkIjJW/mywad2lIfjHR/0rZ43jD1bPb7s+tyYcJBgNg42p2ng==
"@angular/material-moment-adapter@^11.0.2":
version "11.0.2"
resolved "https://registry.yarnpkg.com/@angular/material-moment-adapter/-/material-moment-adapter-11.0.2.tgz#73afa45174385ece6a1cc9228ebf59ef78963cd2"
integrity sha512-/GkNJJuNziFEKU+fC6BJQmXGuWMgJcRalVA5oLotinbaVg1+GgH3eagbB2lVmSpxTDWTecr3D+K1H0ckTAeHRA==
dependencies:
tslib "^2.0.0"
"@angular/material@~11.0.1":
version "11.0.1"
resolved "https://registry.yarnpkg.com/@angular/material/-/material-11.0.1.tgz#add0e87d3e01d7d20484ea5a90d15439ec31a1d6"