Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | 4x 4x 4x 28x 4x 4x 4x 34x 34x 4x 30x 30x 6x 6x 6x 3x 3x 9x 9x 9x 9x 9x 3x 3x 3x 3x 7x 119x 119x 14x 105x 105x 105x 3x 1x 1x 2x 34x 34x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x | import BaseController from "./BaseController";
import Input from "sap/m/Input";
import Select from "sap/m/Select";
import JSONModel from "sap/ui/model/json/JSONModel";
import MessageToast from "sap/m/MessageToast";
import Event from "sap/ui/base/Event";
import { CURRENT_STATUS_VALUES } from "../model/currentStatus";
import { PamProduct } from "../model/productKey";
/** Maps each form control's view id to the PAM field it edits, mirroring the product detail page's fields. */
const FORM_FIELDS: Array<{ id: string; path: string }> = [
{ id: "addProductVersion", path: "version" },
{ id: "addProductName", path: "name" },
{ id: "addProductProduct", path: "product" },
{ id: "addProductLine", path: "line" },
{ id: "addProductCategory", path: "category" },
{ id: "addProductAddOn", path: "addOn" },
{ id: "addProductStatus", path: "status" },
{ id: "addProductRaPuna", path: "ra_puna" },
{ id: "addProductRaPua", path: "ra_pua" },
{ id: "addProductUa", path: "ua" },
{ id: "addProductHanaStatus", path: "hanaStatus" },
{ id: "addProductHanaDate", path: "hanaDate" },
{ id: "addProductEomm", path: "eomm" },
{ id: "addProductEom", path: "eom" },
{ id: "addProductEop1", path: "eop1" },
{ id: "addProductEosk", path: "eosk" },
{ id: "addProductUrl", path: "url" }
];
/** Form control ids that must have a value before the product can be saved. */
const REQUIRED_FIELD_IDS: string[] = [
"addProductVersion",
"addProductName",
"addProductEomm"
];
/**
* @namespace de.itsfullofstars.sap.pam.controller
*/
export default class MyProductsAdd extends BaseController {
/** Sets up the status dropdown's options and wires the route handler that resets the form. */
public onInit(): void {
const statusOptionsModel = new JSONModel([
{ key: "", text: this.getText("myProducts.notSpecified") },
...CURRENT_STATUS_VALUES.map((value) => ({ key: value, text: value }))
]);
this.setModel(statusOptionsModel, "statusOptions");
this.getRouter()
.getRoute("myproductsadd")
?.attachPatternMatched(this.onRouteMatched.bind(this));
}
/** Resets the (possibly still-filled) form whenever this route is (re-)entered. */
private onRouteMatched(): void {
this.resetForm();
}
/** Reads one form control's current value, trimmed. */
private getControlValue(id: string): string {
const control = this.byId(id);
if (control instanceof Select) {
return control.getSelectedKey().trim();
}
Eif (control instanceof Input) {
return control.getValue().trim();
}
return "";
}
/** Clears a required Input's error state as soon as it has a value again. */
public onRequiredFieldChange(event: Event): void {
const input = event.getSource<Input>();
Eif (input.getValue().trim()) {
input.setValueState("None");
}
}
/**
* Validates the required fields (see {@link REQUIRED_FIELD_IDS}),
* marking empty ones with an inline error.
* @returns `true` if all required fields have a value
*/
private validateRequiredFields(): boolean {
let allValid = true;
let firstInvalidInput: Input | undefined;
REQUIRED_FIELD_IDS.forEach((id) => {
const input = this.byId(id) as Input;
const isEmpty = !input.getValue().trim();
input.setValueState(isEmpty ? "Error" : "None");
input.setValueStateText(this.getText("msg.fieldRequired"));
if (isEmpty) {
allValid = false;
firstInvalidInput ??= input;
}
});
firstInvalidInput?.focus();
return allValid;
}
/** Resets every form field back to blank/unselected and clears error states. */
private resetForm(): void {
FORM_FIELDS.forEach(({ id }) => {
const control = this.byId(id);
if (control instanceof Select) {
control.setSelectedKey("");
} else Eif (control instanceof Input) {
control.setValue("");
control.setValueState("None");
}
});
}
/**
* Validates and, on success, appends the form's values as a new entry
* to the "ownProducts" model, then returns to the MyProducts page.
*/
public onSave(): void {
if (!this.validateRequiredFields()) {
MessageToast.show(this.getText("msg.myProductsMissingRequiredFields"));
return;
}
const product = FORM_FIELDS.reduce<PamProduct>((entry, field) => {
entry[field.path] = this.getControlValue(field.id);
return entry;
}, {});
/*
* MyProducts' and SupportStatus' tables only ever render rows from
* the "pam" model (filtered down to the user's own-products
* selection) - a manually created product needs a row there too,
* or it would be saved into "ownProducts" yet never show up
* anywhere. It is appended, never inserted, so it doesn't shift the
* index-based productdetail/{index} route of any existing entry.
*/
const pamModel = this.getOwnerComponent().getModel("pam") as JSONModel;
const pamData = pamModel.getData() as PamProduct[] | undefined;
const existingPamProducts = Array.isArray(pamData) ? pamData : [];
pamModel.setData([...existingPamProducts, product]);
const ownProductsModel = this.getOwnerComponent().getModel("ownProducts") as JSONModel;
const ownProducts = ownProductsModel.getData() as PamProduct[] | undefined;
const existingOwnProducts = Array.isArray(ownProducts) ? ownProducts : [];
ownProductsModel.setData([...existingOwnProducts, { ...product }]);
this.resetForm();
MessageToast.show(this.getText("msg.productAddedToOwnProducts"));
this.navTo("myproducts");
}
/** Discards the form and returns to the MyProducts page. */
public onCancel(): void {
this.resetForm();
this.navTo("myproducts");
}
}
|