From d2b5202fe4775e8563f0aa78c2ace314ed262741 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Tue, 17 Nov 2020 10:57:43 +0530 Subject: [PATCH 01/22] :sparkles: Initial commit for canned messages - Move from shared to admin app and add basic UI --- app/components/canned-messages-overlay.js | 28 +++ app/controllers/review_item/donor_messages.js | 196 ++++++++++++++++- app/models/canned_response.js | 9 + app/models/message.js | 40 ++++ app/routes/review_item/donor_messages.js | 22 +- app/services/message-service.js | 38 ++++ app/styles/app.scss | 2 + app/styles/templates/_message_template.scss | 198 ++++++++++++++++++ .../components/_canned-messages-overlay.scss | 48 +++++ .../components/canned-messages-overlay.hbs | 51 +++++ app/templates/message_template.hbs | 80 +++++++ 11 files changed, 703 insertions(+), 9 deletions(-) create mode 100644 app/components/canned-messages-overlay.js create mode 100644 app/models/canned_response.js create mode 100644 app/models/message.js create mode 100644 app/services/message-service.js create mode 100644 app/styles/templates/_message_template.scss create mode 100644 app/styles/templates/components/_canned-messages-overlay.scss create mode 100644 app/templates/components/canned-messages-overlay.hbs create mode 100644 app/templates/message_template.hbs diff --git a/app/components/canned-messages-overlay.js b/app/components/canned-messages-overlay.js new file mode 100644 index 000000000..71d60c449 --- /dev/null +++ b/app/components/canned-messages-overlay.js @@ -0,0 +1,28 @@ +import Ember from "ember"; +import _ from "lodash"; +import AsyncTasksMixin, { ERROR_STRATEGIES } from "../mixins/async_tasks"; + +export default Ember.Component.extend(AsyncTasksMixin, { + messageService: Ember.inject.service(), + store: Ember.inject.service(), + + async init() { + this._super(); + await this.runTask(async () => { + await this.get("messageService").fetchCannedResponse(); + this.set("cannedResponses", this.get("store").peekAll("canned_response")); + }, ERROR_STRATEGIES.MODAL); + }, + + didRender() { + console.log(this.get("open")); + }, + + actions: { + setCannedResponse(text) { + const onSelect = this.getWithDefault("onSelect", _.noop); + onSelect(text); + this.set("open", false); + } + } +}); diff --git a/app/controllers/review_item/donor_messages.js b/app/controllers/review_item/donor_messages.js index a4a3a422d..c62596f38 100644 --- a/app/controllers/review_item/donor_messages.js +++ b/app/controllers/review_item/donor_messages.js @@ -1,7 +1,195 @@ import Ember from "ember"; -import MessagesBaseController from "shared-goodcity/controllers/messages_base"; -export default MessagesBaseController.extend({ - review_item: Ember.inject.controller('review_item'), - item: Ember.computed.alias("review_item.model") +export default Ember.Controller.extend({ + messageLinkConvertor: Ember.inject.service(), + messageService: Ember.inject.service(), + review_item: Ember.inject.controller("review_item"), + item: Ember.computed.alias("review_item.model"), + displayCannedMessages: true, + body: "", + offerController: Ember.inject.controller("offer"), + messagesUtil: Ember.inject.service("messages"), + isPrivate: false, + inProgress: false, + offer: Ember.computed.alias("offerController.model"), + sortProperties: ["createdAt:asc"], + sortedElements: Ember.computed.sort("messagesAndVersions", "sortProperties"), + isItemThread: Ember.computed.notEmpty("item"), + isCannedMessagesVisible: Ember.computed( + "messageService.isCannedMessagesVisible", + function() { + return this.get("messageService").isCannedMessagesVisible; + } + ), + + autoMarkAsRead: Ember.on( + "init", + Ember.observer( + "isActive", + "messages.[]", + "messages.@each.state", + function() { + if (this.get("isActive")) { + Ember.run.debounce(this, this.markConversationAsRead, 1500); + } + } + ) + ), + + disabled: Ember.computed("offer.isCancelled", "item.isDraft", function() { + return this.get("offer.isCancelled") || this.get("item.isDraft"); + }), + + groupedElements: Ember.computed("sortedElements.[]", function() { + return this.groupBy(this.get("sortedElements"), "createdDate"); + }), + + allMessages: Ember.computed(function() { + return this.store.peekAll("message"); + }), + + messages: Ember.computed("allMessages.[]", "offer", "item", function() { + var messages = this.get("allMessages"); + messages = this.get("isItemThread") + ? messages.filterBy("itemId", this.get("item.id")) + : messages + .filterBy("offerId", this.get("offer.id")) + .filterBy("item", null); + return messages.filter(m => { + return Boolean(m.get("isPrivate")) === this.get("isPrivate"); + }); + }), + + messagesAndVersions: Ember.computed( + "messages.[]", + "itemVersions", + "packageVersions", + "offerVersions", + function() { + var messages = this.get("messages").toArray(); + var itemVersions = this.get("itemVersions").toArray(); + var packageVersions = this.get("packageVersions").toArray(); + var offerVersions = this.get("offerVersions").toArray(); + return messages.concat(itemVersions, packageVersions, offerVersions); + } + ), + + itemVersions: Ember.computed( + "item.id", + "allVersions.[]", + "isItemThread", + function() { + if (!this.get("isItemThread")) { + return []; + } + var itemId = parseInt(this.get("item.id"), 10); + return this.get("allVersions") + .filterBy("itemId", itemId) + .filterBy("itemType", "Item"); + } + ), + + packageVersions: Ember.computed( + "item.packages", + "allVersions.[]", + "isItemThread", + function() { + if (!this.get("isItemThread")) { + return []; + } + var packageIds = (this.get("item.packages") || []).mapBy("id"); + return this.get("allVersions") + .filterBy("itemType", "Package") + .filter(function(log) { + return ( + packageIds.indexOf(String(log.get("itemId"))) >= 0 && + ["received", "missing"].indexOf(log.get("state")) >= 0 + ); + }); + } + ), + + allVersions: Ember.computed(function() { + return this.get("store").peekAll("version"); + }), + + offerVersions: Ember.computed( + "allVersions.[]", + "offer.id", + "isItemThread", + function() { + if (this.get("isItemThread")) { + return []; + } + var offerId = parseInt(this.get("offer.id"), 10); + return this.get("allVersions") + .filterBy("itemType", "Offer") + .filterBy("itemId", offerId); + } + ), + + groupBy: function(content, key) { + var result = []; + var object, value; + + content.forEach(function(item) { + value = item.get ? item.get(key) : item[key]; + object = result.findBy("value", value); + if (!object) { + object = { + value: value, + items: [] + }; + result.push(object); + } + return object.items.push(item); + }); + return result.getEach("items"); + }, + + markConversationAsRead() { + this.get("messages") + .filterBy("state", "unread") + .forEach(m => this.get("messagesUtil").markRead(m)); + }, + + actions: { + async cannedMessageLookup() { + try { + const text = await this.get("messageService").cannedMessageLookup(); + this.set("body", text); + console.log(text); + } catch (e) { + console.log(e); + } + }, + sendMessage() { + // To hide soft keyboard + Ember.$("textarea").trigger("blur"); + + this.set("inProgress", true); + var values = this.getProperties("body", "offer", "item", "isPrivate"); + values.itemId = this.get("item.id"); + values.offerId = this.get("offer.id"); + values.createdAt = new Date(); + values.sender = this.store.peekRecord( + "user", + this.get("session.currentUser.id") + ); + this.get("messageLinkConvertor").convert(values); + var message = this.store.createRecord("message", values); + message + .save() + .then(() => { + this.set("body", ""); + }) + .catch(error => { + this.store.unloadRecord(message); + throw error; + }) + .finally(() => this.set("inProgress", false)); + + Ember.$("body").animate({ scrollTop: Ember.$(document).height() }, 1000); + } + } }); diff --git a/app/models/canned_response.js b/app/models/canned_response.js new file mode 100644 index 000000000..a7cda8374 --- /dev/null +++ b/app/models/canned_response.js @@ -0,0 +1,9 @@ +import Model from "ember-data/model"; +import attr from "ember-data/attr"; + +export default Model.extend({ + nameEn: attr("string"), + nameZhTw: attr("string"), + contentEn: attr("string"), + contentZhTw: attr("string") +}); diff --git a/app/models/message.js b/app/models/message.js new file mode 100644 index 000000000..fd3d0e165 --- /dev/null +++ b/app/models/message.js @@ -0,0 +1,40 @@ +import Ember from "ember"; +import DS from "ember-data"; +const { getOwner } = Ember; + +var attr = DS.attr, + belongsTo = DS.belongsTo; + +export default DS.Model.extend({ + body: attr("string"), + isPrivate: attr("boolean"), + createdAt: attr("date"), + updatedAt: attr("date"), + offerId: attr("string"), + itemId: attr("string"), + state: attr("string", { defaultValue: "read" }), + sender: belongsTo("user", { async: false }), + item: belongsTo("item", { async: false }), + offer: belongsTo("offer", { async: false }), + + messageableType: attr("string"), + messageableId: attr("string"), + unreadCount: attr("string"), + + myMessage: Ember.computed(function() { + var session = getOwner(this).lookup("service:session"); + return this.get("sender.id") === session.get("currentUser.id"); + }), + + isMessage: Ember.computed("this", function() { + return true; + }), + + createdDate: Ember.computed(function() { + return new Date(this.get("createdAt")).toDateString(); + }), + + itemImageUrl: Ember.computed.alias("item.displayImageUrl"), + isRead: Ember.computed.equal("state", "read"), + isUnread: Ember.computed.equal("state", "unread") +}); diff --git a/app/routes/review_item/donor_messages.js b/app/routes/review_item/donor_messages.js index 8d00d5764..9044cd68f 100644 --- a/app/routes/review_item/donor_messages.js +++ b/app/routes/review_item/donor_messages.js @@ -1,12 +1,24 @@ -import MessagesBaseRoute from 'shared-goodcity/routes/messages_base'; +import AuthorizeRoute from "goodcity/routes/authorize"; -export default MessagesBaseRoute.extend({ +export default AuthorizeRoute.extend({ + setupController(controller, model) { + this._super(controller, model); + controller.set("isActive", true); + }, + + resetController(controller, isExiting) { + if (isExiting) { + controller.set("isActive", false); + } + }, renderTemplate() { - this.render('message_template', {controller: 'review_item.donor_messages'}); + this.render("message_template", { + controller: "review_item.donor_messages" + }); }, afterModel() { - var itemId = this.modelFor('review_item').get('id'); - this.store.query('version', { item_id: itemId, for_item: true }); + var itemId = this.modelFor("review_item").get("id"); + this.store.query("version", { item_id: itemId, for_item: true }); } }); diff --git a/app/services/message-service.js b/app/services/message-service.js new file mode 100644 index 000000000..0a89e8f0f --- /dev/null +++ b/app/services/message-service.js @@ -0,0 +1,38 @@ +import Ember from "ember"; +import _ from "lodash"; + +import ApiBaseService from "./api-base-service"; + +export default ApiBaseService.extend({ + store: Ember.inject.service(), + + init() { + this._super(...arguments); + this.set("isCannedMessagesVisible", false); + }, + + toggle() { + this.toggleProperty("isCannedMessagesVisible"); + }, + + async fetchCannedResponse() { + const data = await this.GET(`/canned_responses`); + this.get("store").pushPayload(data); + return data; + }, + + cannedMessageLookup() { + const deferred = Ember.RSVP.defer(); + + Ember.run(() => { + this.set("isCannedMessagesVisible", true); + this.set("onCannedMessageSelect", text => { + this.set("onCannedMessageSelect", _.noop); + this.set("openLocationSearch", false); + deferred.resolve(text || null); + }); + }); + + return deferred.promise; + } +}); diff --git a/app/styles/app.scss b/app/styles/app.scss index 51f67b358..0858cb34a 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -45,4 +45,6 @@ @import "global_styles"; @import "templates/companies/new"; @import "templates/donors/new"; +@import "templates/message_template"; +@import "templates/components/canned-messages-overlay" diff --git a/app/styles/templates/_message_template.scss b/app/styles/templates/_message_template.scss new file mode 100644 index 000000000..7a6320ee4 --- /dev/null +++ b/app/styles/templates/_message_template.scss @@ -0,0 +1,198 @@ +.message-textbar { + padding-top: 0rem !important; +} +.scaled_icon { + transform: scale(2); + margin-top: 10px; +} + +.message_bubble_box { + background-color: $white; + color: black; + width: 80%; + border-radius: 0.5rem; + padding: 0.8rem; + margin-bottom: 0.8rem; + font-size: 0.9rem; + position: relative; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + + @media #{$small-only} { + font-size: 0.7rem; + } + + .message_details { + font-size: 0.7rem; + margin-bottom: 0.5rem; + + @media #{$small-only} { + font-size: 0.6rem; + } + } + + .item_message { + float: right; + margin-top: -5%; + } + + audio { + width: 100%; + } +} + +.my_message { + @extend .message_bubble_box; + background-color: $light-yellow; + float: right; +} + +.received_message { + @extend .message_bubble_box; + float: left; +} + +.message_arrow { + content: ''; + position: absolute; + border-style: solid; + border-width: 0.5rem 0.5rem 0; + border-color: $white transparent; + display: block; + width: 0; + z-index: 1; + bottom: -0.4rem; +} + +.received_message:after +{ + @extend .message_arrow; + left: 1.5rem; +} + +.my_message:after +{ + @extend .message_arrow; + right: 1.5rem; + border-color: $light-yellow transparent; +} + +.message-section { + .icon-empty-items { + color: $body-font-color; + } + + .item_log { + text-align: center; + margin-bottom: 0.3rem; + } + a { + color: inherit !important; + text-decoration: underline; + } +} + +.btm.message-form { + height: 0px !important; +} + +.message-footer { + height: 65px; + + @media #{$small-only} { + height: 50px; + } +} + +.message_footer_small_page { + position: absolute; + bottom: 0; + width: 100%; +} + +.message-form { + .ui { + padding-bottom: 0.1rem; + + textarea { + margin: 0; + max-width: 100%; + min-height: 1rem !important; + height: 2.3rem; + padding: 0.3rem !important; + + @media #{$small-only} { + margin-left:0.2rem; + margin-right:0.2rem; + } + + @media #{$medium-only} { + margin-left:0.2rem; + } + } + + button { + padding: 0.53rem; + border-radius: 0.2rem; + line-height: 1.2rem; + width: 5rem; + margin: 0; + + @media #{$small-only} { + font-size: 0.9rem; + width: 4rem; + } + } + } + + div { + padding-top: 0.1rem; + padding-right: 0.2rem; + z-index: 10; + } + + .message-base { + background-color: #dee4eb; + } +} + +.day_seperator { + width: 100%; + text-align: center; + border-bottom: 1px solid $light-blue; + line-height: 0.1em; + margin: 10px 0 20px; + + span { + padding: 0 10px; + color: $medium-blue; + background: $dark-blue; + } +} + +.tabs-content .day_seperator span { + background: $light-grey; +} + +.review_item .day_seperator { + border-bottom: 1px solid $medium-blue; +} + +.chat_note { + color: white; + margin-bottom: 0.5rem; + + @media #{$small-only} { + font-size: 0.8rem; + } + + i { + color: $coral-red; + } +} + +.offer_details { + .message-section { + padding-top: 1rem; + } +} diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss new file mode 100644 index 000000000..0117284cd --- /dev/null +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -0,0 +1,48 @@ +.canned-message-container { + display: flex; + color: white; + flex-direction: column; + margin-top: 2rem; + + li { + margin: clamp(1rem,2vw,4rem); + list-style: none; + } + + .header { + display: flex; + align-items: center; + justify-content: center; + } + + .canned-message-list-container { + display: flex; + justify-content: flex-start; + cursor: pointer; + } + + .message-container { + flex: 0.5; + } + + .language-container { + display: flex; + flex: 0.5; + justify-content: space-evenly; + } + + .canned-content-container { + max-width: 58%; + } + + .canned-content { + white-space: nowrap; + font-size: clamp(12px, 2vw, 14px); + width: 10rem; + overflow: hidden; + text-overflow: ellipsis; + color: #a3aab6; + + } +} + diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs new file mode 100644 index 000000000..56ba9800d --- /dev/null +++ b/app/templates/components/canned-messages-overlay.hbs @@ -0,0 +1,51 @@ +
+ {{#popup-overlay open=open}} + +
+
+ Manage pro-forma messages +
+
    + {{#each cannedResponses as |res|}} +
  • +
    +
    +
    + {{res.nameEn}} +
    +
    +
    + + {{res.contentEn}} + +
    +
    +
    +
    + EN + 中文 +
    +
    +
  • + {{/each}} +
+
+ {{/popup-overlay}} +
diff --git a/app/templates/message_template.hbs b/app/templates/message_template.hbs new file mode 100644 index 000000000..135f144b8 --- /dev/null +++ b/app/templates/message_template.hbs @@ -0,0 +1,80 @@ +
+
+
+ {{#href-to-link-to}} + {{#each groupedElements as |messages|}} +
+ {{display-messages-date messages.firstObject.createdDate (t 'day.today')}} +
+ {{#each messages as |message|}} + {{#if message.isMessage}} +
+
+ {{#if message.myMessage}} + {{t "messages.owner" }} + {{else}} + {{custom-img-tag src=message.sender.displayImageUrl class="user-avatar"}} + {{t "full_name" firstName=message.sender.firstName lastName=message.sender.lastName}} + {{message.sender.roleInitials}} + {{/if}} + → + {{display-datetime message.createdAt format="HH:mm"}} +
+ {{{apply-line-break message.body}}} +
+ {{else}} +
+ {{display-datetime message.createdAt format="HH:mm"}} - {{message.displayMessage}} +
+ {{/if}} + {{/each}} + {{/each}} + {{/href-to-link-to}} +
+
+
+ +{{!-- This div holds the id of first unread message. As on page visit, it marked as read and lost the reference to first unread message --}} + +{{canned-messages-overlay open=messageService.isCannedMessagesVisible onSelect=messageService.onCannedMessageSelect}} From 3091ca96a4501b14d6a8100f153cbc0954d2e197 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Tue, 17 Nov 2020 16:52:56 +0530 Subject: [PATCH 02/22] :pencil2: Handle translations and UI improvements --- app/components/canned-messages-overlay.js | 29 ++++++----- app/models/canned_response.js | 4 +- app/services/message-service.js | 4 +- .../components/_canned-messages-overlay.scss | 9 +++- .../components/canned-messages-overlay.hbs | 48 ++++++++++--------- 5 files changed, 53 insertions(+), 41 deletions(-) diff --git a/app/components/canned-messages-overlay.js b/app/components/canned-messages-overlay.js index 71d60c449..562628d00 100644 --- a/app/components/canned-messages-overlay.js +++ b/app/components/canned-messages-overlay.js @@ -1,28 +1,33 @@ import Ember from "ember"; import _ from "lodash"; -import AsyncTasksMixin, { ERROR_STRATEGIES } from "../mixins/async_tasks"; -export default Ember.Component.extend(AsyncTasksMixin, { +export default Ember.Component.extend({ messageService: Ember.inject.service(), + displayResults: true, store: Ember.inject.service(), + onSearchTextChange: Ember.observer("searchText", function() { + Ember.run.debounce(this, this.reloadResults, 500); + }), - async init() { - this._super(); - await this.runTask(async () => { - await this.get("messageService").fetchCannedResponse(); - this.set("cannedResponses", this.get("store").peekAll("canned_response")); - }, ERROR_STRATEGIES.MODAL); - }, - - didRender() { - console.log(this.get("open")); + reloadResults() { + this.set("displayResults", false); + Ember.run.debounce(this, () => this.set("displayResults", true), 500); }, actions: { + loadMoreCannedMessages() { + const params = { searchText: this.get("searchText") }; + return this.get("store").query("canned_response", params); + }, + setCannedResponse(text) { const onSelect = this.getWithDefault("onSelect", _.noop); onSelect(text); this.set("open", false); + }, + + cancel() { + this.set("open", false); } } }); diff --git a/app/models/canned_response.js b/app/models/canned_response.js index a7cda8374..26fe1c3f8 100644 --- a/app/models/canned_response.js +++ b/app/models/canned_response.js @@ -2,8 +2,8 @@ import Model from "ember-data/model"; import attr from "ember-data/attr"; export default Model.extend({ - nameEn: attr("string"), - nameZhTw: attr("string"), + name: attr("string"), + content: attr("string"), contentEn: attr("string"), contentZhTw: attr("string") }); diff --git a/app/services/message-service.js b/app/services/message-service.js index 0a89e8f0f..40c13ab3f 100644 --- a/app/services/message-service.js +++ b/app/services/message-service.js @@ -15,8 +15,8 @@ export default ApiBaseService.extend({ this.toggleProperty("isCannedMessagesVisible"); }, - async fetchCannedResponse() { - const data = await this.GET(`/canned_responses`); + async fetchCannedResponse(opts = {}) { + const data = await this.GET(`/canned_responses`, opts); this.get("store").pushPayload(data); return data; }, diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index 0117284cd..30975f5a1 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -9,6 +9,11 @@ list-style: none; } + ul { + margin-left: 10%; + margin-right: 5%; + } + .header { display: flex; align-items: center; @@ -32,13 +37,13 @@ } .canned-content-container { - max-width: 58%; + max-width: 70%; } .canned-content { white-space: nowrap; font-size: clamp(12px, 2vw, 14px); - width: 10rem; + width: clamp(5rem, 10rem, 20rem); overflow: hidden; text-overflow: ellipsis; color: #a3aab6; diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs index 56ba9800d..28bac8658 100644 --- a/app/templates/components/canned-messages-overlay.hbs +++ b/app/templates/components/canned-messages-overlay.hbs @@ -2,7 +2,7 @@ {{#popup-overlay open=open}}
- {{#form-control}} - {{input type='text' value=name required='true' class='company-input' placeholder=(t 'donor_details.company.enter_name')}} -
+ {{input type='text' value=name required='true' autofocus ="true" class='company-input' placeholder=(t 'donor_details.company.enter_name')}} + {{#unless name}} +
{{t 'donor_details.company.company_name_validation'}}
- {{/form-control}} + {{/unless}}
diff --git a/app/templates/review_offer/donor_details.hbs b/app/templates/review_offer/donor_details.hbs index b07305ad0..c00f8d629 100644 --- a/app/templates/review_offer/donor_details.hbs +++ b/app/templates/review_offer/donor_details.hbs @@ -30,7 +30,7 @@
{{#if currentOffer.companyId}} - {{currentOffer.companyName}} + {{currentOffer.company.name}}
From 95cb78f4548f8e0cc8f4a0ecae4eb8795bef98d7 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Wed, 18 Nov 2020 08:55:36 +0530 Subject: [PATCH 04/22] :lipstick: Add UI stylings and handle mobile views --- app/components/canned-messages-overlay.js | 9 ++++ .../components/_canned-messages-overlay.scss | 41 +++++++++++++++++-- .../components/canned-messages-overlay.hbs | 41 +++++++++++-------- 3 files changed, 69 insertions(+), 22 deletions(-) diff --git a/app/components/canned-messages-overlay.js b/app/components/canned-messages-overlay.js index 562628d00..304d58c8e 100644 --- a/app/components/canned-messages-overlay.js +++ b/app/components/canned-messages-overlay.js @@ -14,6 +14,10 @@ export default Ember.Component.extend({ Ember.run.debounce(this, () => this.set("displayResults", true), 500); }, + hasSearchText: Ember.computed("searchText", function() { + return this.get("searchText") && this.get("searchText").trim().length; + }), + actions: { loadMoreCannedMessages() { const params = { searchText: this.get("searchText") }; @@ -21,11 +25,16 @@ export default Ember.Component.extend({ }, setCannedResponse(text) { + if (!text) return; const onSelect = this.getWithDefault("onSelect", _.noop); onSelect(text); this.set("open", false); }, + clearSearch() { + this.set("searchText", ""); + }, + cancel() { this.set("open", false); } diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index 30975f5a1..a4c4be140 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -1,11 +1,33 @@ +.canned-search-container { + display: flex; + width: 58%; + justify-content: space-around; + align-items: center; + margin-left: 21%; + + @media #{$small-only} { + width: 100%; + margin-left: 0%; + } + + .search-field { + flex: 0.8; + } + + .clear-search { + margin-right: 1rem; + } +} + .canned-message-container { display: flex; color: white; flex-direction: column; margin-top: 2rem; + li { - margin: clamp(1rem,2vw,4rem); + margin: clamp(1rem, 2vw, 4rem); list-style: none; } @@ -23,7 +45,6 @@ .canned-message-list-container { display: flex; justify-content: flex-start; - cursor: pointer; } .message-container { @@ -36,6 +57,16 @@ justify-content: space-evenly; } + .language-container > span { + cursor: pointer; + } + + .language-container > span.disabled { + + color: $org-grey; + cursor: default; + } + .canned-content-container { max-width: 70%; } @@ -43,11 +74,13 @@ .canned-content { white-space: nowrap; font-size: clamp(12px, 2vw, 14px); - width: clamp(5rem, 10rem, 20rem); + width: 20rem; overflow: hidden; text-overflow: ellipsis; color: #a3aab6; - + @media #{$small-only} { + width: 10rem; + } } } diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs index 28bac8658..710d7933f 100644 --- a/app/templates/components/canned-messages-overlay.hbs +++ b/app/templates/components/canned-messages-overlay.hbs @@ -1,21 +1,19 @@
{{#popup-overlay open=open}} - From 10d1d690378098c6c9781a25ad482f9d69751172 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Wed, 18 Nov 2020 12:59:14 +0530 Subject: [PATCH 05/22] :art: Handle UI behaviour when Chinese translation is not available --- app/models/canned_response.js | 1 + app/templates/components/canned-messages-overlay.hbs | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/canned_response.js b/app/models/canned_response.js index 26fe1c3f8..cb32207a2 100644 --- a/app/models/canned_response.js +++ b/app/models/canned_response.js @@ -3,6 +3,7 @@ import attr from "ember-data/attr"; export default Model.extend({ name: attr("string"), + nameEn: attr("string"), content: attr("string"), contentEn: attr("string"), contentZhTw: attr("string") diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs index 710d7933f..677b8237d 100644 --- a/app/templates/components/canned-messages-overlay.hbs +++ b/app/templates/components/canned-messages-overlay.hbs @@ -28,7 +28,11 @@
- {{cannedMessage.name}} + {{#if cannedMessage.name}} + {{cannedMessage.name}} + {{else}} + {{cannedMessage.nameEn}} + {{/if}}
From 9cfe2a428e814f68127cc7c9dbfd4446393bb55c Mon Sep 17 00:00:00 2001 From: bharat619 Date: Thu, 19 Nov 2020 09:16:09 +0530 Subject: [PATCH 06/22] :fire: Remove message_styles file --- app/styles/app.scss | 1 - app/styles/templates/_message_template.scss | 198 ------------------ .../components/_canned-messages-overlay.scss | 15 +- 3 files changed, 10 insertions(+), 204 deletions(-) delete mode 100644 app/styles/templates/_message_template.scss diff --git a/app/styles/app.scss b/app/styles/app.scss index 0858cb34a..bc89426e7 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -45,6 +45,5 @@ @import "global_styles"; @import "templates/companies/new"; @import "templates/donors/new"; -@import "templates/message_template"; @import "templates/components/canned-messages-overlay" diff --git a/app/styles/templates/_message_template.scss b/app/styles/templates/_message_template.scss deleted file mode 100644 index 7a6320ee4..000000000 --- a/app/styles/templates/_message_template.scss +++ /dev/null @@ -1,198 +0,0 @@ -.message-textbar { - padding-top: 0rem !important; -} -.scaled_icon { - transform: scale(2); - margin-top: 10px; -} - -.message_bubble_box { - background-color: $white; - color: black; - width: 80%; - border-radius: 0.5rem; - padding: 0.8rem; - margin-bottom: 0.8rem; - font-size: 0.9rem; - position: relative; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - - @media #{$small-only} { - font-size: 0.7rem; - } - - .message_details { - font-size: 0.7rem; - margin-bottom: 0.5rem; - - @media #{$small-only} { - font-size: 0.6rem; - } - } - - .item_message { - float: right; - margin-top: -5%; - } - - audio { - width: 100%; - } -} - -.my_message { - @extend .message_bubble_box; - background-color: $light-yellow; - float: right; -} - -.received_message { - @extend .message_bubble_box; - float: left; -} - -.message_arrow { - content: ''; - position: absolute; - border-style: solid; - border-width: 0.5rem 0.5rem 0; - border-color: $white transparent; - display: block; - width: 0; - z-index: 1; - bottom: -0.4rem; -} - -.received_message:after -{ - @extend .message_arrow; - left: 1.5rem; -} - -.my_message:after -{ - @extend .message_arrow; - right: 1.5rem; - border-color: $light-yellow transparent; -} - -.message-section { - .icon-empty-items { - color: $body-font-color; - } - - .item_log { - text-align: center; - margin-bottom: 0.3rem; - } - a { - color: inherit !important; - text-decoration: underline; - } -} - -.btm.message-form { - height: 0px !important; -} - -.message-footer { - height: 65px; - - @media #{$small-only} { - height: 50px; - } -} - -.message_footer_small_page { - position: absolute; - bottom: 0; - width: 100%; -} - -.message-form { - .ui { - padding-bottom: 0.1rem; - - textarea { - margin: 0; - max-width: 100%; - min-height: 1rem !important; - height: 2.3rem; - padding: 0.3rem !important; - - @media #{$small-only} { - margin-left:0.2rem; - margin-right:0.2rem; - } - - @media #{$medium-only} { - margin-left:0.2rem; - } - } - - button { - padding: 0.53rem; - border-radius: 0.2rem; - line-height: 1.2rem; - width: 5rem; - margin: 0; - - @media #{$small-only} { - font-size: 0.9rem; - width: 4rem; - } - } - } - - div { - padding-top: 0.1rem; - padding-right: 0.2rem; - z-index: 10; - } - - .message-base { - background-color: #dee4eb; - } -} - -.day_seperator { - width: 100%; - text-align: center; - border-bottom: 1px solid $light-blue; - line-height: 0.1em; - margin: 10px 0 20px; - - span { - padding: 0 10px; - color: $medium-blue; - background: $dark-blue; - } -} - -.tabs-content .day_seperator span { - background: $light-grey; -} - -.review_item .day_seperator { - border-bottom: 1px solid $medium-blue; -} - -.chat_note { - color: white; - margin-bottom: 0.5rem; - - @media #{$small-only} { - font-size: 0.8rem; - } - - i { - color: $coral-red; - } -} - -.offer_details { - .message-section { - padding-top: 1rem; - } -} diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index a4c4be140..ecdcb7a52 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -1,9 +1,9 @@ .canned-search-container { display: flex; - width: 58%; + width: clamp(25rem, 62%, 46rem); justify-content: space-around; align-items: center; - margin-left: 21%; + margin-left: 20%; @media #{$small-only} { width: 100%; @@ -23,17 +23,22 @@ display: flex; color: white; flex-direction: column; - margin-top: 2rem; + margin-top: 1.5rem; li { - margin: clamp(1rem, 2vw, 4rem); + margin-bottom: clamp(1rem, 5vw, 4rem); list-style: none; } ul { - margin-left: 10%; + margin-left: clamp(4rem, 20%, 14rem); margin-right: 5%; + margin-top: 1rem; + @media #{$small-only} { + margin-left: 8%; + margin-right: auto; + } } .header { From 77c62f18c8e90c0577741dd359bc244b764bbcdd Mon Sep 17 00:00:00 2001 From: bharat619 Date: Thu, 19 Nov 2020 09:45:17 +0530 Subject: [PATCH 07/22] Adding translation --- app/locales/en/translations.coffee | 3 +++ app/locales/zh-tw/translations.coffee | 3 +++ .../templates/components/_canned-messages-overlay.scss | 6 ++++++ app/templates/components/canned-messages-overlay.hbs | 2 +- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/locales/en/translations.coffee b/app/locales/en/translations.coffee index a8fc75221..21de5fd58 100644 --- a/app/locales/en/translations.coffee +++ b/app/locales/en/translations.coffee @@ -447,4 +447,7 @@ I18nTranslationsEn = "last_name": "Last name can't be blank" "cell_phone": "Mobile number can't be blank" + "canned_response": + "title": "Manage pro-forma messages" + `export default I18nTranslationsEn` diff --git a/app/locales/zh-tw/translations.coffee b/app/locales/zh-tw/translations.coffee index dc3e020b7..1e969a9c0 100644 --- a/app/locales/zh-tw/translations.coffee +++ b/app/locales/zh-tw/translations.coffee @@ -446,4 +446,7 @@ I18nTranslationsZhTw = "last_name": "姓氏不能漏空" "cell_phone": "電話號碼不能漏空" + "canned_response": + "title": "Manage pro-forma messages" + `export default I18nTranslationsZhTw` diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index ecdcb7a52..d6724afee 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -1,3 +1,8 @@ +.scaled_icon { + transform: scale(2); + margin-top: 0.8rem; +} + .canned-search-container { display: flex; width: clamp(25rem, 62%, 46rem); @@ -45,6 +50,7 @@ display: flex; align-items: center; justify-content: center; + text-decoration: underline; } .canned-message-list-container { diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs index 677b8237d..a3df8c5f8 100644 --- a/app/templates/components/canned-messages-overlay.hbs +++ b/app/templates/components/canned-messages-overlay.hbs @@ -18,7 +18,7 @@
- Manage pro-forma messages + {{t 'canned_response.title'}}
{{#if displayResults}} {{#infinite-list height="82vh" loadMore=(action "loadMoreCannedMessages") as |cannedMessages| }} From 986485ec69634e0c885209e7dbe4cf2cd17f0565 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Mon, 23 Nov 2020 23:35:54 +0530 Subject: [PATCH 08/22] Fix tests --- tests/acceptance/complete_review_offer_test.js | 9 +++++++++ tests/acceptance/reviewer-item-messages-test.js | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/acceptance/complete_review_offer_test.js b/tests/acceptance/complete_review_offer_test.js index f8e44b670..ab14e00d1 100644 --- a/tests/acceptance/complete_review_offer_test.js +++ b/tests/acceptance/complete_review_offer_test.js @@ -33,6 +33,15 @@ module("In Review Offers", { } }); + $.mockjax({ + url: "/api/v1/canned_responses", + type: "GET", + status: 200, + responseText: { + canned_responses: [] + } + }); + $.mockjax({ url: "/api/v1/packages_location*", type: "GET", diff --git a/tests/acceptance/reviewer-item-messages-test.js b/tests/acceptance/reviewer-item-messages-test.js index 6ec5f9fa2..f3aed8faa 100644 --- a/tests/acceptance/reviewer-item-messages-test.js +++ b/tests/acceptance/reviewer-item-messages-test.js @@ -65,6 +65,15 @@ module("Reviewer: Display Item Messages", { messages: [message1, message2, message3] } }); + + $.mockjax({ + url: "/api/v1/canned_responses", + type: "GET", + status: 200, + responseText: { + canned_responses: [] + } + }); }, afterEach: function() { From 1cea4579cc4186352bdabf8619e7f30e1d75539b Mon Sep 17 00:00:00 2001 From: bharat619 Date: Tue, 24 Nov 2020 09:26:46 +0530 Subject: [PATCH 09/22] Fix tests --- tests/acceptance/complete_review_offer_test.js | 2 +- tests/acceptance/reviewer-item-messages-test.js | 2 +- tests/acceptance/reviewer-offer-messages-test.js | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/complete_review_offer_test.js b/tests/acceptance/complete_review_offer_test.js index ab14e00d1..2b5aa5c51 100644 --- a/tests/acceptance/complete_review_offer_test.js +++ b/tests/acceptance/complete_review_offer_test.js @@ -34,7 +34,7 @@ module("In Review Offers", { }); $.mockjax({ - url: "/api/v1/canned_responses", + url: "/api/v1/canned_respons*", type: "GET", status: 200, responseText: { diff --git a/tests/acceptance/reviewer-item-messages-test.js b/tests/acceptance/reviewer-item-messages-test.js index f3aed8faa..06b284204 100644 --- a/tests/acceptance/reviewer-item-messages-test.js +++ b/tests/acceptance/reviewer-item-messages-test.js @@ -67,7 +67,7 @@ module("Reviewer: Display Item Messages", { }); $.mockjax({ - url: "/api/v1/canned_responses", + url: "/api/v1/canned_response*", type: "GET", status: 200, responseText: { diff --git a/tests/acceptance/reviewer-offer-messages-test.js b/tests/acceptance/reviewer-offer-messages-test.js index 4cc124756..8e9f08bc1 100644 --- a/tests/acceptance/reviewer-offer-messages-test.js +++ b/tests/acceptance/reviewer-offer-messages-test.js @@ -85,6 +85,15 @@ module("Reviewer: Display Offer Messages", { responseText: { messages } }); + $.mockjax({ + url: "/api/v1/canned_response*", + type: "GET", + status: 200, + responseText: { + canned_responses: [] + } + }); + $.mockjax({ url: "/api/v1/offer*", type: "GET", From f1f7114316085752c268cf9d6688133205742b6d Mon Sep 17 00:00:00 2001 From: bharat619 Date: Tue, 24 Nov 2020 09:37:44 +0530 Subject: [PATCH 10/22] Fix tests --- tests/acceptance/reviewer-offer-tab-test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/acceptance/reviewer-offer-tab-test.js b/tests/acceptance/reviewer-offer-tab-test.js index 44d82f30e..c5605aefd 100644 --- a/tests/acceptance/reviewer-offer-tab-test.js +++ b/tests/acceptance/reviewer-offer-tab-test.js @@ -28,6 +28,15 @@ module("Reviewer: Display Offer Tab", { } }); + $.mockjax({ + url: "/api/v1/canned_response*", + type: "GET", + status: 200, + responseText: { + canned_responses: [] + } + }); + offer = FactoryGuy.make("offer", { state: "under_review" }); msg_time = new Date().setHours(0, 0, 0); message1 = FactoryGuy.make("message", { From 76e97939ea6cbb244f4d6a6b8073be3d4b4bcf43 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Wed, 25 Nov 2020 11:31:44 +0530 Subject: [PATCH 11/22] Adding canned messages for Donot Offer Messages --- app/controllers/message_base_controller.js | 182 +++++++++++++++++ app/controllers/offer/donor_messages.js | 6 +- app/controllers/review_item/donor_messages.js | 193 +----------------- app/routes/message_base.js | 14 ++ app/routes/offer/donor_messages.js | 10 +- app/routes/review_item/donor_messages.js | 14 +- .../components/_canned-messages-overlay.scss | 1 + 7 files changed, 214 insertions(+), 206 deletions(-) create mode 100644 app/controllers/message_base_controller.js create mode 100644 app/routes/message_base.js diff --git a/app/controllers/message_base_controller.js b/app/controllers/message_base_controller.js new file mode 100644 index 000000000..781805c95 --- /dev/null +++ b/app/controllers/message_base_controller.js @@ -0,0 +1,182 @@ +import Ember from "ember"; + +export default Ember.Controller.extend({ + messageLinkConvertor: Ember.inject.service(), + messageService: Ember.inject.service(), + body: "", + offerController: Ember.inject.controller("offer"), + messagesUtil: Ember.inject.service("messages"), + isPrivate: false, + inProgress: false, + offer: Ember.computed.alias("offerController.model"), + sortProperties: ["createdAt:asc"], + sortedElements: Ember.computed.sort("messagesAndVersions", "sortProperties"), + isItemThread: Ember.computed.notEmpty("item"), + + autoMarkAsRead: Ember.on( + "init", + Ember.observer( + "isActive", + "messages.[]", + "messages.@each.state", + function() { + if (this.get("isActive")) { + Ember.run.debounce(this, this.markConversationAsRead, 1500); + } + } + ) + ), + + disabled: Ember.computed("offer.isCancelled", "item.isDraft", function() { + return this.get("offer.isCancelled") || this.get("item.isDraft"); + }), + + groupedElements: Ember.computed("sortedElements.[]", function() { + return this.groupBy(this.get("sortedElements"), "createdDate"); + }), + + allMessages: Ember.computed(function() { + return this.store.peekAll("message"); + }), + + messages: Ember.computed("allMessages.[]", "offer", "item", function() { + var messages = this.get("allMessages"); + messages = this.get("isItemThread") + ? messages.filterBy("itemId", this.get("item.id")) + : messages + .filterBy("offerId", this.get("offer.id")) + .filterBy("item", null); + return messages.filter(m => { + return Boolean(m.get("isPrivate")) === this.get("isPrivate"); + }); + }), + + messagesAndVersions: Ember.computed( + "messages.[]", + "itemVersions", + "packageVersions", + "offerVersions", + function() { + var messages = this.get("messages").toArray(); + var itemVersions = this.get("itemVersions").toArray(); + var packageVersions = this.get("packageVersions").toArray(); + var offerVersions = this.get("offerVersions").toArray(); + return messages.concat(itemVersions, packageVersions, offerVersions); + } + ), + + itemVersions: Ember.computed( + "item.id", + "allVersions.[]", + "isItemThread", + function() { + if (!this.get("isItemThread")) { + return []; + } + var itemId = parseInt(this.get("item.id"), 10); + return this.get("allVersions") + .filterBy("itemId", itemId) + .filterBy("itemType", "Item"); + } + ), + + packageVersions: Ember.computed( + "item.packages", + "allVersions.[]", + "isItemThread", + function() { + if (!this.get("isItemThread")) { + return []; + } + var packageIds = (this.get("item.packages") || []).mapBy("id"); + return this.get("allVersions") + .filterBy("itemType", "Package") + .filter(function(log) { + return ( + packageIds.indexOf(String(log.get("itemId"))) >= 0 && + ["received", "missing"].indexOf(log.get("state")) >= 0 + ); + }); + } + ), + + allVersions: Ember.computed(function() { + return this.get("store").peekAll("version"); + }), + + offerVersions: Ember.computed( + "allVersions.[]", + "offer.id", + "isItemThread", + function() { + if (this.get("isItemThread")) { + return []; + } + var offerId = parseInt(this.get("offer.id"), 10); + return this.get("allVersions") + .filterBy("itemType", "Offer") + .filterBy("itemId", offerId); + } + ), + + groupBy: function(content, key) { + var result = []; + var object, value; + + content.forEach(function(item) { + value = item.get ? item.get(key) : item[key]; + object = result.findBy("value", value); + if (!object) { + object = { + value: value, + items: [] + }; + result.push(object); + } + return object.items.push(item); + }); + return result.getEach("items"); + }, + + markConversationAsRead() { + this.get("messages") + .filterBy("state", "unread") + .forEach(m => this.get("messagesUtil").markRead(m)); + }, + + actions: { + async cannedMessageLookup() { + const text = await this.get("messageService").cannedMessageLookup(); + this.set("body", text); + }, + + sendMessage() { + // To hide soft keyboard + Ember.$("textarea").trigger("blur"); + + this.set("inProgress", true); + var values = this.getProperties("body", "offer", "item", "isPrivate"); + values.itemId = this.get("item.id"); + values.offerId = this.get("offer.id"); + values.createdAt = new Date(); + values.sender = this.store.peekRecord( + "user", + this.get("session.currentUser.id") + ); + this.get("messageLinkConvertor").convert(values); + var message = this.store.createRecord("message", values); + message + .save() + .then(() => { + this.set("body", ""); + }) + .catch(error => { + this.store.unloadRecord(message); + throw error; + }) + .finally(() => this.set("inProgress", false)); + + Ember.$("body").animate({ scrollTop: Ember.$(document).height() }, 1000); + } + } +}); diff --git a/app/controllers/offer/donor_messages.js b/app/controllers/offer/donor_messages.js index 58d894cbf..3ba09101e 100644 --- a/app/controllers/offer/donor_messages.js +++ b/app/controllers/offer/donor_messages.js @@ -1,3 +1,5 @@ -import MessagesBaseController from "shared-goodcity/controllers/messages_base"; +import MessagesBaseController from "../message_base_controller"; -export default MessagesBaseController; +export default MessagesBaseController.extend({ + displayCannedMessages: true +}); diff --git a/app/controllers/review_item/donor_messages.js b/app/controllers/review_item/donor_messages.js index c62596f38..a1710efa4 100644 --- a/app/controllers/review_item/donor_messages.js +++ b/app/controllers/review_item/donor_messages.js @@ -1,195 +1,8 @@ import Ember from "ember"; +import MessagesBaseController from "../message_base_controller"; -export default Ember.Controller.extend({ - messageLinkConvertor: Ember.inject.service(), - messageService: Ember.inject.service(), +export default MessagesBaseController.extend({ review_item: Ember.inject.controller("review_item"), item: Ember.computed.alias("review_item.model"), - displayCannedMessages: true, - body: "", - offerController: Ember.inject.controller("offer"), - messagesUtil: Ember.inject.service("messages"), - isPrivate: false, - inProgress: false, - offer: Ember.computed.alias("offerController.model"), - sortProperties: ["createdAt:asc"], - sortedElements: Ember.computed.sort("messagesAndVersions", "sortProperties"), - isItemThread: Ember.computed.notEmpty("item"), - isCannedMessagesVisible: Ember.computed( - "messageService.isCannedMessagesVisible", - function() { - return this.get("messageService").isCannedMessagesVisible; - } - ), - - autoMarkAsRead: Ember.on( - "init", - Ember.observer( - "isActive", - "messages.[]", - "messages.@each.state", - function() { - if (this.get("isActive")) { - Ember.run.debounce(this, this.markConversationAsRead, 1500); - } - } - ) - ), - - disabled: Ember.computed("offer.isCancelled", "item.isDraft", function() { - return this.get("offer.isCancelled") || this.get("item.isDraft"); - }), - - groupedElements: Ember.computed("sortedElements.[]", function() { - return this.groupBy(this.get("sortedElements"), "createdDate"); - }), - - allMessages: Ember.computed(function() { - return this.store.peekAll("message"); - }), - - messages: Ember.computed("allMessages.[]", "offer", "item", function() { - var messages = this.get("allMessages"); - messages = this.get("isItemThread") - ? messages.filterBy("itemId", this.get("item.id")) - : messages - .filterBy("offerId", this.get("offer.id")) - .filterBy("item", null); - return messages.filter(m => { - return Boolean(m.get("isPrivate")) === this.get("isPrivate"); - }); - }), - - messagesAndVersions: Ember.computed( - "messages.[]", - "itemVersions", - "packageVersions", - "offerVersions", - function() { - var messages = this.get("messages").toArray(); - var itemVersions = this.get("itemVersions").toArray(); - var packageVersions = this.get("packageVersions").toArray(); - var offerVersions = this.get("offerVersions").toArray(); - return messages.concat(itemVersions, packageVersions, offerVersions); - } - ), - - itemVersions: Ember.computed( - "item.id", - "allVersions.[]", - "isItemThread", - function() { - if (!this.get("isItemThread")) { - return []; - } - var itemId = parseInt(this.get("item.id"), 10); - return this.get("allVersions") - .filterBy("itemId", itemId) - .filterBy("itemType", "Item"); - } - ), - - packageVersions: Ember.computed( - "item.packages", - "allVersions.[]", - "isItemThread", - function() { - if (!this.get("isItemThread")) { - return []; - } - var packageIds = (this.get("item.packages") || []).mapBy("id"); - return this.get("allVersions") - .filterBy("itemType", "Package") - .filter(function(log) { - return ( - packageIds.indexOf(String(log.get("itemId"))) >= 0 && - ["received", "missing"].indexOf(log.get("state")) >= 0 - ); - }); - } - ), - - allVersions: Ember.computed(function() { - return this.get("store").peekAll("version"); - }), - - offerVersions: Ember.computed( - "allVersions.[]", - "offer.id", - "isItemThread", - function() { - if (this.get("isItemThread")) { - return []; - } - var offerId = parseInt(this.get("offer.id"), 10); - return this.get("allVersions") - .filterBy("itemType", "Offer") - .filterBy("itemId", offerId); - } - ), - - groupBy: function(content, key) { - var result = []; - var object, value; - - content.forEach(function(item) { - value = item.get ? item.get(key) : item[key]; - object = result.findBy("value", value); - if (!object) { - object = { - value: value, - items: [] - }; - result.push(object); - } - return object.items.push(item); - }); - return result.getEach("items"); - }, - - markConversationAsRead() { - this.get("messages") - .filterBy("state", "unread") - .forEach(m => this.get("messagesUtil").markRead(m)); - }, - - actions: { - async cannedMessageLookup() { - try { - const text = await this.get("messageService").cannedMessageLookup(); - this.set("body", text); - console.log(text); - } catch (e) { - console.log(e); - } - }, - sendMessage() { - // To hide soft keyboard - Ember.$("textarea").trigger("blur"); - - this.set("inProgress", true); - var values = this.getProperties("body", "offer", "item", "isPrivate"); - values.itemId = this.get("item.id"); - values.offerId = this.get("offer.id"); - values.createdAt = new Date(); - values.sender = this.store.peekRecord( - "user", - this.get("session.currentUser.id") - ); - this.get("messageLinkConvertor").convert(values); - var message = this.store.createRecord("message", values); - message - .save() - .then(() => { - this.set("body", ""); - }) - .catch(error => { - this.store.unloadRecord(message); - throw error; - }) - .finally(() => this.set("inProgress", false)); - - Ember.$("body").animate({ scrollTop: Ember.$(document).height() }, 1000); - } - } + displayCannedMessages: true }); diff --git a/app/routes/message_base.js b/app/routes/message_base.js new file mode 100644 index 000000000..5a22079e4 --- /dev/null +++ b/app/routes/message_base.js @@ -0,0 +1,14 @@ +import AuthorizeRoute from "goodcity/routes/authorize"; + +export default AuthorizeRoute.extend({ + setupController(controller, model) { + this._super(controller, model); + controller.set("isActive", true); + }, + + resetController(controller, isExiting) { + if (isExiting) { + controller.set("isActive", false); + } + } +}); diff --git a/app/routes/offer/donor_messages.js b/app/routes/offer/donor_messages.js index 1c27581c0..2618236e0 100644 --- a/app/routes/offer/donor_messages.js +++ b/app/routes/offer/donor_messages.js @@ -1,8 +1,14 @@ -import MessagesBaseRoute from 'shared-goodcity/routes/messages_base'; +import MessagesBaseRoute from "../message_base"; export default MessagesBaseRoute.extend({ afterModel() { var offerId = this.modelFor("offer").get("id"); - this.store.query('version', { item_id: offerId, for_offer: true }); + this.store.query("version", { item_id: offerId, for_offer: true }); + }, + + resetController(controller, isExiting) { + if (isExiting) { + controller.set("isActive", false); + } } }); diff --git a/app/routes/review_item/donor_messages.js b/app/routes/review_item/donor_messages.js index 9044cd68f..f6967e616 100644 --- a/app/routes/review_item/donor_messages.js +++ b/app/routes/review_item/donor_messages.js @@ -1,16 +1,6 @@ -import AuthorizeRoute from "goodcity/routes/authorize"; +import MessagesBaseRoute from "../message_base"; -export default AuthorizeRoute.extend({ - setupController(controller, model) { - this._super(controller, model); - controller.set("isActive", true); - }, - - resetController(controller, isExiting) { - if (isExiting) { - controller.set("isActive", false); - } - }, +export default MessagesBaseRoute.extend({ renderTemplate() { this.render("message_template", { controller: "review_item.donor_messages" diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index d6724afee..e2998ae20 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -1,6 +1,7 @@ .scaled_icon { transform: scale(2); margin-top: 0.8rem; + color: black; } .canned-search-container { From 0ed7b4692739684bbfa0aec807ccb8ee6dba23f1 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Wed, 25 Nov 2020 11:34:22 +0530 Subject: [PATCH 12/22] Remove header link --- app/styles/templates/components/_canned-messages-overlay.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index e2998ae20..73ea38dcc 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -48,7 +48,7 @@ } .header { - display: flex; + display: none; align-items: center; justify-content: center; text-decoration: underline; From 865fb1c11355d6a49cf2cecbcc860982671cec68 Mon Sep 17 00:00:00 2001 From: bharat619 Date: Wed, 25 Nov 2020 11:49:20 +0530 Subject: [PATCH 13/22] Adds absolute path --- app/controllers/offer/donor_messages.js | 2 +- app/controllers/review_item/donor_messages.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/offer/donor_messages.js b/app/controllers/offer/donor_messages.js index 3ba09101e..71ca65836 100644 --- a/app/controllers/offer/donor_messages.js +++ b/app/controllers/offer/donor_messages.js @@ -1,4 +1,4 @@ -import MessagesBaseController from "../message_base_controller"; +import MessagesBaseController from "goodcity/controllers/message_base_controller"; export default MessagesBaseController.extend({ displayCannedMessages: true diff --git a/app/controllers/review_item/donor_messages.js b/app/controllers/review_item/donor_messages.js index a1710efa4..8c3d2efe6 100644 --- a/app/controllers/review_item/donor_messages.js +++ b/app/controllers/review_item/donor_messages.js @@ -1,5 +1,5 @@ import Ember from "ember"; -import MessagesBaseController from "../message_base_controller"; +import MessagesBaseController from "goodcity/controllers/message_base_controller"; export default MessagesBaseController.extend({ review_item: Ember.inject.controller("review_item"), From 3f7eb76505b082eed40a5b41b3f16f7f119a7fb4 Mon Sep 17 00:00:00 2001 From: shreyas098 Date: Thu, 26 Nov 2020 02:05:07 +0530 Subject: [PATCH 14/22] GCW-3399 Adding New Offers count in dashboard --- app/templates/dashboard/_recent_new_offers.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/dashboard/_recent_new_offers.hbs b/app/templates/dashboard/_recent_new_offers.hbs index cbc9f386e..6d404573f 100644 --- a/app/templates/dashboard/_recent_new_offers.hbs +++ b/app/templates/dashboard/_recent_new_offers.hbs @@ -1,7 +1,7 @@

- {{t "dashboard.new_offers"}} + {{t "dashboard.new_offers"}} ({{offers-count-display offersCount "submitted" false}})  ({{if offersCount.priority_submitted offersCount.priority_submitted 0}})

{{#each model.recentOffers as |offer|}} From 6d9bdca10b42d52783aa7cefc4ed1d7adeb0e7ea Mon Sep 17 00:00:00 2001 From: shreyas098 Date: Thu, 26 Nov 2020 18:44:28 +0530 Subject: [PATCH 15/22] QA fixes for adding company to offers --- app/controllers/companies/edit.js | 13 +++++++++---- app/controllers/companies/new.js | 28 +++++++++++++++++++++++----- app/templates/companies/new.hbs | 2 +- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/controllers/companies/edit.js b/app/controllers/companies/edit.js index 1fb75eb43..5a383ff93 100644 --- a/app/controllers/companies/edit.js +++ b/app/controllers/companies/edit.js @@ -1,6 +1,7 @@ import Ember from "ember"; export default Ember.Controller.extend({ + messageBox: Ember.inject.service(), actions: { back() { this.get("model.company").rollbackAttributes(); @@ -10,16 +11,20 @@ export default Ember.Controller.extend({ ); }, updateCompany() { - let self = this; let company = this.get("model.company"); let offer = this.get("model"); company.set("name", this.get("model.company.name")); company.set("crmId", this.get("model.company.crmId")); company.set("updatedById", this.get("session.currentUser.id")); - company.save().then(function() { - self.transitionToRoute("review_offer.donor_details", offer.get("id")); - }); + company + .save() + .then(() => { + this.transitionToRoute("review_offer.donor_details", offer.get("id")); + }) + .catch(e => + this.get("messageBox").alert(e.errors[0]["detail"].message) + ); } } }); diff --git a/app/controllers/companies/new.js b/app/controllers/companies/new.js index 73b8834f9..121ac1f68 100644 --- a/app/controllers/companies/new.js +++ b/app/controllers/companies/new.js @@ -2,8 +2,17 @@ import Ember from "ember"; export default Ember.Controller.extend({ offerId: Ember.computed.alias("model.id"), + messageBox: Ember.inject.service(), actions: { + back() { + this.get("model.company") && + this.get("model.company").rollbackAttributes(); + this.transitionToRoute( + "review_offer.donor_details", + this.get("model.id") + ); + }, saveCompanyAndOffer() { if (!this.get("name")) { return; @@ -17,12 +26,21 @@ export default Ember.Controller.extend({ crmId: crmId, createdById: createdById }); + company.get("offers").pushObject(offer); - company.save().then(() => { - offer.save().then(() => { - this.transitionToRoute("review_offer.donor_details", offer.get("id")); - }); - }); + company + .save() + .then(() => { + offer.save().then(() => { + this.transitionToRoute( + "review_offer.donor_details", + offer.get("id") + ); + }); + }) + .catch(e => + this.get("messageBox").alert(e.errors[0]["detail"].message) + ); } } }); diff --git a/app/templates/companies/new.hbs b/app/templates/companies/new.hbs index 7c9493add..febc60268 100644 --- a/app/templates/companies/new.hbs +++ b/app/templates/companies/new.hbs @@ -1,6 +1,6 @@