Private workspace
@@ -250,6 +256,25 @@ function NewFolderModal({ onClose, onCreate }) {
return
}
+function JoinOrganizationModal({ onClose, onJoined }) {
+ const [code, setCode] = useState('')
+ const [organization, setOrganization] = useState(null)
+ const [busy, setBusy] = useState(false)
+ const [error, setError] = useState('')
+ async function find(event) {
+ event.preventDefault(); setBusy(true); setError('')
+ try { setOrganization(await api.lookupOrganization(code.trim().toUpperCase())) }
+ catch (requestError) { setError(errorMessage(requestError)); setOrganization(null) }
+ finally { setBusy(false) }
+ }
+ async function join() {
+ setBusy(true); setError('')
+ try { const result = await api.joinOrganization(code.trim().toUpperCase()); await onJoined(result.message) }
+ catch (requestError) { setError(errorMessage(requestError)); setBusy(false) }
+ }
+ return
{organization && {organization.name}
Code: {organization.code}
}{error && {error}
}
+}
+
function ProfileModal({ user, onClose, onLogout, onDeleted, setToast }) {
const [deleting, setDeleting] = useState(false)
const [password, setPassword] = useState('')
diff --git a/src/hooks/useUploads.js b/src/hooks/useUploads.js
index 4895fbe..b58c2f9 100644
--- a/src/hooks/useUploads.js
+++ b/src/hooks/useUploads.js
@@ -12,7 +12,7 @@ function readHistory() {
}
}
-export function useUploads(onComplete) {
+export function useUploads(onComplete, organizationId) {
const [uploads, setUploadsState] = useState(readHistory)
const fileRefs = useRef(new Map())
const abortRefs = useRef(new Map())
@@ -63,6 +63,7 @@ export function useUploads(onComplete) {
size: file.size,
type: file.type || 'application/octet-stream',
folderId: folderId || null,
+ organizationId,
createdAt: new Date().toISOString(),
status: 'queued',
progress: 0,
@@ -72,7 +73,7 @@ export function useUploads(onComplete) {
setUploads((current) => [entry, ...current])
run(entry, file)
}
- }, [run, setUploads])
+ }, [organizationId, run, setUploads])
const cancel = useCallback((id) => abortRefs.current.get(id)?.abort(), [])
@@ -97,6 +98,7 @@ export function useUploads(onComplete) {
setUploads((current) => current.filter((item) => !finalStatuses.has(item.status)))
}, [setUploads])
- const active = useMemo(() => uploads.filter((item) => !finalStatuses.has(item.status)), [uploads])
- return { uploads, active, enqueue, cancel, retry, remove, clearFinished }
+ const visibleUploads = useMemo(() => uploads.filter((item) => !item.organizationId || item.organizationId === organizationId), [organizationId, uploads])
+ const active = useMemo(() => visibleUploads.filter((item) => !finalStatuses.has(item.status)), [visibleUploads])
+ return { uploads: visibleUploads, active, enqueue, cancel, retry, remove, clearFinished }
}
diff --git a/src/lib/api.js b/src/lib/api.js
index d743ff9..1870cc2 100644
--- a/src/lib/api.js
+++ b/src/lib/api.js
@@ -10,6 +10,8 @@ const client = axios.create({
client.interceptors.request.use(async (config) => {
const token = await window.desktop.session.read()
if (token) config.headers.Authorization = `Bearer ${token}`
+ const organizationId = localStorage.getItem('metatron.drive-organization')
+ if (organizationId) config.headers['X-Organization-Id'] = organizationId
return config
})
@@ -24,6 +26,12 @@ export const api = {
async register(input) {
return (await client.post('/auth/register', input)).data
},
+ async joinOrganization(organizationCode) {
+ return (await client.post('/auth/join', { organizationCode })).data
+ },
+ async lookupOrganization(code) {
+ return (await client.get(`/organizations/lookup/${encodeURIComponent(code)}`)).data.organization
+ },
async me() {
return (await client.get('/auth/me')).data.user
},