Skip to content

Commit

Permalink
Due date of Review (#32)
Browse files Browse the repository at this point in the history
- [x] can set due date in sidebar of a document

- [x] can see due date in badge format of three colours
1. critical if due date is passed
2. warning if today is the due date
3. success in more than one days left

- [x] the docs listed in the "Documents waiting for your review" section
in dashboard are sorted wrt due date in ascending order
- [x] date format - MMM DD, YYYY - example - Jul 22, 2023

- [x] one table column of due date is attached in the tables of drafts,
all docs and my docs



![Screenshot 2023-07-23 at 2 20 21
AM](https://github.com/razorpay/hermes/assets/70308421/dba5d7f8-e69a-4142-ba5c-1e753646bf70)

![Screenshot 2023-07-23 at 1 14 26
AM](https://github.com/razorpay/hermes/assets/70308421/2495999c-2bd5-45cf-9e69-e56734b407d9)

<img width="1440" alt="Screenshot 2023-07-23 at 1 15 12 AM"
src="https://github.com/razorpay/hermes/assets/70308421/b375de8a-e1c6-4b04-b713-6286fb1fcdba">
  • Loading branch information
soujash-mandal authored Jul 24, 2023
1 parent 5931a9f commit 6e967d0
Show file tree
Hide file tree
Showing 16 changed files with 388 additions and 200 deletions.
11 changes: 6 additions & 5 deletions internal/api/documents.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
// to be updated with a PATCH request.
type DocumentPatchRequest struct {
Reviewers []string `json:"reviewers,omitempty"`
DueDate string `json:"dueDate,omitempty"`
Contributors []string `json:"contributors,omitempty"`
Status string `json:"status,omitempty"`
Summary string `json:"summary,omitempty"`
Expand Down Expand Up @@ -212,17 +213,17 @@ func DocumentHandler(
)

case "PATCH":
canPatchDocument:=true
canPatchDocument := true
// Authorize request (only the owner can PATCH the doc).
userEmail := r.Context().Value("userEmail").(string)
for _, reviewer := range docObj.GetReviewers() {
if reviewer==userEmail {
canPatchDocument=false
if reviewer == userEmail {
canPatchDocument = false
break
}
}
if userEmail==docObj.GetOwners()[0] {
canPatchDocument=false
if userEmail == docObj.GetOwners()[0] {
canPatchDocument = false
}

if canPatchDocument {
Expand Down
5 changes: 4 additions & 1 deletion internal/api/drafts.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import (
)

type DraftsRequest struct {
Reviewers []string `json:"approvers,omitempty"`
Reviewers []string `json:"reviewers,omitempty"`
DueDate string `json:"dueDate,omitempty"`
Contributors []string `json:"contributors,omitempty"`
DocType string `json:"docType,omitempty"`
Product string `json:"product,omitempty"`
Expand All @@ -40,6 +41,7 @@ type DraftsRequest struct {
// be updated with a PATCH request.
type DraftsPatchRequest struct {
Reviewers []string `json:"reviewers,omitempty"`
DueDate string `json:"dueDate,omitempty"`
Contributors []string `json:"contributors,omitempty"`
Product string `json:"product,omitempty"`
Team string `json:"team,omitempty"`
Expand Down Expand Up @@ -278,6 +280,7 @@ func DraftsHandler(
d := models.Document{
GoogleFileID: f.Id,
Reviewers: reviewers,
DueDate: req.DueDate,
Contributors: contributors,
DocumentCreatedAt: createdTime,
DocumentModifiedAt: createdTime,
Expand Down
7 changes: 7 additions & 0 deletions pkg/hashicorpdocs/basedoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type BaseDoc struct {
// are requested for the document.
Reviewers []string `json:"reviewers,omitempty"`

// last date to review a doc for a reviewer
DueDate string `json:"dueDate,omitempty"`

// ChangesRequestedBy is a slice of email address strings for users that have
// requested changes for the document.
ChangesRequestedBy []string `json:"changesRequestedBy,omitempty"`
Expand Down Expand Up @@ -108,6 +111,10 @@ func (d BaseDoc) GetReviewers() []string {
return d.Reviewers
}

func (d BaseDoc) GetDueDate() string {
return d.DueDate
}

func (d BaseDoc) GetChangesRequestedBy() []string {
return d.ChangesRequestedBy
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/models/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type Document struct {
// document.
Reviewers []*User `gorm:"many2many:document_reviews;"`

// last date to review a doc for a reviewer
DueDate string
// Contributors are users who have contributed to the document.
Contributors []*User `gorm:"many2many:document_contributors;"`

Expand Down
2 changes: 2 additions & 0 deletions web/app/components/dashboard/latest-updates.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
@status={{lowercase doc.status}}
@thumbnail={{doc.googleMetadata.thumbnailLink}}
@title={{doc.title}}
@dueDate={{doc.dueDate}}
@showColorBadge={{false}}
/>
{{/each}}
</div>
Expand Down
7 changes: 7 additions & 0 deletions web/app/components/doc/row.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,11 @@
<Person @ignoreUnknown={{true}} @imgURL={{@avatar}} @email={{@owner}} />
</Hds::Table::Td>
<Hds::Table::Td class="created">{{@createdDate}}</Hds::Table::Td>
<Hds::Table::Td class="created">
{{#if (not (is-empty @dueDate))}}
{{dateformat @dueDate}}
{{else}}
No Due Date
{{/if}}
</Hds::Table::Td>
</Hds::Table::Tr>
26 changes: 25 additions & 1 deletion web/app/components/doc/tile.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,32 @@
@text={{this.productAreaName}}
@icon={{or (get-product-id this.this.args.productArea) "folder"}}
/>
{{#if (not (is-empty @dueDate))}}
{{#if @showColorBadge}}
{{#if this.isDueDateOverdue}}
<Hds::Badge
@color="critical"
@text="Due Date : {{dateformat @dueDate}}"
/>
{{else if this.isDueDateToday}}
<Hds::Badge
@color="warning"
@text="Due Date : {{dateformat @dueDate}}"
/>
{{else}}
<Hds::Badge
@color="success"
@text="Due Date : {{dateformat @dueDate}}"
/>
{{/if}}
{{else}}
<Hds::Badge @text="Due Date : {{dateformat @dueDate}}" />
{{/if}}
{{else}}
<Hds::Badge @text="No Due Date" />
{{/if}}

{{#if (and @isResult @snippet)}}
<Doc::Snippet @snippet={{@snippet}} class="pt-2" />
{{/if}}
</LinkTo>
</LinkTo>
33 changes: 33 additions & 0 deletions web/app/components/doc/tile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Component from "@glimmer/component";
import parseDate from "hermes/utils/parse-date";

interface DocTileComponentSignature {
Args: {
Expand All @@ -14,6 +15,8 @@ interface DocTileComponentSignature {
status?: string;
thumbnail?: string;
title?: string;
dueDate?:string;
showColorBadge:boolean;
};
}

Expand All @@ -28,6 +31,36 @@ export default class DocTileComponent extends Component<DocTileComponentSignatur
return this.args.productArea;
}
}

get currentDate() {
// Get the current date
const today = new Date();

// Extract year, month, and day from the current date
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are zero-based, so we add 1
const day = String(today.getDate()).padStart(2, '0');

// Concatenate the parts in the desired format "yyyy-mm-dd"
return `${year}-${month}-${day}`;
}


get isDueDateOverdue() : boolean {
let date =this.args.dueDate||"";
if (this.currentDate>date) {
return true;
}
return false;
}
get isDueDateToday() : boolean {
if (this.currentDate==this.args.dueDate) {
return true;
}
return false;
}


}

declare module "@glint/environment-ember-loose/registry" {
Expand Down
41 changes: 41 additions & 0 deletions web/app/components/document/sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,47 @@
{{/if}}
</div>

<div class="flex flex-col items-start space-y-2">
<small
class="hds-typography-body-100 hds-foreground-faint"
>Due Date</small>
{{#if this.editingIsDisabled}}
<p
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-primary"
>{{dateformat @document.dueDate}}</p>
{{else}}
<EditableField
@value={{@document.dueDate}}
@onChange={{perform this.save "dueDate"}}
@loading={{this.save.isRunning}}
@disabled={{this.editingIsDisabled}}
>
<:default>
{{#unless (is-empty @document.dueDate)}}
<p
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-primary"
>
{{dateformat @document.dueDate}}</p>
{{else}}
<p
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-faint"
>
Enter due date here</p>
{{/unless}}
</:default>
<:editing as |F|>
<Hds::Form::TextInput::Field
id="user-question"
@type="date"
@value={{F.value}}
{{on "blur" F.update}}
as |F|
/>
</:editing>
</EditableField>
{{/if}}
</div>

<div class="flex flex-col items-start space-y-2">
<small class="hds-typography-body-100 hds-foreground-faint">
Created
Expand Down
9 changes: 8 additions & 1 deletion web/app/components/document/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default class DocumentSidebarComponent extends Component<DocumentSidebarC
@tracked summary = this.args.document.summary || "";
@tracked contributors = this.args.document.contributors || [];
@tracked reviewers = this.args.document.reviewers || [];
@tracked dueDate = this.args.document.dueDate || "";
@tracked product = this.args.document.product || "";
@tracked team = this.args.document.team || "";

Expand Down Expand Up @@ -165,7 +166,7 @@ export default class DocumentSidebarComponent extends Component<DocumentSidebarC
// hasReviewed returns true if the logged in user has reviewed the document.
get hasReviewed() {
let reviewedReviewers: string[] = this.args.document.reviewedBy ?? [];
let res= reviewedReviewers.includes(this.args.profile.email);
let res = reviewedReviewers.includes(this.args.profile.email);
return res;
}

Expand Down Expand Up @@ -258,6 +259,12 @@ export default class DocumentSidebarComponent extends Component<DocumentSidebarC
// productAbbreviation is computed by the back end
});

updateDueDate = restartableTask(async (date: string) => {
this.dueDate = date;
await this.save.perform("dueDate", this.dueDate);
// productAbbreviation is computed by the back end
});

isAllReviewersReviewed(
reviewedReviewers: string[],
allReviewers: string[]
Expand Down
5 changes: 4 additions & 1 deletion web/app/components/row-results.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
<H.Th class="product">Product/Area</H.Th>
<H.Th class="owner">Owner</H.Th>
<H.Th class="created">Created</H.Th>
<H.Th class="created">Due Date</H.Th>
</H.Tr>
</:head>
<:body>
{{#each @docs as |doc index|}}
<Doc::Row
@avatar="{{get doc.ownerPhotos 0}}"
@createdDate="{{parse-date doc.created}}"
{{!-- @createdDate="{{parse-date doc.created}}" --}}
@createdDate="{{doc.created}}"
@docID="{{doc.objectID}}"
@docNumber="{{doc.docNumber}}"
@docType="{{doc.docType}}"
Expand All @@ -37,6 +39,7 @@
@status="{{lowercase doc.status}}"
@title="{{doc.title}}"
@isDraft={{@isDraft}}
@dueDate="{{doc.dueDate}}"
/>
{{/each}}
</:body>
Expand Down
29 changes: 29 additions & 0 deletions web/app/helpers/dateformat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// app/helpers/format-date.ts
import { helper } from '@ember/component/helper';
const monthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
export function dateformat([date]: [string]): string {
let res="",year="",month="",day="";
let n=date.length;
if (n===0) {
return year;
}
for (let index = 0; index <=3; index++) {
let element = date[index];
year+=element;
}
for (let index = 5; index <=6; index++) {
let element = date[index];
month+=element;
}
for (let index = 8; index <=9; index++) {
let element = date[index];
day+=element;
}
res=`${monthNames[parseInt(month) - 1]} ${day}, ${year}`
return res;
}

export default helper(dateformat);
9 changes: 5 additions & 4 deletions web/app/routes/authenticated/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Route from "@ember/routing/route";
import RSVP from "rsvp";
import { inject as service } from "@ember/service";
import timeAgo from "hermes/utils/time-ago";
import {action} from "@ember/object";
import { action } from "@ember/object";

export default class DashboardRoute extends Route {
@service algolia;
Expand Down Expand Up @@ -44,7 +44,7 @@ export default class DashboardRoute extends Route {
` AND NOT reviewedBy:'${userInfo.email}'` +
" AND appCreated:true" +
" AND status:In-Review",
hitsPerPage: 4,
hitsPerPage: 1000,
})
.then((result) => {
// Add modifiedAgo for each doc.
Expand Down Expand Up @@ -79,7 +79,9 @@ export default class DashboardRoute extends Route {
this.recentDocs.all = null;
}
}

docsWaitingForReview._result = docsWaitingForReview._result.sort((a, b) =>
a.dueDate.localeCompare(b.dueDate)
);
return RSVP.hash({
docsWaitingForReview: docsWaitingForReview,
});
Expand All @@ -104,5 +106,4 @@ export default class DashboardRoute extends Route {
}
return parentsQuery;
}

}
3 changes: 2 additions & 1 deletion web/app/routes/authenticated/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export default class DocumentRoute extends Route {
}

if (!!doc.createdTime) {
doc.createdDate = parseDate(doc.createdTime * 1000, "long");
// doc.createdDate = parseDate(doc.createdTime * 1000, "long");
doc.createdDate=doc.created;
}

// Build strings for created and last-modified.
Expand Down
Loading

0 comments on commit 6e967d0

Please sign in to comment.