// module: TRUE
// @ts-ignore
import { gui } from "./pre_entities_of_interest_gui.jsi";
let workflow_filename = Workflow.WorkflowDefinitionFilename();
let m; // the model that is selected in the set up function
let entities_of_interest = []; //object for storing data to go into the .JSON
let entityID; // When selecting entities, the ID of the selected parts
let widgetItemNumberForEdit; // When editing an entry, this holds the widget item number that is being edited
/**
* @typedef {Object} EntityOfInterest
* @property {string} name
* @property {string[]} parts
* @property {String} type
* @property {String[]} partsOfEntity
*/
/**
* The data object in the workflow file
* @typedef {Object} data
* @property {EntityOfInterest[]} entities_of_interest
*/
/** @type {data} */
let data;
set_up();
/* Show the first window "Window1" */
if (gui) gui.Window1.Show(false);
/**
* Sets up the window with callback functions from the GUI, selects the model to be used and fills the WidgetItems for the entity type combobox
*/
function set_up() {
// Selecting the model to use if there are multiple ones open in PRIMER
gui.model = Model.Select("Select the model to use");
if (gui.model == null) {
Window.Information("", "You need to select a model before you can use this workflow");
Exit();
}
m = gui.model;
// Reading in any previously saved data
let numModels = Workflow.NumberOfModels();
for (let i = 0; i < numModels; i++) {
let modelID = Workflow.ModelIdFromIndex(i);
if (modelID != gui.model.number) {
continue;
}
/** @type {data} */
// @ts-ignore
data = Workflow.ModelUserDataFromIndex(i);
try {
for (let i = 0; i < data.entities_of_interest.length; i++) {
let entityName = data.entities_of_interest[i].name.toString();
let entityType = data.entities_of_interest[i].type.toString();
entityID = data.entities_of_interest[i].parts.toString();
// Adds the entry to the listbox and sets the hover value to the entities
let newEntry = new WidgetItem(gui.Window1.lbEntity, entityName + " | " + entityType + " | " + entityID);
newEntry.hover = entityID;
// If the entry is a part set then finds the parts in the part set and saves it to partsInEntity
let partsInEntity = [];
if (entityType == "Part Set") {
partsInEntity = find_parts_in_set();
}
// Saves the data to the entities_of_interest array ready to be added to the .JSON file
entities_of_interest.push({
name: entityName,
parts: entityID.split(","),
type: entityType,
partsOfEntity: partsInEntity
});
}
} catch (e) {
ErrorMessage("Error reading saved data");
}
}
gui.Window1.txtName.onChange = update_buttons;
gui.Window1.lbEntity.onClick = update_buttons;
gui.Window1.cbEntity.onChange = clear_IDs;
gui.Window1.btnSelect.onClick = select_main;
gui.Window1.btnDeleteSelected.onClick = delete_selected;
gui.Window1.btnUnblank.onClick = unblank;
gui.Window1.btnOnly.onClick = only;
gui.Window1.btnAdd.onClick = add;
gui.Window1.btnEdit.onClick = edit;
gui.Window1.btnSaveToFile.onClick = save_to_file1;
gui.Window1.btnSaveToModel.onClick = save_to_model;
gui.Window1.helpBtn.onClick = workflow_manual;
gui.WindowEdit.btnUpdate.onClick = update_edit;
gui.WindowEdit.btnCancel.onClick = close_edit;
gui.WindowEdit.btnSelect.onClick = select_edit;
gui.Window1.cbEntity.RemoveAllWidgetItems();
new WidgetItem(gui.Window1.cbEntity, "Parts");
new WidgetItem(gui.Window1.cbEntity, "Part Set");
gui.Window1.lblLine.Line(Widget.DARKGREY, 0, 50, 100, 50);
update_buttons();
}
/**
* Enables and Disables the buttons on the window according to how many Widget Items there are and how many are selected
*/
function update_buttons() {
if (gui.Window1.txtName.text == "" || entityID == "" || entityID == null) {
gui.Window1.btnAdd.active = false;
} else {
gui.Window1.btnAdd.active = true;
}
let widgetItems = gui.Window1.lbEntity.WidgetItems();
if (widgetItems == null) {
gui.Window1.btnDeleteSelected.active = false;
gui.Window1.btnEdit.active = false;
gui.Window1.btnOnly.active = false;
} else {
let widgetItemsSelected = 0;
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
widgetItemsSelected++;
}
}
if (widgetItemsSelected == 0) {
gui.Window1.btnDeleteSelected.active = false;
gui.Window1.btnOnly.active = false;
}
if (widgetItemsSelected != 0) {
gui.Window1.btnDeleteSelected.active = true;
gui.Window1.btnOnly.active = true;
}
if (widgetItemsSelected == 1) {
gui.Window1.btnEdit.active = true;
} else {
gui.Window1.btnEdit.active = false;
}
}
}
/**
* When the entity type is changed, the entityID list of selected entity's is cleared to prevent being able to add entities IDs of a non matching entity type.
*/
function clear_IDs() {
entityID = null;
update_buttons();
}
/**
* Sends to the select function with parameter main
*/
function select_main() {
select("main");
}
/**
* Sends to the select function with parameter edit
*/
function select_edit() {
select("edit");
}
/**
* Select the entities for the entry and populate the textbox
* @param {string} method
*/
function select(method) {
let f = AllocateFlag();
let selection;
let p;
if (method == "main") {
if (gui.Window1.cbEntity.text == "Parts") {
selection = Part.Select(f, "Pick parts of interest", m, true);
p = Part.First(m);
}
if (gui.Window1.cbEntity.text == "Part Set") {
// @ts-ignore this is because VS Code is checking it based on the core JavaScript Set class, which doesn't have a Select function or PART constant.
selection = Set.Select(Set.PART, f, "Pick part sets of interest", m, true);
// @ts-ignore
p = Set.First(m, Set.PART);
}
}
if (method == "edit") {
if (entities_of_interest[widgetItemNumberForEdit].type.toString() == "Parts") {
selection = Part.Select(f, "Pick parts of interest", m, true);
p = Part.First(m);
}
if (entities_of_interest[widgetItemNumberForEdit].type.toString() == "Part Set") {
// @ts-ignore this is because VS Code is checking it based on the core JavaScript Set class, which doesn't have a Select function or PART constant.
selection = Set.Select(Set.PART, f, "Pick part sets of interest", m, true);
// @ts-ignore
p = Set.First(m, Set.PART);
}
}
if (selection == null) {
ReturnFlag(f);
return;
}
let text = "";
let first = true;
while (p) {
if (p.Flagged(f)) {
if (first) {
text += p.label;
first = false;
} else {
text += "," + p.label;
}
}
p = p.Next();
}
ReturnFlag(f);
entityID = text;
if (method == "edit") {
gui.WindowEdit.txtID.text = entityID;
}
update_buttons();
}
/**
* Unblank all parts
*/
function unblank() {
m.Unblank();
View.Ac();
}
/**
* Only selected parts from the listbox
*/
function only() {
m.Blank();
let widgetItems = gui.Window1.lbEntity.WidgetItems();
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
let parts;
if (entities_of_interest[i].type.toString() == "Parts") {
parts = entities_of_interest[i].parts;
}
if (entities_of_interest[i].type.toString() == "Part Set") {
parts = entities_of_interest[i].partsOfEntity;
}
parts = parts.toString();
parts = parts.split(",");
let parts_flag = AllocateFlag();
for (let x = 0; x < parts.length; x++) {
let p = Part.GetFromID(m, Number(parts[x]));
p.SetFlag(parts_flag);
}
Part.UnblankFlagged(m, parts_flag);
ReturnFlag(parts_flag);
}
}
View.Ac();
}
/**
* Adds an entry to the listbox
*/
function add() {
// Checks if entry has a name
let entityName = gui.Window1.txtName.text;
if (entityName == "") {
Window.Message("", "You must enter a name for your entity");
return;
}
// Checks if entry has a unique name
for (let x = 0; x < entities_of_interest.length; x++) {
let entities_of_interest_name = entities_of_interest[x].name.toString();
entities_of_interest_name = entities_of_interest_name;
if (entityName == entities_of_interest_name) {
Window.Message("", "You can not have entities with the same name");
return;
}
}
// Checks if the entry has entities selected
if (entityID == "" || entityID == " " || entityID == null) {
Window.Message("", "You must select an entity for this entry");
return;
}
let entityType = gui.Window1.cbEntity.text;
// Adds the entry to the listbox and sets the hover value to the entities
let newEntry = new WidgetItem(gui.Window1.lbEntity, entityName + " | " + entityType + " | " + entityID);
newEntry.hover = entityID;
// If the entry is a part set then finds the parts in the part set and saves it to partsInEntity
let partsInEntity = [];
if (entityType == "Part Set") {
partsInEntity = find_parts_in_set();
}
// Saves the data to the entities_of_interest array ready to be added to the .JSON file
entities_of_interest.push({
name: entityName,
parts: entityID.split(","),
type: entityType,
partsOfEntity: partsInEntity
});
}
/**
* Finds parts in a part set by spooling through its setID
* @returns {Array} partsInEntity
*/
function find_parts_in_set() {
let partsInEntity = [];
let partID;
let setIDs = entityID.split(",");
for (let i = 0; i < setIDs.length; i++) {
let setID = Number(setIDs[i]);
// @ts-ignore
let s = Set.GetFromID(m, setID, Set.PART);
s.StartSpool();
while ((partID = s.Spool())) {
partsInEntity.push(partID.toString());
}
}
return partsInEntity;
}
/**
* Deletes a selcted entry from the listbox
*/
function delete_selected() {
let widgetItems = gui.Window1.lbEntity.WidgetItems();
// If there are no entries selected then prints message and returns
if (widgetItems == null) {
Window.Message("", "No entries avaliable to delete");
return;
}
let widgetItemsSelected = 0;
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
widgetItemsSelected++;
}
}
if (widgetItemsSelected == 0) {
Window.Message("", "No entries selected to delete");
}
// Loops through WidgetItems
for (let i = 0; i < widgetItems.length; i++) {
// If the WidgetItem is selected
if (widgetItems[i].selected) {
// Finds the name of the selected WidgetItem
let widgetItemText = widgetItems[i].text;
let widgetItemTextArray = widgetItemText.split("|");
let widgetItemName = widgetItemTextArray[0];
widgetItemName = widgetItemName.toString();
// Loops through the entities_of_interest arreay
for (let x = 0; x < entities_of_interest.length; x++) {
// If the name of the selected WidgetItem matches the name in the entities_of_interest array
let entities_of_interest_name = entities_of_interest[x].name.toString();
entities_of_interest_name = entities_of_interest_name + " ";
if (widgetItemName == entities_of_interest_name) {
// Removes the entry from the entities_of_interest array
entities_of_interest.splice(x, 1);
}
}
// Removes the WidgetItem
gui.Window1.lbEntity.RemoveWidgetItem(widgetItems[i]);
}
}
gui.Window1.Redraw();
update_buttons();
}
/**
* Opens the WindowEdit window ready to edit an entry and validates this is possible
*/
function edit() {
let widgetItems = gui.Window1.lbEntity.WidgetItems();
// If no entry is selected then returns
if (widgetItems == null) {
Window.Message("", "No entrys avaliable to edit");
return;
}
// Checks that their is only 1 WidgetItem selected, if it is then open WindowEdit window, if show message and return
let widgetsSelected = 0;
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
widgetsSelected++;
}
}
if (widgetsSelected == 1) {
let widgetItemsEdit = gui.Window1.lbEntity.WidgetItems();
for (let i = 0; i < widgetItemsEdit.length; i++) {
if (widgetItemsEdit[i].selected) {
widgetItemNumberForEdit = i;
gui.WindowEdit.txtName.text = entities_of_interest[i].name.toString();
gui.WindowEdit.txtID.text = entities_of_interest[i].parts.toString();
gui.WindowEdit.Show(false);
}
}
} else if (widgetsSelected == 0) {
Window.Message("", "You need to select an entry to edit");
return;
} else {
Window.Message("", "You can only edit 1 entry at a time");
return;
}
}
/**
* Edits a selected entry from the listbox if the update button is pressed in the WindowEdit window
*/
function update_edit() {
let widgetItems = gui.Window1.lbEntity.WidgetItems();
// Checks entry has a name
let entityName = gui.WindowEdit.txtName.text;
if (entityName == "") {
Window.Message("", "You must enter a name for your entity");
return;
}
// Checks user hasn't given the entry the name of an existing entry
for (let x = 0; x < entities_of_interest.length; x++) {
let entities_of_interest_name = entities_of_interest[x].name.toString();
if (entityName == entities_of_interest_name) {
if (entityName == entities_of_interest[widgetItemNumberForEdit].name) {
Message("Keeping the same entity name");
} else {
Window.Message("", "You can not have entities with the same name");
return;
}
}
}
// Updates the entites_of_interest array with the updated information
entities_of_interest[widgetItemNumberForEdit].name = gui.WindowEdit.txtName.text;
let parts = gui.WindowEdit.txtID.text.split(",");
entities_of_interest[widgetItemNumberForEdit].parts = parts;
// Updates the WidgetItem hover value with the new entityID
widgetItems[widgetItemNumberForEdit].hover = parts;
// If part set is selected then finds the parts belonging to each set to add to the entities_of_interest array
if (entities_of_interest[widgetItemNumberForEdit].type.toString() == "Part Set") {
entities_of_interest[widgetItemNumberForEdit].partsOfEntity = find_parts_in_set();
}
// Updates the WidgetItem text
let newString =
entities_of_interest[widgetItemNumberForEdit].name +
" | " +
entities_of_interest[widgetItemNumberForEdit].type +
" | " +
entities_of_interest[widgetItemNumberForEdit].parts;
widgetItems[widgetItemNumberForEdit].text = newString;
gui.WindowEdit.Hide();
}
/**
* Closes WindowEdit window
*/
function close_edit() {
gui.WindowEdit.Hide();
}
/**
* Saves data to .JSON file
*/
function save_to_file1() {
/* Get data to write to file */
var data = { entities_of_interest: [] };
for (var i = 0; i < entities_of_interest.length; i++) {
data["entities_of_interest"].push({
name: entities_of_interest[i].name,
parts: entities_of_interest[i].parts,
type: entities_of_interest[i].type,
partsOfEntity: entities_of_interest[i].partsOfEntity
});
}
/* Ask the user where to write it */
var filename = Window.GetFile(".json", true);
if (filename == null) return;
/* API call to write workflow file */
Workflow.WriteToFile(data, filename, workflow_filename);
Message("Written workflow file to " + filename);
}
/**
* Saves data to the model
*/
function save_to_model() {
/* Get data to write to file */
var data = { entities_of_interest: [] };
for (var i = 0; i < entities_of_interest.length; i++) {
data["entities_of_interest"].push({
// do we need the entites_of_interest thing? Intrusion contour plot doesn't have anything named...
name: entities_of_interest[i].name,
parts: entities_of_interest[i].parts,
type: entities_of_interest[i].type,
partsOfEntity: entities_of_interest[i].partsOfEntity
});
}
let model = Model.Select("Select the model to write to");
/* API call to write workflow to a model */
Workflow.WriteToModel(data, model, workflow_filename);
Message("Workflow data added to post *END data. You need to write out the model from the main Model->Write menu to save the additions.");
}
/**
* Opens up the clickhelp manual when the help button is pressed
*/
function workflow_manual() {
OpenManual("primer", "entities-of-interest.html");
}