11import type { ISetting } from '@rocket.chat/apps-engine/definition/settings' ;
22import type { App , SettingValue } from '@rocket.chat/core-typings' ;
33import { Button , ButtonGroup , Box } from '@rocket.chat/fuselage' ;
4- import { useEffectEvent } from '@rocket.chat/fuselage-hooks' ;
4+ import { useBreakpoints , useEffectEvent } from '@rocket.chat/fuselage-hooks' ;
55import { useTranslation , useRouteParameter , useToastMessageDispatch , usePermission , useRouter } from '@rocket.chat/ui-contexts' ;
66import type { ReactElement } from 'react' ;
77import { useMemo , useCallback } from 'react' ;
@@ -14,6 +14,7 @@ import { handleAPIError } from '../helpers/handleAPIError';
1414import { useAppInfo } from '../hooks/useAppInfo' ;
1515import AppDetails from './tabs/AppDetails' ;
1616import AppLogs from './tabs/AppLogs' ;
17+ import AppLogsFilterContextualBar from './tabs/AppLogs/Filters/AppLogsFilterContextualBar' ;
1718import AppReleases from './tabs/AppReleases' ;
1819import AppRequests from './tabs/AppRequests/AppRequests' ;
1920import AppSecurity from './tabs/AppSecurity/AppSecurity' ;
@@ -23,6 +24,17 @@ import { Page, PageFooter, PageHeader, PageScrollableContentWithShadow } from '.
2324
2425type AppDetailsPageFormData = Record < string , SettingValue > ;
2526
27+ type AppLogsFilterFormData = {
28+ startDate ?: string ;
29+ endDate ?: string ;
30+ startTime ?: string ;
31+ endTime ?: string ;
32+ instance ?: string ;
33+ severity ?: string ;
34+ event ?: string ;
35+ timeFilter ?: string ;
36+ } ;
37+
2638type AppDetailsPageProps = {
2739 id : App [ 'id' ] ;
2840} ;
@@ -35,7 +47,10 @@ const AppDetailsPage = ({ id }: AppDetailsPageProps): ReactElement => {
3547
3648 const tab = useRouteParameter ( 'tab' ) ;
3749 const context = useRouteParameter ( 'context' ) ;
50+ const contextualBar = useRouteParameter ( 'contextualBar' ) ;
3851 const appData = useAppInfo ( id , context || '' ) ;
52+ const breakpoint = useBreakpoints ( ) ; // ["xs", "sm", "md", "lg", "xl", xxl"]
53+ const compactMode = ! breakpoint . includes ( 'lg' ) ;
3954
4055 const handleReturn = useEffectEvent ( ( ) : void => {
4156 if ( ! context ) {
@@ -48,6 +63,20 @@ const AppDetailsPage = ({ id }: AppDetailsPageProps): ReactElement => {
4863 } ) ;
4964 } ) ;
5065
66+ const handleReturnToLogs = useEffectEvent ( ( ) : void => {
67+ if ( ! context ) {
68+ return ;
69+ }
70+
71+ router . navigate (
72+ {
73+ name : 'marketplace' ,
74+ params : { ...router . getRouteParameters ( ) , contextualBar : '' } ,
75+ } ,
76+ { replace : true } ,
77+ ) ;
78+ } ) ;
79+
5180 const { installed, settings, privacyPolicySummary, permissions, tosLink, privacyLink, name } = appData || { } ;
5281 const isSecurityVisible = Boolean ( privacyPolicySummary || permissions || tosLink || privacyLink ) ;
5382
@@ -58,12 +87,14 @@ const AppDetailsPage = ({ id }: AppDetailsPageProps): ReactElement => {
5887 ) ;
5988 } , [ settings ] ) ;
6089
61- const methods = useForm < AppDetailsPageFormData > ( { values : reducedSettings } ) ;
90+ const settingsFormMethods = useForm < AppDetailsPageFormData > ( { values : reducedSettings } ) ;
6291 const {
6392 handleSubmit,
6493 reset,
6594 formState : { isDirty, isSubmitting } ,
66- } = methods ;
95+ } = settingsFormMethods ;
96+
97+ const logsFilterFormMethods = useForm < AppLogsFilterFormData > ( { defaultValues : { severity : 'all' , instance : 'all' , timeFilter : 'all' } } ) ;
6798
6899 const saveAppSettings = useCallback (
69100 async ( data : AppDetailsPageFormData ) => {
@@ -81,56 +112,67 @@ const AppDetailsPage = ({ id }: AppDetailsPageProps): ReactElement => {
81112 handleAPIError ( e ) ;
82113 }
83114 } ,
84- [ dispatchToastMessage , id , name , settings , reset ] ,
115+ [ id , settings , reset , dispatchToastMessage , t , name ] ,
85116 ) ;
86117
87118 return (
88- < Page flexDirection = 'column' h = 'full' >
89- < PageHeader title = { t ( 'App_Info' ) } onClickBack = { handleReturn } />
90- < PageScrollableContentWithShadow pi = { 24 } pbs = { 24 } pbe = { 0 } h = 'full' >
91- < Box w = 'full' alignSelf = 'center' h = 'full' display = 'flex' flexDirection = 'column' >
92- { ! appData && < AppDetailsPageLoading /> }
93- { appData && (
94- < >
95- < AppDetailsPageHeader app = { appData } />
96- < AppDetailsPageTabs
97- context = { context || '' }
98- installed = { installed }
99- isSecurityVisible = { isSecurityVisible }
100- settings = { settings }
101- tab = { tab }
102- />
103- { Boolean ( ! tab || tab === 'details' ) && < AppDetails app = { appData } /> }
104- { tab === 'requests' && < AppRequests id = { id } isAdminUser = { isAdminUser } /> }
105- { tab === 'security' && isSecurityVisible && (
106- < AppSecurity
107- privacyPolicySummary = { privacyPolicySummary }
108- appPermissions = { permissions }
109- tosLink = { tosLink }
110- privacyLink = { privacyLink }
119+ < Page flexDirection = 'row' >
120+ < Page flexDirection = 'column' h = 'full' >
121+ < PageHeader title = { t ( 'App_Info' ) } onClickBack = { handleReturn } />
122+ < PageScrollableContentWithShadow pi = { 24 } pbs = { 24 } pbe = { 0 } h = 'full' >
123+ < Box w = 'full' alignSelf = 'center' h = 'full' display = 'flex' flexDirection = 'column' >
124+ { ! appData && < AppDetailsPageLoading /> }
125+ { appData && (
126+ < >
127+ < AppDetailsPageHeader app = { appData } />
128+ < AppDetailsPageTabs
129+ context = { context || '' }
130+ installed = { installed }
131+ isSecurityVisible = { isSecurityVisible }
132+ settings = { settings }
133+ tab = { tab }
111134 />
112- ) }
113- { tab === 'releases' && < AppReleases id = { id } /> }
114- { Boolean ( tab === 'settings' && settings && Object . values ( settings ) . length ) && (
115- < FormProvider { ...methods } >
116- < AppSettings settings = { settings || { } } />
117- </ FormProvider >
118- ) }
119- { tab === 'logs' && < AppLogs id = { id } /> }
120- </ >
121- ) }
122- </ Box >
123- </ PageScrollableContentWithShadow >
124- < PageFooter isDirty = { isDirty } >
125- < ButtonGroup >
126- < Button onClick = { ( ) => reset ( ) } > { t ( 'Cancel' ) } </ Button >
127- { installed && isAdminUser && (
128- < Button primary loading = { isSubmitting } onClick = { handleSubmit ( saveAppSettings ) } >
129- { t ( 'Save_changes' ) }
130- </ Button >
131- ) }
132- </ ButtonGroup >
133- </ PageFooter >
135+ { Boolean ( ! tab || tab === 'details' ) && < AppDetails app = { appData } /> }
136+ { tab === 'requests' && < AppRequests id = { id } isAdminUser = { isAdminUser } /> }
137+ { tab === 'security' && isSecurityVisible && (
138+ < AppSecurity
139+ privacyPolicySummary = { privacyPolicySummary }
140+ appPermissions = { permissions }
141+ tosLink = { tosLink }
142+ privacyLink = { privacyLink }
143+ />
144+ ) }
145+ { tab === 'releases' && < AppReleases id = { id } /> }
146+ { Boolean ( tab === 'settings' && settings && Object . values ( settings ) . length ) && (
147+ < FormProvider { ...settingsFormMethods } >
148+ < AppSettings settings = { settings || { } } />
149+ </ FormProvider >
150+ ) }
151+ { ( tab === 'logs' || tab === 'logs-filter' ) && (
152+ < FormProvider { ...logsFilterFormMethods } >
153+ < AppLogs id = { id } />
154+ </ FormProvider >
155+ ) }
156+ </ >
157+ ) }
158+ </ Box >
159+ </ PageScrollableContentWithShadow >
160+ < PageFooter isDirty = { isDirty } >
161+ < ButtonGroup >
162+ < Button onClick = { ( ) => reset ( ) } > { t ( 'Cancel' ) } </ Button >
163+ { installed && isAdminUser && (
164+ < Button primary loading = { isSubmitting } onClick = { handleSubmit ( saveAppSettings ) } >
165+ { t ( 'Save_changes' ) }
166+ </ Button >
167+ ) }
168+ </ ButtonGroup >
169+ </ PageFooter >
170+ </ Page >
171+ { compactMode && contextualBar === 'filter-logs' && (
172+ < FormProvider { ...logsFilterFormMethods } >
173+ < AppLogsFilterContextualBar onClose = { handleReturnToLogs } />
174+ </ FormProvider >
175+ ) }
134176 </ Page >
135177 ) ;
136178} ;
0 commit comments