All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced NavigationTabsContext to manage tab state and navigation within the dashboard. - Added DashboardTabs component for improved tabbed navigation, allowing users to add, close, and reorder tabs. - Enhanced Dashboard layout to conditionally render tab panes based on the active tab, improving user experience. - Updated various components to utilize navigation tab context, ensuring consistent title management and tab interactions. - Implemented drag-and-drop functionality for tabs, enabling users to rearrange their workspace effectively. - Refactored CSS styles for dashboard tabs and panes to ensure proper layout and responsiveness across devices.
178 lines
5.3 KiB
JavaScript
178 lines
5.3 KiB
JavaScript
import { BrowserView } from 'electrobun/bun'
|
|
import {
|
|
checkForCompletedUpdate,
|
|
getRunningAppVersion,
|
|
startAppUpdate
|
|
} from './appupdate.js'
|
|
import {
|
|
checkForDuplicateInstallations,
|
|
removeDuplicateInstallations
|
|
} from './check-duplicate-installations.js'
|
|
import { setSidebarViewMenu } from './menu.js'
|
|
import { sendToAllWindows, sendToRenderer, sendToWindow } from './notify.js'
|
|
import { resizeSpotlightWindow } from './spotlight.js'
|
|
import {
|
|
clearAuthSession,
|
|
getAppSettings,
|
|
getAuthSession,
|
|
setAppSettings,
|
|
setAuthSession
|
|
} from './store.js'
|
|
import {
|
|
createAppWindow,
|
|
getMainWindow,
|
|
getWindowSession,
|
|
getWindowState,
|
|
handleWindowControl,
|
|
openExternalUrl,
|
|
openInternalUrl,
|
|
syncWindowTabs,
|
|
beginTabDrag,
|
|
completeTabDrop,
|
|
cancelTabDrag
|
|
} from './window.js'
|
|
|
|
export function createAppRpc() {
|
|
const requestHandlers = {
|
|
getOsInfo: async () => ({
|
|
platform: process.platform
|
|
}),
|
|
getWindowState: async ({ windowId } = {}) => getWindowState(windowId),
|
|
windowControl: async ({ action, windowId } = {}) => {
|
|
handleWindowControl(action, windowId)
|
|
return { ok: true }
|
|
},
|
|
syncWindowTabs: async ({ windowId, activeTabId, tabs } = {}) => ({
|
|
ok: syncWindowTabs(windowId, { activeTabId, tabs })
|
|
}),
|
|
getWindowSession: async ({ windowId } = {}) => getWindowSession(windowId),
|
|
createAppWindow: async ({
|
|
tabs,
|
|
activeTabId,
|
|
windowId
|
|
} = {}) => {
|
|
await createAppWindow({
|
|
tabs,
|
|
activeTabId,
|
|
sourceWindowId: windowId
|
|
})
|
|
return { ok: true }
|
|
},
|
|
beginTabDrag: async ({ windowId, tab } = {}) =>
|
|
beginTabDrag({ windowId, tab }),
|
|
completeTabDrop: async ({ windowId, beforeTabId, insertBefore } = {}) =>
|
|
completeTabDrop({ windowId, beforeTabId, insertBefore }),
|
|
cancelTabDrag: async ({ windowId } = {}) => cancelTabDrag({ windowId }),
|
|
openExternalUrl: async ({ url }) => {
|
|
openExternalUrl(url)
|
|
return { ok: true }
|
|
},
|
|
openInternalUrl: async ({ url }) => ({
|
|
ok: openInternalUrl(url)
|
|
}),
|
|
getAuthSession: async () => getAuthSession(),
|
|
setAuthSession: async ({ session }) => ({
|
|
ok: await setAuthSession(session)
|
|
}),
|
|
clearAuthSession: async () => ({
|
|
ok: await clearAuthSession()
|
|
}),
|
|
getAppSettings: async () => getAppSettings(),
|
|
setAppSettings: async ({ settings }) => ({
|
|
ok: await setAppSettings(settings)
|
|
}),
|
|
startAppUpdate: async ({ update }) => {
|
|
const mainWindow = getMainWindow()
|
|
const sendProgress = (payload) => {
|
|
sendToAllWindows('appUpdateProgress', {
|
|
timestamp: new Date().toISOString(),
|
|
...payload
|
|
})
|
|
}
|
|
|
|
// Updates can take several minutes; return immediately and report
|
|
// progress via appUpdateProgress messages instead of blocking RPC.
|
|
void startAppUpdate(mainWindow, update, sendProgress).catch((error) => {
|
|
console.error('App update failed:', error)
|
|
})
|
|
return { ok: true }
|
|
},
|
|
resizeSpotlightWindow: async ({ height }) => ({
|
|
ok: resizeSpotlightWindow(height)
|
|
}),
|
|
setSidebarViewMenu: async ({ sections }) => ({
|
|
ok: setSidebarViewMenu(sections)
|
|
}),
|
|
checkAppUpdateResult: async () =>
|
|
checkForCompletedUpdate(getMainWindow()),
|
|
checkDuplicateInstallations: async () => checkForDuplicateInstallations(),
|
|
removeDuplicateInstallations: async () => {
|
|
// Removal waits on an admin/UAC prompt which can outlive the RPC
|
|
// timeout; report the outcome via a push message instead.
|
|
void removeDuplicateInstallations()
|
|
.catch((error) => ({
|
|
ok: false,
|
|
error:
|
|
error?.message || 'Failed to remove the duplicate installation.'
|
|
}))
|
|
.then((result) => {
|
|
sendToAllWindows('duplicateInstallationsRemoved', result)
|
|
})
|
|
return { ok: true }
|
|
},
|
|
getAppVersion: async () => getRunningAppVersion() || 'desktop',
|
|
getAppEngine: async () => {
|
|
const mainWindow = getMainWindow()
|
|
const renderer = mainWindow?.renderer || 'native'
|
|
return renderer === 'cef' ? 'chromium' : 'native'
|
|
}
|
|
}
|
|
|
|
return BrowserView.defineRPC({
|
|
maxRequestTime: 30000,
|
|
handlers: {
|
|
requests: requestHandlers,
|
|
messages: {
|
|
rendererRequest: ({ id, method, params, windowId }) => {
|
|
const requestParams = params || {}
|
|
const requestWindowId = windowId || requestParams.windowId
|
|
const respond = (payload) => {
|
|
if (requestWindowId) {
|
|
sendToWindow(requestWindowId, 'rpcResponse', payload)
|
|
return
|
|
}
|
|
sendToRenderer('rpcResponse', payload)
|
|
}
|
|
|
|
const handler = requestHandlers[method]
|
|
if (!handler) {
|
|
respond({
|
|
id,
|
|
success: false,
|
|
error: `Unknown desktop RPC method: ${String(method)}`
|
|
})
|
|
return
|
|
}
|
|
|
|
void Promise.resolve()
|
|
.then(() => handler(requestParams))
|
|
.then((result) => {
|
|
respond({
|
|
id,
|
|
success: true,
|
|
result
|
|
})
|
|
})
|
|
.catch((error) => {
|
|
respond({
|
|
id,
|
|
success: false,
|
|
error: error?.message || String(error)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|