UNPKG

product-admin

Version:

EA admin screens

359 lines (313 loc) 11.5 kB
<link rel="import" href="../admin-shared-styles/admin-shared-styles.html" /> <link rel="import" href="./edit-product-styles.html" /> <link rel="import" href="../bms-behaviors-util/bms-behaviors-util.html" /> <dom-module id="edit-product"> <template> <style include="admin-shared-styles"></style> <style include="edit-product-styles"></style> <px-modal id="pxModalContainer" modal-id="editCreateProductModal" modal-heading="[[ localizedHeading ]]" btn-modal-positive="[[ localize('btnCreateEditPositive') ]]" btn-modal-negative="[[ localize('btnCreateEditNegative') ]]" btn-modal-positive-disabled="{{!isFormValid}}" > <!-- This will be updated imperetively on #attached if isCreate @method POST | PUT @url "/updateProduct/[[ id ]]" | "/createProduct" --> <iron-ajax method="[[ productApiRequestMethod ]]" id="productApiRequest" url="[[ productApiRequestUrl ]]" handle-as="json" headers='{ "accept": "application/json" }' content-type="application/json" on-response="_handleProductApiSuccess" on-error="_handleProductApiError" body="[[ product ]]" loading="{{loading}}" ></iron-ajax> <form name="edit-create-form" id="editCreateForm"> <label for$="productDescription" class="label--inline">[[ localize("productDescription") ]]</label> <input placeholder="[[ localize('productDescription') ]]" id="productDescription" type="text" class="text-input input--tiny" value="{{product.productDescription::input}}" pattern=".{0,255}" /> <label for$="productCode" class="label--inline">[[ localize("productCode") ]]</label> <input placeholder="[[ localize('productCode') ]]" id="productCode" type="text" class="text-input input--tiny" readonly$="{{!isCreate}}" value="{{product.productCode::input}}" required pattern=".{1,255}" on-input="_validateField" /> <hr /> <label for$="productLongDescription">[[ localize("productLongDescription") ]] <span class="label--light">[[ localize("productDescriptionParen") ]]</span></label> <div placeholder='[[ localize("productLongDescription") ]]' id="longDescription" class="textarea--long-description" name="longDescription" contenteditable="true" value="{{ product.longDescription }}" pattern=".{0,150}" on-input="_validateField" ></div> <hr /> <label for$="currentSpecificationRate" class="label--inline">[[ localize("currentSpecificationRate") ]]</label> <input class="text-input input--tiny" placeholder="[[ localize('currentSpecificationRate') ]]" id="currentSpecificationRate" type="number" pattern="[0-9.]{0,8}" on-input="_validateField" step="0.001" min="0" max="9999999999999999" value="{{product.currentSpecificationRate::input}}" /> <label for$="currentSpecificationRate" class="label--inline label--light label--space-right-large">[[ localize("currentSpecificationRateLabel") ]]</label> <wbr /> <label for="estCycleTimeHours" class="label--inline label--space-right-small">{{ localize("estCycleTime") }}</label> <input class="text-input text-input--four-char" type="number" min="0" max="9999" pattern="[0-9]{0,255}" on-input="_validateField" step="1" id="estCycleTimeHours" placeholder="0" type="number" maxlength="4" value="{{product.estCycleTimeHours::input}}" /> <label for$="estCycleTimeHours" class="label--inline label--light label--space-right-medium label--space-left-small">[[ localize("hours") ]]</label> <wbr /> <input class="text-input text-input--two-char" type="number" min="0" maxlength="2" pattern="[0-9]{0,255}" step="1" id="estCycleTimeMinutes" type="number" placeholder="0" on-input="_validateField" value="{{ product.estCycleTimeMinutes::input }}" /> <label for$="estCycleTimeMinutes" on-input="_validateField" class="label--inline label--light label--space-left-small">[[ localize("minutes") ]]</label> <template is="dom-if" if="{{ showUnitsSection }}"> <hr /> <label>{{ localize("produceOnUnits") }}</label> </template> <section class="section--scrollable"> <template is="dom-repeat" id="produceOnUnitsId" items="{{ assets }}" initialCount="24"> <div class="container--col__units"> <paper-checkbox checked$="{{item.selected}}" value="[[ item.value ]]" on-change="_changeAssetSelection" class="checkbox__unit" id="asset-[[ item.value ]]" ></paper-checkbox> <label class="label--inline label__checkbox--unit" for$="asset-[[ item.value ]]" on-tap="_selectCorrespondingCheckbox">[[ item.name ]]</label> </div> </template> </section> </form> </px-modal> </template> </dom-module> <script> (function (Polymer, util, undefined) { "use strict"; Polymer({ is: 'edit-product', behaviors: [ Polymer.AppLocalizeBehavior, bms.behaviors.util // TODO: create validations behavior or add to util ], properties: { isCreate: { type: Boolean, value: false }, isFormValid: { type: Boolean, value: false }, product: { type: Object, value: function () { return { productDescription: "", longDescription: "", productCode: "", currentSpecificationRate: 0, estCycleTimeHours: 0, estCycleTimeMinutes: 0, assets: [], specifications: [] }; } }, assets: Array, // units productApiRequestUrl: String, productApiRequestMethod: String, baseUrl: { type: String, readOnly: true, value: function () { return util.properties.BASE_PATH.value; } } }, attached: attached, _handleProductApiSuccess: _handleProductApiSuccess, _handleProductApiError: _handleProductApiError, _btnModalPositiveClicked: _btnModalPositiveClicked, _changeAssetSelection: _changeAssetSelection, _hasDisplayAssets: _hasDisplayAssets, _updateLocalization: _updateLocalization, _selectCorrespondingCheckbox: _selectCorrespondingCheckbox, _validateField: _validateField, refresh: refresh, listeners: { btnModalPositiveClicked: "_btnModalPositiveClicked", refresh: "refresh" }, observers: [ "_updateLocalization(resources.*)", ], }); function _validateField (event) { var field = event.target; if (field.id === "longDescription") { if (field.innerHTML.length < 150) return; return field.innerHTML = field.innerHTML.slice(-150); } var isValid = field.validity.valid; if (!isValid) { this.isFormValid = false; field.reportValidity(); } else { this.isFormValid = this.$.editCreateForm.checkValidity(); } } function refresh () { // INITIALIZE MODAL HERE // loop smaller or larger array first? // [1, 2, 3] ... [1, 5, 6, 7, 8, 9, 10, 2, 3] // how many times does it loop the entire larger array? smaller? // cycles? this.$.longDescription.innerHTML = this.product.longDescription; this.showUnitsSection = this.assets && this.assets.length > 0; if (this.assets) { this.assets.forEach(function (asset) { asset.selected = false; checkboxDisplayControl.call(this, asset.value, false); }, this); } this.product = Object.assign(this.product, { assets: this.product.assets || [], estCycleTimeMinutes: this.product.estCycleTimeMinutes || 0, estCycleTimeHours: this.product.estCycleTimeHours || 0, currentSpecificationRate: this.product.currentSpecificationRate || 0 }); this.product.assets.forEach(function (selectedAssetId) { for (var i = 0; i < this.assets.length; i += 1) { if (this.assets[i].value !== selectedAssetId) continue; this.assets[i].selected = true; } checkboxDisplayControl.call(this, selectedAssetId, true); }, this); this.isFormValid = this.$.editCreateForm.checkValidity(); if (!this.isFormValid) this.$.editCreateForm.reportValidity(); function checkboxDisplayControl (elementValue, toggle) { var checkbox = this.$$("#asset-" + elementValue); if (!checkbox) return; if (toggle) checkbox.setAttribute("checked", true); else checkbox.removeAttribute("checked"); } } function _updateLocalization () { var resources = this.resources[this.language]; if (!resources) { this.language = "en"; resources = this.resources.en; } this.localizedHeading = this.isCreate? resources.headingCreate: resources.headingEdit; } function _hasDisplayAssets () { return this.assets && this.assets.length > 0; } function attached () { this.isCreate = this.isCreate === (true || "true"); } function _selectCorrespondingCheckbox (ev) { var id = ev.target.getAttribute("for"); var checkbox = this.$$("#" + id); checkbox.checked = !checkbox.checked; checkbox.fire("change"); // #_changeAssetSelection } function _changeAssetSelection (ev) { if (ev.target.checked) { addToRequestBodyAssets.call(this, ev.target); } else { removeFromRequestBodyAssets.call(this, ev.target); } } function _btnModalPositiveClicked (e) { if (this.isCreate) { this.productApiRequestUrl = this.baseUrl.concat("/createProduct"); this.productApiRequestMethod = "POST"; } else { this.productApiRequestUrl = this.baseUrl.concat("/updateProduct/", this.product.pk); this.productApiRequestMethod = "PUT"; } var form = this.$.editCreateForm; if (!form.checkValidity()) return form.reportValidity(); this.product.longDescription = cleanHtml(this.$.longDescription.innerHTML).slice(0, 150); //TODO: I am not a big fan of data manipulation in what we are trying to do here. If there is a cleaner approach that will satisfy both edit-product and product-table-view, lets refactor it. for now, this works for drop2. this.product.currentSpecificationCycleTime = util.convertHrMinToCycleTime(this.product.estCycleTimeHours, this.product.estCycleTimeMinutes); this.$.productApiRequest.generateRequest(); } function _handleProductApiSuccess (response) { response = response.detail.__data__.response; this.product = response; if (this.isCreate) { this.fire("createProduct", this.product); } else { this.fire("updateProduct", this.product); } } function _handleProductApiError (errResponse) { errResponse.messageTitle = this.localize("error"); errResponse.errorMessage = this.localize("editProductError"); this.fire('alert-error-message', errResponse) console.error("Failed to get response", errResponse); } function addToRequestBodyAssets (unit) { this.push("product.assets", unit.value); } function removeFromRequestBodyAssets (unit) { var unitIndex = this.product.assets.indexOf(unit.value); this.splice("product.assets", unitIndex, 1); } function cleanHtml (innerHtml) { innerHtml = innerHtml || ""; var tmp = document.createElement("DIV"); var regexp = new RegExp("(<\/?div>|<br\s*\/?>)", "gi"); tmp.innerHTML = innerHtml.replace(regexp, " \n"); return tmp.textContent || tmp.innerText || " "; } })(Polymer, bms.behaviors.util); </script>