robobyte-front-builder 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/pages/viewer/[id]/index.js +87 -14
package/package.json
CHANGED
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
import { useRouter } from 'next/router'
|
|
2
|
-
import { useEffect, useState, useContext } from 'react'
|
|
3
|
-
import { Box, Typography, CircularProgress, Grid } from '@mui/material'
|
|
2
|
+
import { useEffect, useState, useContext, useMemo } from 'react'
|
|
3
|
+
import { Box, Typography, CircularProgress, Grid, Tab, Tabs } from '@mui/material'
|
|
4
4
|
import { SystemContext } from 'context/SystemContext'
|
|
5
5
|
import { Endpoints, Services } from 'services/Endpoints'
|
|
6
6
|
import ProductionViewer from 'views/builder/viewer/ProductionViewer'
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Finds the parent group of a viewId in the navigator config items tree.
|
|
10
|
+
* Returns the array of siblings (all dynamic children of that parent).
|
|
11
|
+
*
|
|
12
|
+
* nav.config.items shape:
|
|
13
|
+
* [ { title, children: [ { title, type, viewId }, ... ] }, ... ]
|
|
14
|
+
*/
|
|
15
|
+
function findSiblings(navConfig, viewId) {
|
|
16
|
+
if (!navConfig?.items || viewId == null) return []
|
|
17
|
+
for (const group of navConfig.items) {
|
|
18
|
+
const children = group.children || []
|
|
19
|
+
const dynamicChildren = children.filter(c => c.type === 'dynamic' && c.viewId != null)
|
|
20
|
+
const found = dynamicChildren.find(c => Number(c.viewId) === Number(viewId))
|
|
21
|
+
if (found) return dynamicChildren
|
|
22
|
+
}
|
|
23
|
+
return []
|
|
24
|
+
}
|
|
25
|
+
|
|
8
26
|
export default function ViewPage() {
|
|
9
27
|
const router = useRouter()
|
|
10
28
|
const { id } = router.query
|
|
11
29
|
const systemContext = useContext(SystemContext)
|
|
12
30
|
const viewRegistry = systemContext.nav?.registry || {}
|
|
31
|
+
const navConfig = systemContext.nav?.config
|
|
13
32
|
|
|
14
33
|
const [schema, setSchema] = useState({})
|
|
15
34
|
const [viewMetaData, setViewMetaData] = useState({})
|
|
16
35
|
const [loading, setLoading] = useState(true)
|
|
17
36
|
const [error, setError] = useState(null)
|
|
18
37
|
|
|
38
|
+
// Sibling pages under the same root section — used for horizontal sub-nav tabs
|
|
39
|
+
const siblings = useMemo(() => findSiblings(navConfig, id), [navConfig, id])
|
|
40
|
+
|
|
19
41
|
const handleGetView = async (viewId) => {
|
|
20
42
|
try {
|
|
21
43
|
setLoading(true)
|
|
@@ -51,7 +73,6 @@ export default function ViewPage() {
|
|
|
51
73
|
}
|
|
52
74
|
}, [id])
|
|
53
75
|
|
|
54
|
-
// Loading state
|
|
55
76
|
if (!id) return null
|
|
56
77
|
|
|
57
78
|
if (loading) {
|
|
@@ -68,21 +89,73 @@ export default function ViewPage() {
|
|
|
68
89
|
const view = viewRegistry[viewId]
|
|
69
90
|
|
|
70
91
|
return (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
92
|
+
<>
|
|
93
|
+
{siblings.length > 1 && (
|
|
94
|
+
<HorizontalSubNav siblings={siblings} currentId={viewId} router={router} />
|
|
95
|
+
)}
|
|
96
|
+
<Box sx={{ p: 6, textAlign: 'center' }}>
|
|
97
|
+
<Typography variant="h4">Coming soon 🚧</Typography>
|
|
98
|
+
<Typography variant="body2" sx={{ mt: 2 }}>
|
|
99
|
+
View #{viewId} {view ? `(${view.name})` : ''} has not been created yet.
|
|
100
|
+
</Typography>
|
|
101
|
+
</Box>
|
|
102
|
+
</>
|
|
77
103
|
)
|
|
78
104
|
}
|
|
79
105
|
|
|
80
|
-
// Success state
|
|
106
|
+
// Success state
|
|
81
107
|
return (
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
<
|
|
108
|
+
<Box>
|
|
109
|
+
{siblings.length > 1 && (
|
|
110
|
+
<HorizontalSubNav siblings={siblings} currentId={Number(id)} router={router} />
|
|
111
|
+
)}
|
|
112
|
+
<Grid container>
|
|
113
|
+
<Grid item size={12}>
|
|
114
|
+
<ProductionViewer schema={schema} />
|
|
115
|
+
</Grid>
|
|
85
116
|
</Grid>
|
|
86
|
-
</
|
|
117
|
+
</Box>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Horizontal sub-navigation tabs shown at the top of the viewer page
|
|
123
|
+
* when the current view has sibling pages under the same root section.
|
|
124
|
+
*/
|
|
125
|
+
function HorizontalSubNav({ siblings, currentId, router }) {
|
|
126
|
+
const currentIndex = siblings.findIndex(s => Number(s.viewId) === Number(currentId))
|
|
127
|
+
const activeTab = currentIndex >= 0 ? currentIndex : 0
|
|
128
|
+
|
|
129
|
+
const handleChange = (_, newIndex) => {
|
|
130
|
+
const target = siblings[newIndex]
|
|
131
|
+
if (target?.viewId != null) {
|
|
132
|
+
router.push(`/viewer/${target.viewId}`)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<Box
|
|
138
|
+
sx={{
|
|
139
|
+
borderBottom: 1,
|
|
140
|
+
borderColor: 'divider',
|
|
141
|
+
mb: 2,
|
|
142
|
+
backgroundColor: 'background.paper',
|
|
143
|
+
px: 2,
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<Tabs
|
|
147
|
+
value={activeTab}
|
|
148
|
+
onChange={handleChange}
|
|
149
|
+
variant="scrollable"
|
|
150
|
+
scrollButtons="auto"
|
|
151
|
+
>
|
|
152
|
+
{siblings.map((sibling) => (
|
|
153
|
+
<Tab
|
|
154
|
+
key={sibling.viewId}
|
|
155
|
+
label={sibling.title}
|
|
156
|
+
/>
|
|
157
|
+
))}
|
|
158
|
+
</Tabs>
|
|
159
|
+
</Box>
|
|
87
160
|
)
|
|
88
161
|
}
|