149 lines
4.2 KiB
TypeScript
149 lines
4.2 KiB
TypeScript
|
|
import Input from '@/components/ui/Input'
|
|||
|
|
import { getTenantByNameDetail } from '@/services/tenant.service'
|
|||
|
|
import { useStoreActions, useStoreState } from '@/store'
|
|||
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|||
|
|
import { defaultDomain, getSubdomain } from '@/utils/subdomain'
|
|||
|
|
import type { CSSProperties } from 'react'
|
|||
|
|
import { useCallback, useEffect, useRef } from 'react'
|
|||
|
|
|
|||
|
|
const hiddenTenantStyle: CSSProperties = {
|
|||
|
|
opacity: 0,
|
|||
|
|
position: 'absolute',
|
|||
|
|
pointerEvents: 'none',
|
|||
|
|
height: 0,
|
|||
|
|
margin: 0,
|
|||
|
|
padding: 0,
|
|||
|
|
border: 'none',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const TenantSelector = () => {
|
|||
|
|
const { translate } = useLocalization()
|
|||
|
|
const isMultiTenant = useStoreState((state) => state.abpConfig.config?.multiTenancy.isEnabled)
|
|||
|
|
const tenantName = useStoreState((state) => state.locale.currentTenantName)
|
|||
|
|
const { setTenantName } = useStoreActions((actions) => actions.locale)
|
|||
|
|
const { setTenant } = useStoreActions((actions) => actions.auth.tenant)
|
|||
|
|
const { setWarning } = useStoreActions((actions) => actions.base.messages)
|
|||
|
|
const requestIdRef = useRef(0)
|
|||
|
|
const lastRequestedTenantNameRef = useRef<string>()
|
|||
|
|
|
|||
|
|
const subDomainName = getSubdomain()
|
|||
|
|
const isSubdomainTenant = !!subDomainName && subDomainName !== defaultDomain
|
|||
|
|
const tenantStyle = isSubdomainTenant ? hiddenTenantStyle : undefined
|
|||
|
|
|
|||
|
|
const setWarningTimeout = useCallback(
|
|||
|
|
(message: string) => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
setWarning(message)
|
|||
|
|
}, 100)
|
|||
|
|
},
|
|||
|
|
[setWarning],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const redirectToMainDomain = useCallback(
|
|||
|
|
(name: string) => {
|
|||
|
|
setTenantName(undefined)
|
|||
|
|
const parts = window.location.hostname.split('.')
|
|||
|
|
const mainDomain = parts.length >= 3 ? parts.slice(1).join('.') : window.location.hostname
|
|||
|
|
setWarningTimeout(
|
|||
|
|
`"${name}" kurumuna ait kayıt bulunamadı.\nAna sayfaya yönlendiriliyorsunuz...`,
|
|||
|
|
)
|
|||
|
|
setTimeout(() => {
|
|||
|
|
window.location.href = `${window.location.protocol}//${mainDomain}`
|
|||
|
|
}, 3000)
|
|||
|
|
},
|
|||
|
|
[setTenantName, setWarningTimeout],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const fetchDataByName = useCallback(
|
|||
|
|
async (name: string, isSubdomain = false) => {
|
|||
|
|
if (!isSubdomain && name === lastRequestedTenantNameRef.current) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
lastRequestedTenantNameRef.current = name
|
|||
|
|
const requestId = requestIdRef.current + 1
|
|||
|
|
requestIdRef.current = requestId
|
|||
|
|
|
|||
|
|
if (name) {
|
|||
|
|
try {
|
|||
|
|
const response = await getTenantByNameDetail(name)
|
|||
|
|
|
|||
|
|
if (requestId !== requestIdRef.current) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (response.data) {
|
|||
|
|
setTenant({
|
|||
|
|
tenantId: response.data.id,
|
|||
|
|
tenantName: response.data.name,
|
|||
|
|
menuGroup: response.data.menuGroup,
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
setTenant(undefined)
|
|||
|
|
if (isSubdomain) redirectToMainDomain(name)
|
|||
|
|
}
|
|||
|
|
} catch {
|
|||
|
|
if (requestId !== requestIdRef.current) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setTenant(undefined)
|
|||
|
|
if (isSubdomain) redirectToMainDomain(name)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
setTenant(undefined)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
[redirectToMainDomain, setTenant],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const handleTenantNameChange = (value: string) => {
|
|||
|
|
setTenantName(value)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleTenantNameBlur = () => {
|
|||
|
|
if (subDomainName) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fetchDataByName(tenantName || '')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
if (!isMultiTenant) {
|
|||
|
|
setTenant(undefined)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (subDomainName) {
|
|||
|
|
setTenantName(subDomainName)
|
|||
|
|
fetchDataByName(subDomainName, true)
|
|||
|
|
}
|
|||
|
|
}, [fetchDataByName, isMultiTenant, setTenant, setTenantName, subDomainName])
|
|||
|
|
|
|||
|
|
if (!isMultiTenant) {
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<>
|
|||
|
|
<label className="form-label mb-2" style={tenantStyle}>
|
|||
|
|
{translate('::Organization')}
|
|||
|
|
</label>
|
|||
|
|
<div className="mb-4">
|
|||
|
|
<Input
|
|||
|
|
placeholder={translate('::Organization')}
|
|||
|
|
value={tenantName ?? ''}
|
|||
|
|
onChange={(event) => handleTenantNameChange(event.target.value)}
|
|||
|
|
onBlur={handleTenantNameBlur}
|
|||
|
|
style={tenantStyle}
|
|||
|
|
aria-hidden={isSubdomainTenant ? 'true' : 'false'}
|
|||
|
|
autoFocus={!isSubdomainTenant}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default TenantSelector
|