Even more conversion

This commit is contained in:
Olivier Gagnon 2021-08-28 03:31:47 -04:00
parent 94ad7ccf4b
commit 0de3deee3f
2 changed files with 240 additions and 220 deletions

@ -20,7 +20,12 @@ export class Industry extends BaseReactComponent {
return (
<div>
<div className={"cmpy-mgmt-industry-left-panel"}>
<IndustryOverview {...this.props} />
<IndustryOverview
routing={this.props.routing}
eventHandler={this.props.eventHandler}
corp={this.props.corp}
currentCity={this.props.currentCity}
/>
<IndustryOffice {...this.props} />
</div>

@ -1,120 +1,136 @@
// React Component for displaying an Industry's OfficeSpace information
// (bottom-left panel in the Industry UI)
import React from "react";
import { BaseReactComponent } from "./BaseReactComponent";
import React, { useState } from "react";
import { OfficeSpace } from "../OfficeSpace";
import { Employee } from "../Employee";
import { EmployeePositions } from "../EmployeePositions";
import { numeralWrapper } from "../../ui/numeralFormat";
import { getSelectText } from "../../../utils/uiHelpers/getSelectData";
export class IndustryOffice extends BaseReactComponent {
constructor(props) {
super(props);
this.state = {
city: "",
division: "",
employeeManualAssignMode: false,
employee: null, // Reference to employee being referenced if in Manual Mode
numEmployees: 0,
numOperations: 0,
numEngineers: 0,
numBusiness: 0,
numManagement: 0,
numResearch: 0,
numUnassigned: 0,
numTraining: 0,
interface IProps {
routing: any;
eventHandler: any;
corp: any;
currentCity: string;
}
this.updateEmployeeCount(); // This function validates division and office refs
export function IndustryOffice(props: IProps): React.ReactElement {
const [employeeManualAssignMode, setEmployeeManualAssignMode] = useState(false);
const [city, setCity] = useState("");
const [divisionName, setDivisionName] = useState("");
const [employee, setEmployee] = useState<Employee | null>(null);
const [numEmployees, setNumEmployees] = useState(0);
const [numOperations, setNumOperations] = useState(0);
const [numEngineers, setNumEngineers] = useState(0);
const [numBusiness, setNumBusiness] = useState(0);
const [numManagement, setNumManagement] = useState(0);
const [numResearch, setNumResearch] = useState(0);
const [numUnassigned, setNumUnassigned] = useState(0);
const [numTraining, setNumTraining] = useState(0);
function resetEmployeeCount() {
setNumEmployees(0);
setNumOperations(0);
setNumEngineers(0);
setNumBusiness(0);
setNumManagement(0);
setNumResearch(0);
setNumUnassigned(0);
setNumTraining(0);
}
resetEmployeeCount() {
this.state.numEmployees = 0;
this.state.numOperations = 0;
this.state.numEngineers = 0;
this.state.numBusiness = 0;
this.state.numManagement = 0;
this.state.numResearch = 0;
this.state.numUnassigned = 0;
this.state.numTraining = 0;
}
updateEmployeeCount() {
const division = this.routing().currentDivision;
function updateEmployeeCount() {
const division = props.routing.currentDivision;
if (division == null) {
throw new Error(`Routing does not hold reference to the current Industry`);
}
const office = division.offices[this.props.currentCity];
const office = division.offices[props.currentCity];
if (!(office instanceof OfficeSpace)) {
throw new Error(`Current City (${this.props.currentCity}) for UI does not have an OfficeSpace object`);
throw new Error(`Current City (${props.currentCity}) for UI does not have an OfficeSpace object`);
}
// If we're in a new city, we have to reset the state
if (division.name !== this.state.division || this.props.currentCity !== this.state.city) {
this.resetEmployeeCount();
this.state.division = division.name;
this.state.city = this.props.currentCity;
if (division.name !== divisionName || props.currentCity !== city) {
resetEmployeeCount();
setDivisionName(division.name);
setCity(props.currentCity);
}
// Calculate how many NEW emplyoees we need to account for
// Calculate how many NEW employees we need to account for
const currentNumEmployees = office.employees.length;
let newOperations = numOperations;
let newEngineers = numEngineers;
let newBusiness = numBusiness;
let newManagement = numManagement;
let newResearch = numResearch;
let newUnassigned = numUnassigned;
let newTraining = numTraining;
// Record the number of employees in each position, for NEW employees only
for (let i = this.state.numEmployees; i < office.employees.length; ++i) {
for (let i = numEmployees; i < office.employees.length; ++i) {
switch (office.employees[i].pos) {
case EmployeePositions.Operations:
++this.state.numOperations;
newOperations++;
break;
case EmployeePositions.Engineer:
++this.state.numEngineers;
newEngineers++;
break;
case EmployeePositions.Business:
++this.state.numBusiness;
newBusiness++;
break;
case EmployeePositions.Management:
++this.state.numManagement;
newManagement++;
break;
case EmployeePositions.RandD:
++this.state.numResearch;
newResearch++;
break;
case EmployeePositions.Unassigned:
++this.state.numUnassigned;
newUnassigned++;
break;
case EmployeePositions.Training:
++this.state.numTraining;
newTraining++;
break;
default:
console.error("Unrecognized employee position: " + office.employees[i].pos);
break;
}
}
if(newOperations !== numOperations) setNumOperations(newOperations);
if(newEngineers !== numEngineers) setNumEngineers(newEngineers);
if(newBusiness !== numBusiness) setNumBusiness(newBusiness);
if(newManagement !== numManagement) setNumManagement(newManagement);
if(newResearch !== numResearch) setNumResearch(newResearch);
if(newUnassigned !== numUnassigned) setNumUnassigned(newUnassigned);
if(newTraining !== numTraining) setNumTraining(newTraining);
this.state.numEmployees = currentNumEmployees;
if(currentNumEmployees !== numEmployees) setNumEmployees(currentNumEmployees);
}
updateEmployeeCount();
// Renders the "Employee Management" section of the Office UI
renderEmployeeManagement() {
this.updateEmployeeCount();
function renderEmployeeManagement() {
updateEmployeeCount();
if (this.state.employeeManualAssignMode) {
return this.renderManualEmployeeManagement();
if (employeeManualAssignMode) {
return renderManualEmployeeManagement();
} else {
return this.renderAutomaticEmployeeManagement();
return renderAutomaticEmployeeManagement();
}
}
renderAutomaticEmployeeManagement() {
const division = this.routing().currentDivision; // Validated in constructor
const office = division.offices[this.props.currentCity]; // Validated in constructor
const vechain = (this.corp().unlockUpgrades[4] === 1); // Has Vechain upgrade
function renderAutomaticEmployeeManagement() {
const division = props.routing.currentDivision; // Validated in constructor
const office = division.offices[props.currentCity]; // Validated in constructor
const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade
const switchModeOnClick = () => {
this.state.employeeManualAssignMode = true;
this.corp().rerender();
setEmployeeManualAssignMode(true);
props.corp.rerender();
}
// Calculate average morale, happiness, and energy. Also salary
@ -135,87 +151,87 @@ export class IndustryOffice extends BaseReactComponent {
}
// Helper functions for (re-)assigning employees to different positions
const assignEmployee = (to) => {
if (this.state.numUnassigned <= 0) {
function assignEmployee(to: string) {
if (numUnassigned <= 0) {
console.warn("Cannot assign employee. No unassigned employees available");
return;
}
switch (to) {
case EmployeePositions.Operations:
++this.state.numOperations;
setNumOperations(n => n+1);
break;
case EmployeePositions.Engineer:
++this.state.numEngineers;
setNumEngineers(n => n+1);
break;
case EmployeePositions.Business:
++this.state.numBusiness;
setNumBusiness(n => n+1);
break;
case EmployeePositions.Management:
++this.state.numManagement;
setNumManagement(n => n+1);
break;
case EmployeePositions.RandD:
++this.state.numResearch;
setNumResearch(n => n+1);
break;
case EmployeePositions.Unassigned:
++this.state.numUnassigned;
setNumUnassigned(n => n+1);
break;
case EmployeePositions.Training:
++this.state.numTraining;
setNumTraining(n => n+1);
break;
default:
console.error("Unrecognized employee position: " + to);
break;
}
--this.state.numUnassigned;
setNumUnassigned(n => n-1);
office.assignEmployeeToJob(to);
office.calculateEmployeeProductivity({ corporation: this.corp(), industry:division });
this.corp().rerender();
office.calculateEmployeeProductivity({ corporation: props.corp, industry:division });
props.corp.rerender();
}
const unassignEmployee = (from) => {
function logWarning(pos) {
function unassignEmployee(from: string) {
function logWarning(pos: string) {
console.warn(`Cannot unassign from ${pos} because there is nobody assigned to that position`);
}
switch (from) {
case EmployeePositions.Operations:
if (this.state.numOperations <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numOperations;
if (numOperations <= 0) { return logWarning(EmployeePositions.Operations); }
setNumOperations(n => n-1);
break;
case EmployeePositions.Engineer:
if (this.state.numEngineers <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numEngineers;
if (numEngineers <= 0) { return logWarning(EmployeePositions.Operations); }
setNumEngineers(n => n-1);
break;
case EmployeePositions.Business:
if (this.state.numBusiness <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numBusiness;
if (numBusiness <= 0) { return logWarning(EmployeePositions.Operations); }
setNumBusiness(n => n-1);
break;
case EmployeePositions.Management:
if (this.state.numManagement <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numManagement;
if (numManagement <= 0) { return logWarning(EmployeePositions.Operations); }
setNumManagement(n => n-1);
break;
case EmployeePositions.RandD:
if (this.state.numResearch <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numResearch;
if (numResearch <= 0) { return logWarning(EmployeePositions.Operations); }
setNumResearch(n => n-1);
break;
case EmployeePositions.Unassigned:
console.warn(`Tried to unassign from the Unassigned position`);
break;
case EmployeePositions.Training:
if (this.state.numTraining <= 0) { return logWarning(EmployeePositions.Operations); }
--this.state.numTraining;
if (numTraining <= 0) { return logWarning(EmployeePositions.Operations); }
setNumTraining(n => n-1);
break;
default:
console.error("Unrecognized employee position: " + from);
break;
}
++this.state.numUnassigned;
setNumUnassigned(n => n+1);
office.unassignEmployeeFromJob(from);
office.calculateEmployeeProductivity({ corporation: this.corp(), industry:division });
this.corp().rerender();
office.calculateEmployeeProductivity({ corporation: props.corp, industry:division });
props.corp.rerender();
}
const positionHeaderStyle = {
@ -223,67 +239,67 @@ export class IndustryOffice extends BaseReactComponent {
margin: "5px 0px 5px 0px",
width: "50%",
}
const assignButtonClass = this.state.numUnassigned > 0 ? "std-button" : "a-link-button-inactive";
const assignButtonClass = numUnassigned > 0 ? "std-button" : "a-link-button-inactive";
const operationAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.Operations);
this.corp().rerender();
props.corp.rerender();
}
const operationUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.Operations);
this.corp().rerender();
props.corp.rerender();
}
const operationUnassignButtonClass = this.state.numOperations > 0 ? "std-button" : "a-link-button-inactive";
const operationUnassignButtonClass = numOperations > 0 ? "std-button" : "a-link-button-inactive";
const engineerAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.Engineer);
this.corp().rerender();
props.corp.rerender();
}
const engineerUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.Engineer);
this.corp().rerender();
props.corp.rerender();
}
const engineerUnassignButtonClass = this.state.numEngineers > 0 ? "std-button" : "a-link-button-inactive";
const engineerUnassignButtonClass = numEngineers > 0 ? "std-button" : "a-link-button-inactive";
const businessAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.Business);
this.corp().rerender();
props.corp.rerender();
}
const businessUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.Business);
this.corp().rerender();
props.corp.rerender();
}
const businessUnassignButtonClass = this.state.numBusiness > 0 ? "std-button" : "a-link-button-inactive";
const businessUnassignButtonClass = numBusiness > 0 ? "std-button" : "a-link-button-inactive";
const managementAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.Management);
this.corp().rerender();
props.corp.rerender();
}
const managementUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.Management);
this.corp().rerender();
props.corp.rerender();
}
const managementUnassignButtonClass = this.state.numManagement > 0 ? "std-button" : "a-link-button-inactive";
const managementUnassignButtonClass = numManagement > 0 ? "std-button" : "a-link-button-inactive";
const rndAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.RandD);
this.corp().rerender();
props.corp.rerender();
}
const rndUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.RandD);
this.corp().rerender();
props.corp.rerender();
}
const rndUnassignButtonClass = this.state.numResearch > 0 ? "std-button" : "a-link-button-inactive";
const rndUnassignButtonClass = numResearch > 0 ? "std-button" : "a-link-button-inactive";
const trainingAssignButtonOnClick = () => {
assignEmployee(EmployeePositions.Training);
this.corp().rerender();
props.corp.rerender();
}
const trainingUnassignButtonOnClick = () => {
unassignEmployee(EmployeePositions.Training);
this.corp().rerender();
props.corp.rerender();
}
const trainingUnassignButtonClass = this.state.numTraining > 0 ? "std-button" : "a-link-button-inactive";
const trainingUnassignButtonClass = numTraining > 0 ? "std-button" : "a-link-button-inactive";
return (
<div>
@ -295,7 +311,7 @@ export class IndustryOffice extends BaseReactComponent {
</span>
</button>
<p><strong>Unassigned Employees: {this.state.numUnassigned}</strong></p>
<p><strong>Unassigned Employees: {numUnassigned}</strong></p>
<br />
<p>Avg Employee Morale: {numeralWrapper.format(avgMorale, "0.000")}</p>
@ -344,7 +360,7 @@ export class IndustryOffice extends BaseReactComponent {
}
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.Operations} ({this.state.numOperations})
{EmployeePositions.Operations} ({numOperations})
<span className={"tooltiptext"}>
Manages supply chain operations. Improves the amount of Materials and Products you produce.
</span>
@ -354,7 +370,7 @@ export class IndustryOffice extends BaseReactComponent {
<br />
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.Engineer} ({this.state.numEngineers})
{EmployeePositions.Engineer} ({numEngineers})
<span className={"tooltiptext"}>
Develops and maintains products and production systems. Increases the quality of
everything you produce. Also increases the amount you produce (not as much
@ -366,7 +382,7 @@ export class IndustryOffice extends BaseReactComponent {
<br />
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.Business} ({this.state.numBusiness})
{EmployeePositions.Business} ({numBusiness})
<span className={"tooltiptext"}>
Handles sales and finances. Improves the amount of Materials and Products you can sell.
</span>
@ -376,7 +392,7 @@ export class IndustryOffice extends BaseReactComponent {
<br />
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.Management} ({this.state.numManagement})
{EmployeePositions.Management} ({numManagement})
<span className={"tooltiptext"}>
Leads and oversees employees and office operations. Improves the effectiveness of
Engineer and Operations employees
@ -387,7 +403,7 @@ export class IndustryOffice extends BaseReactComponent {
<br />
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.RandD} ({this.state.numResearch})
{EmployeePositions.RandD} ({numResearch})
<span className={"tooltiptext"}>
Research new innovative ways to improve the company. Generates Scientific Research
</span>
@ -397,7 +413,7 @@ export class IndustryOffice extends BaseReactComponent {
<br />
<h2 className={"tooltip"} style={positionHeaderStyle}>
{EmployeePositions.Training} ({this.state.numTraining})
{EmployeePositions.Training} ({numTraining})
<span className={"tooltiptext"}>
Set employee to training, which will increase some of their stats. Employees in training do not affect any company operations.
</span>
@ -408,14 +424,14 @@ export class IndustryOffice extends BaseReactComponent {
)
}
renderManualEmployeeManagement() {
const corp = this.corp();
const division = this.routing().currentDivision; // Validated in constructor
const office = division.offices[this.props.currentCity]; // Validated in constructor
function renderManualEmployeeManagement() {
const corp = props.corp;
const division = props.routing.currentDivision; // Validated in constructor
const office = division.offices[props.currentCity]; // Validated in constructor
const switchModeOnClick = () => {
this.state.employeeManualAssignMode = false;
this.corp().rerender();
setEmployeeManualAssignMode(false);
props.corp.rerender();
}
const employeeInfoDivStyle = {
@ -430,11 +446,11 @@ export class IndustryOffice extends BaseReactComponent {
employees.push(<option key={office.employees[i].name}>{office.employees[i].name}</option>)
}
const employeeSelectorOnChange = (e) => {
const employeeSelectorOnChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const name = getSelectText(e.target);
for (let i = 0; i < office.employees.length; ++i) {
if (name === office.employees[i].name) {
this.state.employee = office.employees[i];
setEmployee(office.employees[i]);
break;
}
}
@ -443,8 +459,8 @@ export class IndustryOffice extends BaseReactComponent {
}
// Employee Positions Selector
const emp = this.state.employee;
let employeePositionSelectorInitialValue = null;
const emp = employee;
let employeePositionSelectorInitialValue = "";
const employeePositions = [];
const positionNames = Object.values(EmployeePositions);
for (let i = 0; i < positionNames.length; ++i) {
@ -454,10 +470,11 @@ export class IndustryOffice extends BaseReactComponent {
}
}
const employeePositionSelectorOnChange = (e) => {
function employeePositionSelectorOnChange(e: React.ChangeEvent<HTMLSelectElement>) {
if(employee === null) return;
const pos = getSelectText(e.target);
this.state.employee.pos = pos;
this.resetEmployeeCount();
employee.pos = pos;
resetEmployeeCount();
corp.rerender();
}
@ -486,29 +503,29 @@ export class IndustryOffice extends BaseReactComponent {
{employees}
</select>
{
this.state.employee != null &&
employee != null &&
<p>
Morale: {numeralWrapper.format(this.state.employee.mor, nf)}
Morale: {numeralWrapper.format(employee.mor, nf)}
<br />
Happiness: {numeralWrapper.format(this.state.employee.hap, nf)}
Happiness: {numeralWrapper.format(employee.hap, nf)}
<br />
Energy: {numeralWrapper.format(this.state.employee.ene, nf)}
Energy: {numeralWrapper.format(employee.ene, nf)}
<br />
Intelligence: {numeralWrapper.format(effInt, nf)}
<br />
Charisma: {numeralWrapper.format(effCha, nf)}
<br />
Experience: {numeralWrapper.format(this.state.employee.exp, nf)}
Experience: {numeralWrapper.format(employee.exp, nf)}
<br />
Creativity: {numeralWrapper.format(effCre, nf)}
<br />
Efficiency: {numeralWrapper.format(effEff, nf)}
<br />
Salary: {numeralWrapper.formatMoney(this.state.employee.sal)}
Salary: {numeralWrapper.formatMoney(employee.sal)}
</p>
}
{
this.state.employee != null &&
employee != null &&
<select onChange={employeePositionSelectorOnChange} value={employeePositionSelectorInitialValue}>
{employeePositions}
</select>
@ -518,10 +535,9 @@ export class IndustryOffice extends BaseReactComponent {
)
}
render() {
const corp = this.corp();
const division = this.routing().currentDivision; // Validated in constructor
const office = division.offices[this.props.currentCity]; // Validated in constructor
const corp = props.corp;
const division = props.routing.currentDivision; // Validated in constructor
const office = division.offices[props.currentCity]; // Validated in constructor
const buttonStyle = {
fontSize: "13px",
@ -552,14 +568,14 @@ export class IndustryOffice extends BaseReactComponent {
const autohireEmployeeButtonOnClick = () => {
if (office.atCapacity()) { return; }
office.hireRandomEmployee();
this.corp().rerender();
props.corp.rerender();
}
// Upgrade Office Size Button
const upgradeOfficeSizeOnClick = this.eventHandler().createUpgradeOfficeSizePopup.bind(this.eventHandler(), office);
const upgradeOfficeSizeOnClick = props.eventHandler.createUpgradeOfficeSizePopup.bind(props.eventHandler, office);
// Throw Office Party
const throwOfficePartyOnClick = this.eventHandler().createThrowOfficePartyPopup.bind(this.eventHandler(), office);
const throwOfficePartyOnClick = props.eventHandler.createThrowOfficePartyPopup.bind(props.eventHandler, office);
return (
<div className={"cmpy-mgmt-employee-panel"}>
@ -599,8 +615,7 @@ export class IndustryOffice extends BaseReactComponent {
}
<br />
{this.renderEmployeeManagement()}
{renderEmployeeManagement()}
</div>
)
}
}