1
1
import { makeStyles } from "@material-ui/core/styles"
2
- import { useMachine } from "@xstate/react"
3
2
import { useOrganizationId } from "hooks/useOrganizationId"
4
3
import { createContext , FC , Suspense , useContext } from "react"
5
4
import { NavLink , Outlet , useNavigate , useParams } from "react-router-dom"
6
5
import { combineClasses } from "util/combineClasses"
7
- import {
8
- TemplateContext ,
9
- templateMachine ,
10
- } from "xServices/template/templateXService"
11
6
import { Margins } from "components/Margins/Margins"
12
7
import { Stack } from "components/Stack/Stack"
13
- import { Permissions } from "xServices/auth/authXService"
14
8
import { Loader } from "components/Loader/Loader"
15
- import { usePermissions } from "hooks/usePermissions"
16
9
import { TemplatePageHeader } from "./TemplatePageHeader"
17
10
import { AlertBanner } from "components/AlertBanner/AlertBanner"
11
+ import {
12
+ checkAuthorization ,
13
+ getTemplateByName ,
14
+ getTemplateVersion ,
15
+ } from "api/api"
16
+ import { useQuery } from "@tanstack/react-query"
17
+ import { useDashboard } from "components/Dashboard/DashboardProvider"
18
+
19
+ const templatePermissions = ( templateId : string ) => ( {
20
+ canUpdateTemplate : {
21
+ object : {
22
+ resource_type : "template" ,
23
+ resource_id : templateId ,
24
+ } ,
25
+ action : "update" ,
26
+ } ,
27
+ } )
18
28
19
- const useTemplateName = ( ) => {
20
- const { template } = useParams ( )
29
+ const fetchTemplate = async ( orgId : string , templateName : string ) => {
30
+ const template = await getTemplateByName ( orgId , templateName )
31
+ const [ activeVersion , permissions ] = await Promise . all ( [
32
+ getTemplateVersion ( template . active_version_id ) ,
33
+ checkAuthorization ( {
34
+ checks : templatePermissions ( template . id ) ,
35
+ } ) ,
36
+ ] )
21
37
22
- if ( ! template ) {
23
- throw new Error ( "No template found in the URL" )
38
+ return {
39
+ template,
40
+ activeVersion,
41
+ permissions,
24
42
}
25
-
26
- return template
27
43
}
28
44
29
- type TemplateLayoutContextValue = {
30
- context : TemplateContext
31
- permissions ?: Permissions
45
+ const useTemplateData = ( orgId : string , templateName : string ) => {
46
+ return useQuery ( {
47
+ queryKey : [ "template" , templateName ] ,
48
+ queryFn : ( ) => fetchTemplate ( orgId , templateName ) ,
49
+ } )
32
50
}
33
51
52
+ type TemplateLayoutContextValue = Awaited < ReturnType < typeof fetchTemplate > >
53
+
34
54
const TemplateLayoutContext = createContext <
35
55
TemplateLayoutContextValue | undefined
36
56
> ( undefined )
@@ -50,38 +70,30 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({
50
70
} ) => {
51
71
const navigate = useNavigate ( )
52
72
const styles = useStyles ( )
53
- const organizationId = useOrganizationId ( )
54
- const templateName = useTemplateName ( )
55
- const [ templateState , _ ] = useMachine ( templateMachine , {
56
- context : {
57
- templateName,
58
- organizationId,
59
- } ,
60
- } )
61
- const {
62
- template,
63
- permissions : templatePermissions ,
64
- getTemplateError,
65
- } = templateState . context
66
- const permissions = usePermissions ( )
73
+ const orgId = useOrganizationId ( )
74
+ const { template } = useParams ( ) as { template : string }
75
+ const templateData = useTemplateData ( orgId , template )
76
+ const dashboard = useDashboard ( )
67
77
68
- if ( getTemplateError ) {
78
+ if ( templateData . error ) {
69
79
return (
70
80
< div className = { styles . error } >
71
- < AlertBanner severity = "error" error = { getTemplateError } />
81
+ < AlertBanner severity = "error" error = { templateData . error } />
72
82
</ div >
73
83
)
74
84
}
75
85
76
- if ( ! template || ! templatePermissions ) {
86
+ if ( templateData . isLoading || ! templateData . data ) {
77
87
return < Loader />
78
88
}
79
89
80
90
return (
81
91
< >
82
92
< TemplatePageHeader
83
- template = { template }
84
- permissions = { templatePermissions }
93
+ template = { templateData . data . template }
94
+ activeVersion = { templateData . data . activeVersion }
95
+ permissions = { templateData . data . permissions }
96
+ canEditFiles = { dashboard . experiments . includes ( "template_editor" ) }
85
97
onDeleteTemplate = { ( ) => {
86
98
navigate ( "/templates" )
87
99
} }
@@ -92,7 +104,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({
92
104
< Stack direction = "row" spacing = { 0.25 } >
93
105
< NavLink
94
106
end
95
- to = { `/templates/${ template . name } ` }
107
+ to = { `/templates/${ template } ` }
96
108
className = { ( { isActive } ) =>
97
109
combineClasses ( [
98
110
styles . tabItem ,
@@ -103,7 +115,7 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({
103
115
Summary
104
116
</ NavLink >
105
117
< NavLink
106
- to = { `/templates/${ template . name } /permissions` }
118
+ to = { `/templates/${ template } /permissions` }
107
119
className = { ( { isActive } ) =>
108
120
combineClasses ( [
109
121
styles . tabItem ,
@@ -113,14 +125,23 @@ export const TemplateLayout: FC<{ children?: JSX.Element }> = ({
113
125
>
114
126
Permissions
115
127
</ NavLink >
128
+ < NavLink
129
+ to = { `/templates/${ template } /files` }
130
+ className = { ( { isActive } ) =>
131
+ combineClasses ( [
132
+ styles . tabItem ,
133
+ isActive ? styles . tabItemActive : undefined ,
134
+ ] )
135
+ }
136
+ >
137
+ Source Code
138
+ </ NavLink >
116
139
</ Stack >
117
140
</ Margins >
118
141
</ div >
119
142
120
143
< Margins >
121
- < TemplateLayoutContext . Provider
122
- value = { { permissions, context : templateState . context } }
123
- >
144
+ < TemplateLayoutContext . Provider value = { templateData . data } >
124
145
< Suspense fallback = { < Loader /> } > { children } </ Suspense >
125
146
</ TemplateLayoutContext . Provider >
126
147
</ Margins >
0 commit comments