Fix AwakeningSelect component
It was completely broken for weapons. We managed to fix the problem by refactoring how data is sent to SelectWithInput but I fear the root error is still there. We also cleaned the component up a bit.
This commit is contained in:
parent
39940abf9f
commit
6023f9ab6a
5 changed files with 60 additions and 87 deletions
|
|
@ -1,51 +1,41 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useRouter } from 'next/router'
|
import cloneDeep from 'lodash.clonedeep'
|
||||||
import { useTranslation } from 'next-i18next'
|
|
||||||
|
|
||||||
import SelectWithInput from '~components/SelectWithInput'
|
import SelectWithInput from '~components/SelectWithInput'
|
||||||
import SelectItem from '~components/SelectItem'
|
|
||||||
|
|
||||||
import classNames from 'classnames'
|
|
||||||
|
|
||||||
import { weaponAwakening, characterAwakening } from '~data/awakening'
|
import { weaponAwakening, characterAwakening } from '~data/awakening'
|
||||||
import type { Awakening } from '~data/awakening'
|
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
object: 'character' | 'weapon'
|
object: 'character' | 'weapon'
|
||||||
awakeningType?: number
|
type?: number
|
||||||
awakeningLevel?: number
|
level?: number
|
||||||
onOpenChange?: (open: boolean) => void
|
onOpenChange?: (open: boolean) => void
|
||||||
sendValidity: (isValid: boolean) => void
|
sendValidity: (isValid: boolean) => void
|
||||||
sendValues: (type: number, level: number) => void
|
sendValues: (type: number, level: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const AwakeningSelect = (props: Props) => {
|
const AwakeningSelect = (props: Props) => {
|
||||||
const router = useRouter()
|
// Data states
|
||||||
const locale =
|
|
||||||
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
|
|
||||||
const { t } = useTranslation('common')
|
|
||||||
|
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
|
|
||||||
// States
|
|
||||||
const [awakeningType, setAwakeningType] = useState(
|
const [awakeningType, setAwakeningType] = useState(
|
||||||
props.object === 'weapon' ? -1 : 1
|
props.object === 'weapon' ? 0 : 1
|
||||||
)
|
)
|
||||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
const [maxValue, setMaxValue] = useState(1)
|
|
||||||
|
|
||||||
const [error, setError] = useState('')
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
const dataSet = () => {
|
const chooseDataset = () => {
|
||||||
if (props.object === 'character') return characterAwakening
|
let list: ItemSkill[] = []
|
||||||
else {
|
|
||||||
const weaponDataSet = weaponAwakening
|
|
||||||
|
|
||||||
weaponDataSet.unshift({
|
switch (props.object) {
|
||||||
|
case 'character':
|
||||||
|
list = characterAwakening
|
||||||
|
break
|
||||||
|
case 'weapon':
|
||||||
|
// WARNING: Clonedeep is masking a deeper error
|
||||||
|
// which is running this method every time this component is rerendered
|
||||||
|
// causing multiple "No awakening" items to be added
|
||||||
|
const awakening = cloneDeep(weaponAwakening)
|
||||||
|
awakening.unshift({
|
||||||
id: 0,
|
id: 0,
|
||||||
name: {
|
name: {
|
||||||
en: 'No awakening',
|
en: 'No awakening',
|
||||||
|
|
@ -56,48 +46,30 @@ const AwakeningSelect = (props: Props) => {
|
||||||
maxValue: 0,
|
maxValue: 0,
|
||||||
fractional: false,
|
fractional: false,
|
||||||
})
|
})
|
||||||
|
list = awakening
|
||||||
return weaponDataSet
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Classes
|
return list
|
||||||
const inputClasses = classNames({
|
}
|
||||||
Bound: true,
|
|
||||||
Hidden: awakeningType === -1,
|
|
||||||
})
|
|
||||||
|
|
||||||
const errorClasses = classNames({
|
|
||||||
errors: true,
|
|
||||||
visible: error !== '',
|
|
||||||
})
|
|
||||||
|
|
||||||
// Set max value based on object type
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.object === 'character') setMaxValue(9)
|
|
||||||
else if (props.object === 'weapon') setMaxValue(15)
|
|
||||||
}, [props.object])
|
|
||||||
|
|
||||||
// Set default awakening and level based on object type
|
// Set default awakening and level based on object type
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let defaultAwakening = 1
|
const defaultAwakening = props.object === 'weapon' ? 0 : 1
|
||||||
if (props.object === 'weapon') defaultAwakening = -1
|
const type = props.type != undefined ? props.type : defaultAwakening
|
||||||
|
|
||||||
setAwakeningType(
|
setAwakeningType(type)
|
||||||
props.awakeningType != undefined ? props.awakeningType : defaultAwakening
|
setAwakeningLevel(props.level ? props.level : 1)
|
||||||
)
|
}, [props.object, props.type, props.level])
|
||||||
setAwakeningLevel(props.awakeningLevel ? props.awakeningLevel : 1)
|
|
||||||
}, [props.object, props.awakeningType, props.awakeningLevel])
|
|
||||||
|
|
||||||
// Send validity of form when awakening level changes
|
// Send validity of form when awakening level changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
props.sendValidity(awakeningLevel > 0 && error === '')
|
props.sendValidity(awakeningLevel > 0)
|
||||||
}, [props.sendValidity, awakeningLevel, error])
|
}, [props.sendValidity, awakeningLevel])
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
function changeOpen() {
|
function changeOpen(open: boolean) {
|
||||||
setOpen(!open)
|
if (props.onOpenChange) props.onOpenChange(open)
|
||||||
if (props.onOpenChange) props.onOpenChange(!open)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleValueChange(type: number, level: number) {
|
function handleValueChange(type: number, level: number) {
|
||||||
|
|
@ -110,7 +82,7 @@ const AwakeningSelect = (props: Props) => {
|
||||||
<div className="Awakening">
|
<div className="Awakening">
|
||||||
<SelectWithInput
|
<SelectWithInput
|
||||||
object={`${props.object}_awakening`}
|
object={`${props.object}_awakening`}
|
||||||
dataSet={dataSet()}
|
dataSet={chooseDataset()}
|
||||||
selectValue={awakeningType}
|
selectValue={awakeningType}
|
||||||
inputValue={awakeningLevel}
|
inputValue={awakeningLevel}
|
||||||
onOpenChange={changeOpen}
|
onOpenChange={changeOpen}
|
||||||
|
|
|
||||||
|
|
@ -254,8 +254,8 @@ const CharacterModal = ({
|
||||||
<h3>{t('modals.characters.subtitles.awakening')}</h3>
|
<h3>{t('modals.characters.subtitles.awakening')}</h3>
|
||||||
<AwakeningSelect
|
<AwakeningSelect
|
||||||
object="character"
|
object="character"
|
||||||
awakeningType={awakeningType}
|
type={awakeningType}
|
||||||
awakeningLevel={awakeningLevel}
|
level={awakeningLevel}
|
||||||
sendValidity={receiveValidity}
|
sendValidity={receiveValidity}
|
||||||
sendValues={receiveAwakeningValues}
|
sendValues={receiveAwakeningValues}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,11 @@ const SelectWithInput = ({
|
||||||
|
|
||||||
// Set default values from props
|
// Set default values from props
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCurrentItemSkill(dataSet.find((sk) => sk.id === selectValue))
|
const found = dataSet.find((sk) => sk.id === selectValue)
|
||||||
|
if (found) {
|
||||||
|
setCurrentItemSkill(found)
|
||||||
setFieldInputValue(inputValue)
|
setFieldInputValue(inputValue)
|
||||||
|
}
|
||||||
}, [selectValue, inputValue])
|
}, [selectValue, inputValue])
|
||||||
|
|
||||||
// Methods: UI state management
|
// Methods: UI state management
|
||||||
|
|
@ -98,14 +101,6 @@ const SelectWithInput = ({
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (object === 'weapon_awakening') {
|
|
||||||
options?.unshift(
|
|
||||||
<SelectItem key={-1} value={-1}>
|
|
||||||
{t(`${object}.no_type`)}
|
|
||||||
</SelectItem>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,12 +108,18 @@ const SelectWithInput = ({
|
||||||
function handleSelectChange(rawValue: string) {
|
function handleSelectChange(rawValue: string) {
|
||||||
const value = parseInt(rawValue)
|
const value = parseInt(rawValue)
|
||||||
const skill = dataSet.find((sk) => sk.id === value)
|
const skill = dataSet.find((sk) => sk.id === value)
|
||||||
|
|
||||||
|
if (skill) {
|
||||||
setCurrentItemSkill(skill)
|
setCurrentItemSkill(skill)
|
||||||
|
sendValues(skill.id, fieldInputValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||||
const value = parseFloat(event.target.value)
|
const value = parseFloat(event.target.value)
|
||||||
if (handleInputError(value)) setFieldInputValue(value)
|
if (handleInputError(value)) setFieldInputValue(value)
|
||||||
|
|
||||||
|
if (currentItemSkill) sendValues(currentItemSkill.id, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods: Handle error
|
// Methods: Handle error
|
||||||
|
|
@ -169,7 +170,7 @@ const SelectWithInput = ({
|
||||||
open={open}
|
open={open}
|
||||||
disabled={selectDisabled}
|
disabled={selectDisabled}
|
||||||
onValueChange={handleSelectChange}
|
onValueChange={handleSelectChange}
|
||||||
onOpenChange={() => changeOpen()}
|
onOpenChange={changeOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
triggerClass="modal"
|
triggerClass="modal"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const WeaponModal = ({ gridWeapon, children }: Props) => {
|
||||||
|
|
||||||
const [element, setElement] = useState(-1)
|
const [element, setElement] = useState(-1)
|
||||||
|
|
||||||
const [awakeningType, setAwakeningType] = useState(-1)
|
const [awakeningType, setAwakeningType] = useState(0)
|
||||||
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
const [awakeningLevel, setAwakeningLevel] = useState(1)
|
||||||
|
|
||||||
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
const [primaryAxModifier, setPrimaryAxModifier] = useState(-1)
|
||||||
|
|
@ -298,8 +298,8 @@ const WeaponModal = ({ gridWeapon, children }: Props) => {
|
||||||
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
<h3>{t('modals.weapon.subtitles.awakening')}</h3>
|
||||||
<AwakeningSelect
|
<AwakeningSelect
|
||||||
object="weapon"
|
object="weapon"
|
||||||
awakeningType={gridWeapon.awakening?.type}
|
type={gridWeapon.awakening?.type}
|
||||||
awakeningLevel={gridWeapon.awakening?.level}
|
level={gridWeapon.awakening?.level}
|
||||||
onOpenChange={receiveAwakeningOpen}
|
onOpenChange={receiveAwakeningOpen}
|
||||||
sendValidity={receiveValidity}
|
sendValidity={receiveValidity}
|
||||||
sendValues={receiveAwakeningValues}
|
sendValues={receiveAwakeningValues}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ const WeaponUnit = (props: Props) => {
|
||||||
props.gridWeapon &&
|
props.gridWeapon &&
|
||||||
props.gridWeapon.object.awakening &&
|
props.gridWeapon.object.awakening &&
|
||||||
props.gridWeapon.awakening &&
|
props.gridWeapon.awakening &&
|
||||||
props.gridWeapon.awakening.type >= 0 &&
|
props.gridWeapon.awakening.type > 0 &&
|
||||||
props.gridWeapon.awakening.type != null
|
props.gridWeapon.awakening.type != null
|
||||||
) {
|
) {
|
||||||
const awakening = weaponAwakening.find(
|
const awakening = weaponAwakening.find(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue