Compare commits
No commits in common. "04d26600fd5959ff13337f11dd9e1df1ae8bbb19" and "845b33024297bc919969ed20c436899719734df5" have entirely different histories.
04d26600fd
...
845b330242
@ -12,21 +12,10 @@ const FilePreview = ({ file, style = {} }) => {
|
|||||||
|
|
||||||
const [fileObjectUrl, setFileObjectUrl] = useState(null)
|
const [fileObjectUrl, setFileObjectUrl] = useState(null)
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
const [error, setError] = useState(null)
|
|
||||||
|
|
||||||
const fetchPreview = useCallback(async () => {
|
const fetchPreview = useCallback(async () => {
|
||||||
if (error != null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
console.log('fetching file content', file)
|
|
||||||
const objectUrl = await fetchFileContent(file, false)
|
const objectUrl = await fetchFileContent(file, false)
|
||||||
if (objectUrl == null) {
|
|
||||||
setLoading(false)
|
|
||||||
console.error('Failed to fetch file content', file)
|
|
||||||
setError('Failed to fetch file content')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setFileObjectUrl(objectUrl)
|
setFileObjectUrl(objectUrl)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}, [file, fetchFileContent])
|
}, [file, fetchFileContent])
|
||||||
@ -41,10 +30,6 @@ const FilePreview = ({ file, style = {} }) => {
|
|||||||
return <LoadingPlaceholder message={'Loading file preview...'} />
|
return <LoadingPlaceholder message={'Loading file preview...'} />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != null) {
|
|
||||||
return <div style={{ color: 'red' }}>{error}</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
const isGcode = ['.g', '.gcode'].includes(
|
const isGcode = ['.g', '.gcode'].includes(
|
||||||
(file?.extension || '').toLowerCase()
|
(file?.extension || '').toLowerCase()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -7,14 +7,12 @@ import ObjectSelect from './ObjectSelect'
|
|||||||
import FileList from './FileList'
|
import FileList from './FileList'
|
||||||
import PlusIcon from '../../Icons/PlusIcon'
|
import PlusIcon from '../../Icons/PlusIcon'
|
||||||
import { LoadingOutlined } from '@ant-design/icons'
|
import { LoadingOutlined } from '@ant-design/icons'
|
||||||
import FileIcon from '../../Icons/FileIcon'
|
|
||||||
|
|
||||||
const { Text } = Typography
|
const { Text } = Typography
|
||||||
|
|
||||||
const FileUpload = ({
|
const FileUpload = ({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
minimal = false,
|
|
||||||
multiple = true,
|
multiple = true,
|
||||||
defaultPreviewOpen = false,
|
defaultPreviewOpen = false,
|
||||||
showPreview = true,
|
showPreview = true,
|
||||||
@ -98,15 +96,6 @@ const FileUpload = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minimal == true) {
|
|
||||||
return (
|
|
||||||
<Flex gap={'small'} vertical>
|
|
||||||
<FileIcon file={currentFiles[0]} style={{ fontSize: '24px' }} />
|
|
||||||
<Text>{currentFiles[0]?.name}</Text>
|
|
||||||
</Flex>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex gap={'small'} vertical>
|
<Flex gap={'small'} vertical>
|
||||||
{hasNoItems && uploading == false ? (
|
{hasNoItems && uploading == false ? (
|
||||||
@ -181,8 +170,7 @@ FileUpload.propTypes = {
|
|||||||
multiple: PropTypes.bool,
|
multiple: PropTypes.bool,
|
||||||
showPreview: PropTypes.bool,
|
showPreview: PropTypes.bool,
|
||||||
showInfo: PropTypes.bool,
|
showInfo: PropTypes.bool,
|
||||||
defaultPreviewOpen: PropTypes.bool,
|
defaultPreviewOpen: PropTypes.bool
|
||||||
minimal: PropTypes.bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FileUpload
|
export default FileUpload
|
||||||
|
|||||||
@ -559,7 +559,6 @@ const ObjectProperty = ({
|
|||||||
return (
|
return (
|
||||||
<FileList
|
<FileList
|
||||||
files={value}
|
files={value}
|
||||||
minimal={minimal}
|
|
||||||
multiple={false}
|
multiple={false}
|
||||||
card={false}
|
card={false}
|
||||||
defaultPreviewOpen={previewOpen}
|
defaultPreviewOpen={previewOpen}
|
||||||
@ -573,7 +572,6 @@ const ObjectProperty = ({
|
|||||||
return (
|
return (
|
||||||
<FileList
|
<FileList
|
||||||
files={value}
|
files={value}
|
||||||
minimal={minimal}
|
|
||||||
multiple={true}
|
multiple={true}
|
||||||
defaultPreviewOpen={previewOpen}
|
defaultPreviewOpen={previewOpen}
|
||||||
showPreview={showPreview}
|
showPreview={showPreview}
|
||||||
@ -803,7 +801,6 @@ const ObjectProperty = ({
|
|||||||
return (
|
return (
|
||||||
<FileUpload
|
<FileUpload
|
||||||
multiple={false}
|
multiple={false}
|
||||||
minimal={minimal}
|
|
||||||
defaultPreviewOpen={previewOpen}
|
defaultPreviewOpen={previewOpen}
|
||||||
showPreview={showPreview}
|
showPreview={showPreview}
|
||||||
showInfo={showHyperlink}
|
showInfo={showHyperlink}
|
||||||
@ -814,7 +811,6 @@ const ObjectProperty = ({
|
|||||||
return (
|
return (
|
||||||
<FileUpload
|
<FileUpload
|
||||||
multiple={true}
|
multiple={true}
|
||||||
minimal={minimal}
|
|
||||||
defaultPreviewOpen={previewOpen}
|
defaultPreviewOpen={previewOpen}
|
||||||
showPreview={showPreview}
|
showPreview={showPreview}
|
||||||
showInfo={showHyperlink}
|
showInfo={showHyperlink}
|
||||||
|
|||||||
@ -57,7 +57,6 @@ const PropertyChanges = ({ type, value }) => {
|
|||||||
{...changeProperty}
|
{...changeProperty}
|
||||||
longId={false}
|
longId={false}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
showPreview={false}
|
|
||||||
objectData={value?.old}
|
objectData={value?.old}
|
||||||
maxWidth='200px'
|
maxWidth='200px'
|
||||||
/>
|
/>
|
||||||
@ -72,7 +71,6 @@ const PropertyChanges = ({ type, value }) => {
|
|||||||
{...changeProperty}
|
{...changeProperty}
|
||||||
longId={false}
|
longId={false}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
showPreview={false}
|
|
||||||
objectData={value?.new}
|
objectData={value?.new}
|
||||||
maxWidth='200px'
|
maxWidth='200px'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -42,19 +42,6 @@ const AuthContext = createContext()
|
|||||||
|
|
||||||
const { Text } = Typography
|
const { Text } = Typography
|
||||||
|
|
||||||
const extractUserFromAuthData = (authData) => {
|
|
||||||
if (!authData || typeof authData !== 'object') return null
|
|
||||||
if (authData.user && typeof authData.user === 'object') return authData.user
|
|
||||||
|
|
||||||
// Some endpoints may return the "user" fields at the top-level. Only treat it
|
|
||||||
// as a user object if it looks like one (avoid confusing token-only payloads).
|
|
||||||
const looksLikeUser =
|
|
||||||
authData._id || authData.username || authData.email || authData.name
|
|
||||||
if (looksLikeUser) return authData
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const AuthProvider = ({ children }) => {
|
const AuthProvider = ({ children }) => {
|
||||||
const [messageApi, contextHolder] = message.useMessage()
|
const [messageApi, contextHolder] = message.useMessage()
|
||||||
const [notificationApi, notificationContextHolder] =
|
const [notificationApi, notificationContextHolder] =
|
||||||
@ -93,6 +80,19 @@ const AuthProvider = ({ children }) => {
|
|||||||
redirectType = 'app-scheme'
|
redirectType = 'app-scheme'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const extractUserFromAuthData = (authData) => {
|
||||||
|
if (!authData || typeof authData !== 'object') return null
|
||||||
|
if (authData.user && typeof authData.user === 'object') return authData.user
|
||||||
|
|
||||||
|
// Some endpoints may return the "user" fields at the top-level. Only treat it
|
||||||
|
// as a user object if it looks like one (avoid confusing token-only payloads).
|
||||||
|
const looksLikeUser =
|
||||||
|
authData._id || authData.username || authData.email || authData.name
|
||||||
|
if (looksLikeUser) return authData
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const isSessionExpired = (session) => {
|
const isSessionExpired = (session) => {
|
||||||
if (!session?.expiresAt) return true
|
if (!session?.expiresAt) return true
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
@ -100,32 +100,6 @@ const AuthProvider = ({ children }) => {
|
|||||||
return expirationDate <= now
|
return expirationDate <= now
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserInfo = useCallback(
|
|
||||||
async (token, getIsCancelled = () => false) => {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`${config.backendUrl}/auth/user`, {
|
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
|
||||||
})
|
|
||||||
if (!getIsCancelled() && response.status === 200 && response.data) {
|
|
||||||
const nextUser = extractUserFromAuthData(response.data)
|
|
||||||
if (nextUser) setUserProfile(nextUser)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (!getIsCancelled()) {
|
|
||||||
logger.debug('Failed to refresh user from API:', err)
|
|
||||||
if (err.response?.status === 401) {
|
|
||||||
setAuthenticated(false)
|
|
||||||
setToken(null)
|
|
||||||
setUserProfile(null)
|
|
||||||
setExpiresAt(null)
|
|
||||||
setShowUnauthorizedModal(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
const persistSession = useCallback(
|
const persistSession = useCallback(
|
||||||
async ({ token: nextToken, expiresAt: nextExpiresAt, user: nextUser }) => {
|
async ({ token: nextToken, expiresAt: nextExpiresAt, user: nextUser }) => {
|
||||||
if (isElectron) {
|
if (isElectron) {
|
||||||
@ -180,10 +154,6 @@ const AuthProvider = ({ children }) => {
|
|||||||
setUserProfile(session.user)
|
setUserProfile(session.user)
|
||||||
setExpiresAt(session.expiresAt)
|
setExpiresAt(session.expiresAt)
|
||||||
setAuthenticated(true)
|
setAuthenticated(true)
|
||||||
|
|
||||||
if (session.user) {
|
|
||||||
getUserInfo(session.token, () => cancelled)
|
|
||||||
}
|
|
||||||
} else if (!cancelled) {
|
} else if (!cancelled) {
|
||||||
setAuthenticated(false)
|
setAuthenticated(false)
|
||||||
setUserProfile(null)
|
setUserProfile(null)
|
||||||
@ -203,10 +173,6 @@ const AuthProvider = ({ children }) => {
|
|||||||
setUserProfile(storedUser)
|
setUserProfile(storedUser)
|
||||||
setExpiresAt(storedExpiresAt)
|
setExpiresAt(storedExpiresAt)
|
||||||
setAuthenticated(true)
|
setAuthenticated(true)
|
||||||
|
|
||||||
if (storedToken && storedUser) {
|
|
||||||
getUserInfo(storedToken, () => cancelled)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (!cancelled) {
|
} else if (!cancelled) {
|
||||||
setAuthenticated(false)
|
setAuthenticated(false)
|
||||||
@ -231,7 +197,7 @@ const AuthProvider = ({ children }) => {
|
|||||||
return () => {
|
return () => {
|
||||||
cancelled = true
|
cancelled = true
|
||||||
}
|
}
|
||||||
}, [isElectron, getAuthSession, clearPersistedSession, getUserInfo])
|
}, [isElectron, getAuthSession, clearPersistedSession])
|
||||||
|
|
||||||
// Set up cookie synchronization between tabs
|
// Set up cookie synchronization between tabs
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -113,11 +113,17 @@ const NotificationProvider = ({ children }) => {
|
|||||||
const unreadCount = notifications.filter((n) => !n.read).length
|
const unreadCount = notifications.filter((n) => !n.read).length
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (authenticated == true && notificationCenterVisible == true) {
|
if (authenticated && notificationCenterVisible) {
|
||||||
fetchNotifications()
|
fetchNotifications()
|
||||||
}
|
}
|
||||||
}, [authenticated, notificationCenterVisible, fetchNotifications])
|
}, [authenticated, notificationCenterVisible, fetchNotifications])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (authenticated) {
|
||||||
|
fetchNotifications()
|
||||||
|
}
|
||||||
|
}, [authenticated, fetchNotifications])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNotificationCenterVisible(false)
|
setNotificationCenterVisible(false)
|
||||||
}, [location.pathname])
|
}, [location.pathname])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user