!7 set flag NoNanoHTTPD. concept BEAObject { } module /*cmodule2*/ GazelleBEA > DynGazelleRocks { void init { super.init(); botName = heading = adminName = "Gazelle BEA"; set enableVars; set showTalkToBotLink; unset phoneNumberSpecialInputField; } L crudClasses(Req req) { ret listPlus(super.crudClasses(req), BEAObject); } S authFormHeading() { ret h3("Gazelle BEA"); } void makeFramer(Req req) { super.makeFramer(req); req.framer.renderTitle = () -> h1(ahref(baseLink + "/", "Gazelle BEA") + " " + htmlEncode2(req.framer.title)); } HCRUD_Concepts crudData(Class c, Req req) { HCRUD_Concepts cc = super.crudData(c, req); if (c == BEAObject) { cc.convertConceptValuesToRefs = true; cc.itemName = () -> "BEA Object"; cc.getObjectForDuplication = id -> { MapSO item = cc.getObjectForDuplication_base(id); item.put(creator := req.auth.user!); // set default creator to current user item.put(createdFrom := getConcept(toLong(id))); ret item; }; } ret cc; } HCRUD makeCRUD(Class c, Req req, HTMLFramer1 framer) { HCRUD crud = super.makeCRUD(c, req, framer); if (c == BEAObject) { HCRUD_Concepts cc = cast crud.data; crud.massageFormMatrix = (map, matrix) -> { assertNull("moreSelectizeOptions", crud.moreSelectizeOptions); crud.moreSelectizeOptions = name -> !eq(name, "newField_type") ? null : [[, onChange: function(value) { $("[name=newField_value]").toggle(value == "String"); $("[name=newField_conceptValue]").toggle(value == "BEAObject"); } }]]; S refSelector = crud.renderInput("newField_conceptValue", cc.makeConceptsComboBox("newField_conceptValue", BEAObject), null); matrix.add(ll("Add field", htmlTable2_noHtmlEncode(ll( ll("Name", htextfield newField_name(), "Value", // string input htextfield newField_value(), refSelector, "Type", crud.renderComboBox("newField_type", "String", ll("String", "BEAObject"), false) )), noHeader := true))); }; crud.preprocessUpdateParams = params -> { params = cloneMap(params); S name = params.get("newField_name"), type = params.get("newField_type"), refValue = params.get("newField_conceptValue"), value = params.get("newField_value"); if (eq(type, "BEAObject")) { value = refValue; params.put("metaInfo_" + name, "concept"); } if (eq(value, "")) value = null; if (nempty(name) /*&& neqOneOf(value, null, "")*/) params.put(crud.fieldPrefix + name, value); ret params; }; } ret crud; } O serveBotFunction(Req req, S function, Map data, User user) { if (eq(function, "beaList")) { long changedAfter = toLong(data.get("changedAfter")); double pollFor = min(bot_maxPollSeconds, toLong(data.get("pollFor"))); // how long to poll (seconds) long startTime = sysNow(); // We're super-anal about catching all changes. This will probably never trigger if (changedAfter > 0 && changedAfter == now()) sleep(1); Cl objects; while true { objects = changedAfter == 0 ? list(BEAObject) : conceptsWithFieldGreaterThan_sorted(BEAObject, _modified := changedAfter); // return when there are results, no polling or poll expired if (nempty(objects) || pollFor == 0 || elapsedSeconds_sysNow(startTime) >= pollFor) ret serveJSON_breakAtLevels(2, result := map(objects, obj -> litmap(id := obj.id) // TODO )); // sleep and try again sleep(bot_pollInterval); } } ret super.serveBotFunction(req, function, data, user); } } // end of module