diff --git a/Gemfile.lock b/Gemfile.lock index 17444cba3..bcb2eefb7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,17 +17,17 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.1.0) - aws-partitions (1.417.0) - aws-sdk-core (3.111.2) + aws-partitions (1.430.0) + aws-sdk-core (3.112.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.41.0) - aws-sdk-core (~> 3, >= 3.109.0) + aws-sdk-kms (1.42.0) + aws-sdk-core (~> 3, >= 3.112.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.87.0) - aws-sdk-core (~> 3, >= 3.109.0) + aws-sdk-s3 (1.89.0) + aws-sdk-core (~> 3, >= 3.112.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) aws-sigv4 (1.2.2) @@ -86,9 +86,9 @@ GEM domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) dotenv (2.7.6) - emoji_regex (3.2.1) + emoji_regex (3.2.2) escape (0.0.4) - excon (0.78.1) + excon (0.79.0) faraday (1.3.0) faraday-net_http (~> 1.0) multipart-post (>= 1.2, < 3) @@ -99,8 +99,8 @@ GEM faraday-net_http (1.0.1) faraday_middleware (1.0.0) faraday (~> 1.0) - fastimage (2.2.1) - fastlane (2.172.0) + fastimage (2.2.3) + fastlane (2.176.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.3, < 3.0.0) artifactory (~> 3.0) @@ -124,6 +124,7 @@ GEM jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) multipart-post (~> 2.0.0) + naturally (~> 2.2) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) @@ -148,7 +149,7 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.0) signet (~> 0.12) - google-apis-core (0.2.0) + google-apis-core (0.2.1) addressable (~> 2.5, >= 2.5.1) googleauth (~> 0.14) httpclient (>= 2.8.1, < 3.0) @@ -157,9 +158,10 @@ GEM retriable (>= 2.0, < 4.0) rexml signet (~> 0.14) + webrick google-apis-iamcredentials_v1 (0.1.0) google-apis-core (~> 0.1) - google-apis-storage_v1 (0.1.0) + google-apis-storage_v1 (0.2.0) google-apis-core (~> 0.1) google-cloud-core (1.5.0) google-cloud-env (~> 1.0) @@ -175,7 +177,7 @@ GEM google-cloud-core (~> 1.2) googleauth (~> 0.9) mini_mime (~> 1.0) - googleauth (0.14.0) + googleauth (0.15.1) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -223,7 +225,7 @@ GEM ruby2_keywords (0.0.4) rubyzip (2.3.0) security (0.1.3) - signet (0.14.0) + signet (0.14.1) addressable (~> 2.3) faraday (>= 0.17.3, < 2.0) jwt (>= 1.5, < 3.0) @@ -250,6 +252,7 @@ GEM unf_ext unf_ext (0.0.7.7) unicode-display_width (1.7.0) + webrick (1.7.0) word_wrap (1.0.0) xcodeproj (1.19.0) CFPropertyList (>= 2.3.3, < 4.0) diff --git a/Rakefile b/Rakefile index 84ebbd45a..4e5a06a6e 100755 --- a/Rakefile +++ b/Rakefile @@ -103,7 +103,7 @@ namespace :cordova do if platform == 'android' sh %{ cordova plugin add phonegap-plugin-push@2.1.2 } else - sh %{ cordova plugin add phonegap-plugin-push@1.9.2 --variable SENDER_ID="XXXXXXX" } + sh %{ cordova plugin add phonegap-plugin-push@2.3.0 --variable SENDER_ID="XXXXXXX" } end build = (environment == "staging" && platform == 'android') ? "debug" : "release" extra_params = (platform === "android") ? '' : ios_build_config diff --git a/app/components/add-edit-message-overlay.js b/app/components/add-edit-message-overlay.js new file mode 100644 index 000000000..4cc3754f3 --- /dev/null +++ b/app/components/add-edit-message-overlay.js @@ -0,0 +1,61 @@ +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 didReceiveAttrs() { + const editMessage = this.get("messageService.editMessage"); + const store = this.get("store"); + const message = + store.peekRecord("canned_response", editMessage.messageId) || + store.createRecord("canned-response"); + this.set("message", message); + this.set("isEnglish", true); + }, + + disableCreateEdit: Ember.computed( + "message.nameEn", + "message.contentEn", + function() { + return !(this.get("message.nameEn") && this.get("message.contentEn")); + } + ), + + actions: { + createCannedMessage() { + this.runTask( + this.get("message") + .save() + .then(() => this.set("messageService.isAddMessageVisible", false)) + ); + }, + + closeOverlay() { + this.set("messageService.isAddMessageVisible", false); + this.set("messageService.editMessage.language", "en"); + this.set("messageService.editMessage.messageId", ""); + }, + + setLanguage(lang = "en") { + this.set("isEnglish", lang == "en"); + }, + + deleteMessage() { + const store = this.get("store"); + const message = store.peekRecord( + "canned_response", + this.get("message").id + ); + this.runTask( + message.destroyRecord().then(() => { + store.unloadRecord(message); + this.set("messageService.isAddMessageVisible", false); + }), + ERROR_STRATEGIES + ); + } + } +}); diff --git a/app/components/canned-messages-overlay.js b/app/components/canned-messages-overlay.js index 304d58c8e..bf0ac95d4 100644 --- a/app/components/canned-messages-overlay.js +++ b/app/components/canned-messages-overlay.js @@ -18,12 +18,25 @@ export default Ember.Component.extend({ return this.get("searchText") && this.get("searchText").trim().length; }), + refreshDisplayResult: Ember.observer( + "messageService.isAddMessageVisible", + function() { + if (!this.get("messageService.isAddMessageVisible")) { + this.reloadResults(); + } + } + ), + actions: { loadMoreCannedMessages() { const params = { searchText: this.get("searchText") }; return this.get("store").query("canned_response", params); }, + openProFormaOverlay() { + this.set("messageService.isProFormaMessageVisible", true); + }, + setCannedResponse(text) { if (!text) return; const onSelect = this.getWithDefault("onSelect", _.noop); diff --git a/app/components/let-alias.js b/app/components/let-alias.js new file mode 100644 index 000000000..56268b039 --- /dev/null +++ b/app/components/let-alias.js @@ -0,0 +1,20 @@ +import Ember from "ember"; + +/** + * @module Components/let-alias + * @description Small helper component allowing to rename variables within the .hbs file + * @example + * + * {{#let-alias model.someReallyLongPropertyName as |short| }} + *
This is {{short}}
+ *
I can use {{short}} many times {{short}}
+ *
because it's very {{short}}
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") + }; + return this.get("store").query("canned_response", params); + }, + + addMessage() { + this.set("messageService.isAddMessageVisible", true); + }, + + closeOverlay() { + this.set("messageService.isProFormaMessageVisible", false); + }, + + editMessage(message, lang) { + this.set("messageService.editMessage.messageId", message.id); + this.set("messageService.editMessage.language", lang); + this.send("addMessage"); + }, + + cancel() { + this.set("open", false); + } + } +}); diff --git a/app/components/receive-menu.js b/app/components/receive-menu.js index 15c96d95f..700c7773c 100644 --- a/app/components/receive-menu.js +++ b/app/components/receive-menu.js @@ -15,6 +15,14 @@ export default Ember.Component.extend(AsyncTasksMixin, { isReceived: Ember.computed.equal("package.state", "received"), isMissing: Ember.computed.equal("package.state", "missing"), + isReceivedWithoutInventory: Ember.computed( + "package", + "isReceived", + function() { + return this.get("isReceived") && !this.get("package.inventoryNumber"); + } + ), + allowLabelPrint: Ember.computed( "isReceived", "package.inventoryNumber", @@ -157,6 +165,18 @@ export default Ember.Component.extend(AsyncTasksMixin, { } }, + inventorizeReceivedItem() { + this.get("messageBox").confirm( + this.get("i18n").t("receive.inventorize_warning"), + () => { + this.get("router").transitionTo( + "receive_package", + this.get("packageId") + ); + } + ); + }, + applyReceiving(event, allow_event = true) { if (!this.get("isFirstReceivingPackage") && allow_event) { return this.send(event); diff --git a/app/controllers/application.js b/app/controllers/application.js new file mode 100644 index 000000000..3a58115ec --- /dev/null +++ b/app/controllers/application.js @@ -0,0 +1,59 @@ +import config from "../config/environment"; + +export default Ember.Controller.extend({ + cordova: Ember.inject.service(), + subscriptions: Ember.inject.controller(), + messageService: Ember.inject.service(), + isMobileApp: config.cordova.enabled, + config, + + app_id: config.APP.ANDROID_APP_ID, + ios_app_id: config.APP.IOS_APP_ID, + appTitle: config.APP.TITLE, + bannerImage: config.APP.BANNER_IMAGE, + + initSubscriptions: Ember.on("init", function() { + if (this.session.get("isLoggedIn")) { + this.send("setSubscriptions"); + } + }), + + supportGCLink: Ember.computed("session.language", function() { + return this.get("session.language") === "zh-tw" + ? "https://www.crossroads.org.hk/zh-hant/home/donate-funds/" + : "https://www.crossroads.org.hk/home/donate-funds/"; + }), + + appVersion: Ember.computed(function() { + return config.cordova.enabled ? config.APP.VERSION : null; + }), + + actions: { + logMeOut() { + this.session.clear(); // this should be first since it updates isLoggedIn status + this.get("subscriptions").send("unwire"); + this.get("subscriptions").send("unloadNotifications"); + this.store.unloadAll(); + var _this = this; + config.APP.PRELOAD_TYPES.forEach(function(type) { + _this.store.findAll(type); + }); + this.transitionToRoute("login"); + }, + + logMeIn() { + this.send("setSubscriptions"); + }, + + setSubscriptions() { + this.get("subscriptions").send("wire"); + }, + + rateApp() { + if (this.get("cordova").isIOS()) { + this.set("app_id", this.get("ios_app_id")); + } + LaunchReview.launch(this.get("app_id")); + } + } +}); diff --git a/app/controllers/message_base_controller.js b/app/controllers/message_base_controller.js index bfc6a550d..2e2ae162d 100644 --- a/app/controllers/message_base_controller.js +++ b/app/controllers/message_base_controller.js @@ -59,14 +59,13 @@ export default Ember.Controller.extend({ this.get("recipientId") || (this.get("isPrivate") ? null : this.get("offer.createdById")); - if (recipientId) { - messages = messages.filter(m => { - return ( - m.get("recipientId") === recipientId || - m.get("senderId") === recipientId - ); - }); - } + messages = messages.filter(m => { + return ( + recipientId && + (m.get("recipientId") === recipientId || + m.get("senderId") === recipientId) + ); + }); return messages.filter(m => { return Boolean(m.get("isPrivate")) === this.get("isPrivate"); diff --git a/app/controllers/my_notifications.js b/app/controllers/my_notifications.js index aa5646bb8..d082d5bbe 100644 --- a/app/controllers/my_notifications.js +++ b/app/controllers/my_notifications.js @@ -183,8 +183,9 @@ export default Ember.Controller.extend({ const donorId = message.get("offer.createdById"); return ( - message.get("senderId") !== donorId && - message.get("recipientId") !== donorId + !donorId || + (message.get("senderId") !== donorId && + message.get("recipientId") !== donorId) ); }, @@ -235,6 +236,9 @@ export default Ember.Controller.extend({ const messageId = notification.get("id"); var message = this.store.peekRecord("message", messageId); var route = this.get("messagesUtil").getRoute(message); + if (message.get("messageableType") === "Item") { + route[1] = message.get("item.offer.id"); + } this.transitionToRoute.apply(this, route); } }, diff --git a/app/controllers/receive_package.js b/app/controllers/receive_package.js index e1ec937a4..022c15882 100644 --- a/app/controllers/receive_package.js +++ b/app/controllers/receive_package.js @@ -398,22 +398,11 @@ export default Ember.Controller.extend(AsyncTasksMixin, { pkgUpdateError(pkg) { const errorMessage = pkg.get("errors.firstObject.message") || - pkg.get("adapterError.errors.firstObject.title"); - if ( - errorMessage === "Adapter Error" || - errorMessage.indexOf("Connection error") >= 0 - ) { - this.get("messageBox").alert( - "could not contact Stockit, try again later.", - () => pkg.rollbackAttributes() - ); - } else { - this.get("messageBox").alert( - pkg - .get("errors") - .getEach("message") - .join("\n") - ); + pkg.get("adapterError.errors.firstObject.detail.errors.firstObject"); + + if (errorMessage) { + pkg.rollbackAttributes(); + this.get("messageBox").alert(errorMessage); } } } diff --git a/app/controllers/review_offer.js b/app/controllers/review_offer.js index 5cace66ef..e6ec32d0f 100644 --- a/app/controllers/review_offer.js +++ b/app/controllers/review_offer.js @@ -97,6 +97,17 @@ export default Ember.Controller.extend(AsyncTasksMixin, { } }), + deleteOffer(offer, path = this.get("backLinkPath")) { + this.set("cancelByMe", true); + this.runTask(offer.destroyRecord()) + .then(() => this.transitionToRoute(path)) + .catch(error => { + offer.rollbackAttributes(); + throw error; + }) + .finally(() => this.set("cancelByMe", false)); + }, + actions: { toggleOfferOptions() { this.toggleProperty("displayOfferOptions"); @@ -133,25 +144,36 @@ export default Ember.Controller.extend(AsyncTasksMixin, { deleteOffer() { this.send("toggleOfferOptions"); - var offer = this.get("model"); + const offer = this.get("model"); this.get("messageBox").custom( this.get("i18n").t("delete_confirm"), this.get("i18n").t("review_offer.options.yes"), () => { - this.set("cancelByMe", true); - this.runTask(offer.destroyRecord()) - .then(() => this.transitionToRoute(this.get("backLinkPath"))) - .catch(error => { - offer.rollbackAttributes(); - throw error; - }) - .finally(() => this.set("cancelByMe", false)); + this.deleteOffer(offer); }, this.get("i18n").t("review_item.not_now"), null ); }, + transitionTo(path) { + const offer = this.get("model"); + const items = offer.get("items"); + if (!items.length) { + this.get("messageBox").custom( + this.get("i18n").t("review_offer.empty_offer_message"), + this.get("i18n").t("review_offer.options.yes"), + () => { + this.deleteOffer(offer, path); + }, + this.get("i18n").t("review_item.not_now"), + null + ); + } else { + this.transitionToRoute(path); + } + }, + reopenOffer() { this.runTask(async () => { await this.get("offerService").reopenOffer(this.get("model")); diff --git a/app/controllers/review_offer/share/index.js b/app/controllers/review_offer/share/index.js index 0d9163222..644d32158 100644 --- a/app/controllers/review_offer/share/index.js +++ b/app/controllers/review_offer/share/index.js @@ -23,7 +23,6 @@ export default Ember.Controller.extend(AsyncTasksMixin, { "allMessages.length", "allMessages.@each.{senderId,recipientId}", function() { - const donorId = this.get("offer.createdById"); return this.get("allMessages") .filterBy("offerId", this.get("offer.id")) .filter(m => @@ -141,7 +140,7 @@ export default Ember.Controller.extend(AsyncTasksMixin, { const t = k => this.get("i18n").t(k); const district = this.getWithDefault( "offer.createdBy.address.district.name", - "N/A" + "Hong Kong" ); const lines = [ `${t("review_offer.donor.district")}: ${district}`, diff --git a/app/controllers/search.js b/app/controllers/search.js index e81797393..b43d8ec16 100644 --- a/app/controllers/search.js +++ b/app/controllers/search.js @@ -76,15 +76,18 @@ export default Ember.Controller.extend(backNavigator, { getFilterQuery() { const filterService = this.get("filterService"); const isPriority = filterService.isPriority(); + const isPublished = filterService.isPublished(); const { after, before } = filterService.get("offerTimeRange"); let stateFilters = _.without( filterService.get("offerStateFilters"), - "showPriority" + "priorityOffers", + "publishedOffers" ); return { state: utilityMethods.stringifyArray(stateFilters), priority: isPriority, + shareable: isPublished, after: after && after.getTime(), before: before && before.getTime() }; diff --git a/app/helpers/state-filter-icon.js b/app/helpers/state-filter-icon.js index a29938402..83bc7d5b8 100644 --- a/app/helpers/state-filter-icon.js +++ b/app/helpers/state-filter-icon.js @@ -3,6 +3,7 @@ import { STATE_FILTERS } from "../services/filter-service"; const { PRIORITY, + PUBLISHED, NEW, REVIEWING, REVIEWED, @@ -22,7 +23,8 @@ const STATE_ICONS = { [RECEIVED]: "thumbs-up", [CANCELLED]: "thumbs-down", [INACTIVE]: "bed", - [PRIORITY]: "warning" + [PRIORITY]: "warning", + [PUBLISHED]: "eye" }; export default Ember.Helper.helper(function(state) { diff --git a/app/locales/en/translations.coffee b/app/locales/en/translations.coffee index 3411052d5..81ce409e2 100644 --- a/app/locales/en/translations.coffee +++ b/app/locales/en/translations.coffee @@ -91,7 +91,7 @@ I18nTranslationsEn = month: "This month", next_month: "Next month" - show_priority_offers: "Only Show Priority Offers" + show_priority_offers: "Only Show ..." offer_statuses: "Offer Statuses" on_or_after: "On or after" on_or_before: "On or before" @@ -103,8 +103,10 @@ I18nTranslationsEn = time_filter_title: "Offer Due Date" button_state: "State" button_due: "Due" - showPriority: "Show Priority" - showPriority_info: "Have remained in a state too long. Need attention." + priorityOffers: "Priority Offers" + priorityOffers_info: "Have remained in a state too long. Need attention." + publishedOffers: "Published Offers" + publishedOffers_info: "Shared on charity site" submitted: "New" submitted_info: "Offers that have yet to be reviewed." under_review: "Reviewing" @@ -250,6 +252,7 @@ I18nTranslationsEn = "close_offer_summary": "This will close the offer." "add_note": "Tap to add/edit sticky note" "tap_to_save": "tap to save" + "empty_offer_message": "This offer is empty. Do you want to delete it?" "donor": "offer_id": "Offer ID" @@ -318,6 +321,7 @@ I18nTranslationsEn = "assign": "Assign" "select_package_image": "Choose the favourite image for this package:" + "reject": "select_type": "Please choose Item Type first!" "option_error": "Please choose a reason." @@ -353,6 +357,8 @@ I18nTranslationsEn = "not_now": "Not Now" "begin_receiving": "Begin Receiving" + "inventorize_warning": "Are you sure you want to inventorize?" + "finished": "title": "Finished" "received": "Received" @@ -471,5 +477,9 @@ I18nTranslationsEn = "canned_response": "title": "Manage pro-forma messages" - + "en_content": "English content cannot be blank" + "en_label": "English label be blank" + "delete_message": "Delete Message" + "label": "Label" + "message": "Message" `export default I18nTranslationsEn` diff --git a/app/locales/zh-tw/translations.coffee b/app/locales/zh-tw/translations.coffee index 807a92f15..9df74c124 100644 --- a/app/locales/zh-tw/translations.coffee +++ b/app/locales/zh-tw/translations.coffee @@ -91,7 +91,7 @@ I18nTranslationsZhTw = month: "This month", next_month: "Next month" - show_priority_offers: "Only Show Priority Offers" + show_priority_offers: "Only Show ..." offer_statuses: "Offer Statuses" on_or_after: "On or after" on_or_before: "On or before" @@ -102,8 +102,10 @@ I18nTranslationsZhTw = all_review: "All" time_filter_title: "Offer Due Date" button_state: "State" - showPriority: "Show Priority" - showPriority_info: "Have remained in a state too long. Need attention." + priorityOffers: "Priority Offers" + priorityOffers_info: "Have remained in a state too long. Need attention." + publishedOffers: "Published Offers" + publishedOffers_info: "Shared on charity site" submitted: "New" submitted_info: "Offers that have yet to be reviewed." under_review: "Reviewing" @@ -248,6 +250,7 @@ I18nTranslationsZhTw = "close_offer_summary": "這項捐贈項目將列為完成。" "add_note": "按下以增加/修改記事板" "tap_to_save": "按下以儲存" + "empty_offer_message": "這個捐贈沒有任何相關物資。你是否需要刪除" "donor": "offer_id": "捐贈項目號碼" @@ -349,7 +352,8 @@ I18nTranslationsZhTw = "header": "開始接收捐贈項目" "cant_modify_note": "提示:一旦捐贈項目狀態改成「正在接收」,將無法還原,捐贈人士亦無法更改物資資料。" "not_now": "現在無法進行" - "begin_receiving": "開始接收" + "begin_receiving": "開始接收", + "inventorize_warning": "Are you sure you want to inventorize?" "finished": @@ -470,5 +474,10 @@ I18nTranslationsZhTw = "canned_response": "title": "Manage pro-forma messages" + "en_content": "English content cannot be blank" + "en_label": "English label be blank" + "delete_message": "Delete Message" + "label": "Label" + "message": "Message" `export default I18nTranslationsZhTw` diff --git a/app/models/canned_response.js b/app/models/canned_response.js index cb32207a2..554720ee5 100644 --- a/app/models/canned_response.js +++ b/app/models/canned_response.js @@ -4,6 +4,7 @@ import attr from "ember-data/attr"; export default Model.extend({ name: attr("string"), nameEn: attr("string"), + nameZhTw: attr("string"), content: attr("string"), contentEn: attr("string"), contentZhTw: attr("string") diff --git a/app/models/message.js b/app/models/message.js index 262a07704..11b7b94ce 100644 --- a/app/models/message.js +++ b/app/models/message.js @@ -69,6 +69,10 @@ export default DS.Model.extend({ const donorId = this.get("offer.createdById"); + if (!donorId) { + return !this.get("isPrivate"); + } + // It's a chat with an external user (a charity) if: // - It's public // - It does not involve the donor diff --git a/app/routes/receive_package.js b/app/routes/receive_package.js index c5ab5bfc1..e1be58afa 100644 --- a/app/routes/receive_package.js +++ b/app/routes/receive_package.js @@ -36,7 +36,7 @@ export default AuthorizeRoute.extend({ model.get("inventoryNumber"); this.setupPrinterId(controller); - if (model.get("isReceived")) { + if (model.get("isReceived") && model.get("inventoryNumber")) { return controller.redirectToReceiveOffer(); } if (!model.get("inventoryNumber")) { diff --git a/app/routes/review_item.js b/app/routes/review_item.js index 837f42929..c76a117eb 100644 --- a/app/routes/review_item.js +++ b/app/routes/review_item.js @@ -1,26 +1,32 @@ -import AuthorizeRoute from './authorize'; +import AuthorizeRoute from "./authorize"; export default AuthorizeRoute.extend({ - editItemRequest: "", - beforeModel(){ + beforeModel() { var previousRoutes = this.router.router.currentHandlerInfos; var previousRoute = previousRoutes && previousRoutes.pop(); - if(previousRoute){ - var editItemRequest = ["review_offer.items", "review_offer.receive"].indexOf(previousRoute.name) >= 0; + if (previousRoute) { + var editItemRequest = + ["review_offer.items", "review_offer.receive"].indexOf( + previousRoute.name + ) >= 0; this.set("editItemRequest", editItemRequest); } }, model(params) { - return this.store.findRecord('item', params.item_id); + return this.store.findRecord("item", params.item_id); }, setupController(controller, model) { this._super(controller, model); + this.set( + "existingPackageType", + model.get("packageType") && model.get("packageType").id + ); - if((this.get("editItemRequest"))){ + if (this.get("editItemRequest")) { var itemDetails = { donorConditionId: model.get("donorConditionId"), donorDescription: model.get("donorDescription") diff --git a/app/services/filter-service.js b/app/services/filter-service.js index 8f1e766bd..73d38850e 100644 --- a/app/services/filter-service.js +++ b/app/services/filter-service.js @@ -24,7 +24,8 @@ const PERSISTENT_VAR = function(propName, defaultValue, deserializeMap = {}) { }; export const STATE_FILTERS = { - PRIORITY: "showPriority", + PRIORITY: "priorityOffers", + PUBLISHED: "publishedOffers", NEW: "submitted", REVIEWING: "under_review", REVIEWED: "reviewed", @@ -48,6 +49,11 @@ export default Ember.Service.extend(Ember.Evented, { return filters && filters.indexOf(STATE_FILTERS.PRIORITY) >= 0; }, + isPublished() { + const filters = this.get("offerStateFilters"); + return _.includes(filters, STATE_FILTERS.PUBLISHED); + }, + clearOfferStateFilters() { this.set("offerStateFilters", []); }, diff --git a/app/services/message-service.js b/app/services/message-service.js index 40c13ab3f..ceb29978a 100644 --- a/app/services/message-service.js +++ b/app/services/message-service.js @@ -5,10 +5,16 @@ import ApiBaseService from "./api-base-service"; export default ApiBaseService.extend({ store: Ember.inject.service(), + editMessage: { + language: "en", + messageId: "" + }, init() { this._super(...arguments); this.set("isCannedMessagesVisible", false); + this.set("isProFormaMessageVisible", false); + this.set("isAddMessageVisible", false); }, toggle() { diff --git a/app/styles/_filters.scss b/app/styles/_filters.scss index 1c5aa5242..976f59441 100644 --- a/app/styles/_filters.scss +++ b/app/styles/_filters.scss @@ -86,7 +86,7 @@ font-size: 1.2rem; float: right; @media #{$small-only} { - margin-right: 8.5rem !important; + margin-right: 7.5rem !important; } @media #{$medium-only} { margin-right: 22.2rem; diff --git a/app/styles/templates/_dashboard.scss b/app/styles/templates/_dashboard.scss index 98c6952b5..9523cdf61 100644 --- a/app/styles/templates/_dashboard.scss +++ b/app/styles/templates/_dashboard.scss @@ -78,7 +78,7 @@ justify-content: center; img { - height: -webkit-fill-available; + height: 89px; @media #{$small-only} { margin-left: -5%; diff --git a/app/styles/templates/components/_canned-messages-overlay.scss b/app/styles/templates/components/_canned-messages-overlay.scss index b6b0f68a8..388b45154 100644 --- a/app/styles/templates/components/_canned-messages-overlay.scss +++ b/app/styles/templates/components/_canned-messages-overlay.scss @@ -16,6 +16,19 @@ margin-left: 0%; } + .tabs { + width: 50%; + padding-left: 15%; + margin-left: -10%; + float: left; + padding-top: 2%; + padding-bottom: 2%; + cursor: pointer; + } + + .selected { + border-bottom: 2px solid #ddd; + } .search-field { flex: 0.8; } @@ -43,6 +56,80 @@ flex-direction: column; margin-top: 1.5rem; + i.edit-pointer { + font-size: 200%; + } + + .message-textarea { + background: #1A3A64; + border: 1px solid #002352; + color: #8496AE; + width: 98%; + font-size: 100%; + } + + .edit-message { + display: flex; + + + .disabled { + color: #bab3b3; + cursor: default; + } + + .input-error { + background: #f46769; + color: #fff; + padding: .2rem; + width: 98%; + margin-top: -5%; + margin-bottom: 5%; + } + } + + .create-btn{ + width: 50%; + margin-left: 30%; + } + + span.label { + flex: 1; + text-align: center; + } + + span.content { + flex: 5; + } + + .light-button { + border: 1px solid #fff; + max-width: 16rem; + height: 2rem; + text-align: center; + cursor: pointer; + color: #fff; + background: #002352; + float: right; + font-size: 100%; + padding-bottom: 2.5%; + padding-top: 1%; + padding-left: 5%; + padding-right: 5%; + margin-right: 25%; + + + @media #{$small-only} { + line-height: 2rem; + font-size: 120%; + padding-bottom: 7.5%; + padding-top: 0.5%; + padding-left: 7%; + padding-right: 7%; + position: relative; + margin-right: 5%; + } + } + li { margin-bottom: clamp(1rem, 5vw, 4rem); diff --git a/app/templates/_global_components.hbs b/app/templates/_global_components.hbs new file mode 100644 index 000000000..bc54c8e9e --- /dev/null +++ b/app/templates/_global_components.hbs @@ -0,0 +1,10 @@ +{{#let-alias messageService as |s|}} + {{pro-forma-message-overlay + open=s.isProFormaMessageVisible + }} + + {{add-edit-message-overlay + open=s.isAddMessageVisible + cannedMessageId=s.cannedMessageId + }} +{{/let-alias}} \ No newline at end of file diff --git a/app/templates/_state_filters.hbs b/app/templates/_state_filters.hbs index ee0f84422..e85f96d77 100644 --- a/app/templates/_state_filters.hbs +++ b/app/templates/_state_filters.hbs @@ -7,7 +7,12 @@
- {{offer-filter-checkbox name="showPriority"}} + {{offer-filter-checkbox name="priorityOffers"}} +
+
+
+
+ {{offer-filter-checkbox name="publishedOffers"}}

diff --git a/app/templates/components/add-edit-message-overlay.hbs b/app/templates/components/add-edit-message-overlay.hbs new file mode 100644 index 000000000..fcd5c7bda --- /dev/null +++ b/app/templates/components/add-edit-message-overlay.hbs @@ -0,0 +1,64 @@ +
+ {{#popup-overlay open=open}} + +
+ {{#if message.id}} +
+ +
+ {{/if}} +
+ + {{t 'canned_response.label'}}* +
+ EN | 中文 +
+
+ + {{#if isEnglish}} + {{textarea type='textarea' value=message.nameEn classNames="message-textarea" rows="5"}} + {{else}} + {{textarea type='textarea' value=message.nameZhTw classNames="message-textarea" rows="5"}} + {{/if}} + {{#unless message.nameEn}} +
{{t 'canned_response.en_label'}}
+ {{/unless}} +
+
+ +
+ + {{t 'canned_response.message'}}* +
+ EN | 中文 +
+
+ + {{#if isEnglish}} + {{textarea type='textarea' value=message.contentEn classNames="message-textarea" rows="10"}} + {{else}} + {{textarea type='textarea' value=message.contentZhTw classNames="message-textarea" rows="10"}} + {{/if}} + {{#unless message.contentEn}} +
{{t 'canned_response.en_content'}}
+ {{/unless}} +
+
+ + + +
+ + + {{/popup-overlay}} +
\ No newline at end of file diff --git a/app/templates/components/canned-messages-overlay.hbs b/app/templates/components/canned-messages-overlay.hbs index 80758df66..4501e85b5 100644 --- a/app/templates/components/canned-messages-overlay.hbs +++ b/app/templates/components/canned-messages-overlay.hbs @@ -19,9 +19,10 @@
-
+
{{t 'canned_response.title'}}
+ {{#if displayResults}} {{#infinite-list height="82vh" loadMore=(action "loadMoreCannedMessages") as |cannedMessages| }}
+ {{else if isReceivedWithoutInventory}} +
+ + {{t "receive.inventory"}} +
{{else}} -
- - {{t "receive.inventory"}} -
+
+ + {{t "receive.inventory"}} +
{{/if}}