@@ -2,6 +2,7 @@ import "./ApplicationDetail.scss";
22import React , { useEffect , useState } from "react" ;
33import { connectServiceProviderToIdentityProvider , publicServiceProviderByDetail } from "../api/index.js" ;
44import I18n from "../locale/I18n.js" ;
5+ import ExternalLinkIcon from "../icons/external-link.svg" ;
56import { useNavigate , useParams } from "react-router-dom" ;
67import {
78 Button ,
@@ -31,6 +32,7 @@ import {authorities} from "../utils/Permissions.js";
3132import InputField from "../components/InputField.jsx" ;
3233import { mainMenuItems } from "../utils/MenuItems.js" ;
3334import { TabHeader } from "../components/TabHeader.jsx" ;
35+ import { InfoBlock } from "../components/InfoBlock.jsx" ;
3436
3537const confirmationModalOptions = {
3638 makeConnection : "makeConnection" ,
@@ -44,10 +46,11 @@ const tabNames = ["access", "information"]
4446
4547const ApplicationDetail = ( { anonymous, refreshUser} ) => {
4648
47- const { arp, privacy, user, setFlash} = useAppStore ( useShallow ( state => ( {
49+ const { arp, privacy, user, config , setFlash} = useAppStore ( useShallow ( state => ( {
4850 arp : state . arp ,
4951 privacy : state . privacy ,
5052 user : state . user ,
53+ config : state . config ,
5154 setFlash : state . setFlash
5255 } ) ) ) ;
5356
@@ -276,15 +279,49 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
276279
277280 const renderAccessApp = ( ) => {
278281 return (
279- < div >
280- < span > TODO renderAccessApp </ span >
281- < span > readOnly: { readOnly . toString ( ) } </ span >
282+ < div className = "app-access" >
283+ < h2 > { I18n . t ( "appAccess.title" ) } </ h2 >
284+ < InfoBlock className = "no-gap" >
285+ < div className = "grouped" >
286+ < div >
287+ < h3 > { I18n . t ( "appAccess.users" , { name : providerOrganizationName ( I18n . locale , serviceProvider ) } ) } </ h3 >
288+ < p > { I18n . t ( "appAccess.config" ) } </ p >
289+ </ div >
290+ < Button type = { ButtonType . Primary }
291+ onClick = { ( ) => alert ( "ToDo" ) }
292+ txt = { I18n . t ( "forms.edit" ) } />
293+ </ div >
294+ < p > { I18n . t ( "appAccess.accessFor" ) } </ p >
295+ < div className = "access-card" >
296+ < h4 > { I18n . t ( "appAccess.everyBody" , { name : providerOrganizationName ( I18n . locale , serviceProvider ) } ) } </ h4 >
297+ { renderLogo ( user . identityProvider . data . metaDataFields ) }
298+ </ div >
299+ </ InfoBlock >
300+ < InfoBlock className = "no-gap" >
301+ < div className = "grouped" >
302+ < div >
303+ < h3 > { I18n . t ( "appAccess.outSideUsers" ) } </ h3 >
304+ < p > { I18n . t ( "appAccess.roleBasedAccess" ) } </ p >
305+ </ div >
306+ < Button type = { ButtonType . Primary }
307+ onClick = { ( ) => window . open ( config . invite , "_blank" ) . focus ( ) }
308+ icon = { < ExternalLinkIcon /> }
309+ txt = { I18n . t ( "appAccess.roleManagement" ) } />
310+ </ div >
311+ < p > { I18n . t ( "appAccess.accessFor" ) } </ p >
312+ < div className = "access-card" >
313+ < h4 > { I18n . t ( "appAccess.everyBody" , { name : providerOrganizationName ( I18n . locale , serviceProvider ) } ) } </ h4 >
314+ { renderLogo ( user . identityProvider . data . metaDataFields ) }
315+ </ div >
316+ </ InfoBlock >
317+ < p > readOnly: { readOnly . toString ( ) } </ p >
318+ < p > isAccessible: { accessible . toString ( ) } </ p >
282319 </ div >
283320 ) ;
284321 }
285322
286323 const renderInformation = ( ) => {
287- return < span > TODO renderInformation </ span > ;
324+ return renderDetailsApp ( ) ;
288325 }
289326
290327 const renderAccessibleApp = ( ) => {
@@ -385,6 +422,77 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
385422 </ div > ;
386423 }
387424
425+ const renderQuickLinks = ( ) => {
426+ return (
427+ < >
428+ < p className = "info" > { I18n . t ( "applicationDetail.quickLinks" ) } </ p >
429+ < div className = "app-info-block" >
430+ { APPLICATION_LINKS . map ( ( link , index ) =>
431+ externalLink ( link , metaData , index )
432+ ) }
433+ </ div >
434+ </ >
435+ ) ;
436+ }
437+
438+ const renderLogo = metaDataFields => {
439+ const logoUrl = metaDataFields [ "logo:0:url" ] ;
440+ return isEmpty ( logoUrl ) ? < PlaceHolderImage /> : < img src = { logoUrl } alt = "" />
441+ }
442+
443+ const renderDetailsApp = ( ) => {
444+ return (
445+ < div className = "details" >
446+ < div className = "left" >
447+ < p > { providerDescription ( I18n . locale , serviceProvider ) } </ p >
448+ { renderAppAttributes ( ) }
449+ { renderAppPrivacy ( ) }
450+ </ div >
451+ < div className = "right" >
452+ < p className = "license" > { I18n . t ( `applicationDetail.license.${ metaData [ 'coin:ss:license_status' ] || 'license_not_required' } ` ) } </ p >
453+ { renderQuickLinks ( ) }
454+ < p className = "info" > { I18n . t ( "applicationDetail.contractual" ) } </ p >
455+ < p >
456+ < span >
457+ { metaData [ "coin:contractual_base" ] ?
458+ I18n . t ( `applicationDetail.contractualBase.${ metaData [ "coin:contractual_base" ] . toLowerCase ( ) } ` ,
459+ { organisation : providerOrganizationName ( I18n . locale , serviceProvider ) } )
460+ : I18n . t ( "applicationDetail.noInformation" ) }
461+ </ span >
462+ < span
463+ dangerouslySetInnerHTML = { { __html : I18n . t ( "applicationDetail.wiki" ) } } />
464+ </ p >
465+ < p > { I18n . t ( "applicationDetail.contractualInfoOrganization" ,
466+ { name : providerOrganizationName ( I18n . locale , serviceProvider ) } ) } </ p >
467+ < p className = "info" > { I18n . t ( "applicationDetail.supportedEntityCategories" ) } </ p >
468+ < div className = "app-info-block" >
469+ { [ 1 , 2 , 3 , 4 ] . map ( nbr =>
470+ externalLink ( {
471+ locale : "applicationDetail.entityCategory" ,
472+ localeAttribute : true ,
473+ metaData : `coin:entity_categories:${ nbr } ` ,
474+ languageProperty : false
475+ } , metaData , nbr )
476+ ) }
477+ { [ 1 , 2 , 3 , 4 ] . every ( nbr => isEmpty ( metaData [ `coin:entity_categories:${ nbr } ` ] ) ) &&
478+ < p > { I18n . t ( "applicationDetail.none" ) } </ p >
479+ }
480+ </ div >
481+ { metaData [ "mdrpi:RegistrationInfo" ] && (
482+ < div className = "federation-source" >
483+ < p className = "info" > { I18n . t ( 'applicationDetail.interfedSource' ) } </ p >
484+ < span
485+ dangerouslySetInnerHTML = { {
486+ __html : I18n . t ( 'applicationDetail.registrationInfo' , { url : metaData [ "mdrpi:RegistrationInfo" ] } ) ,
487+ } }
488+ />
489+ </ div >
490+ ) }
491+ </ div >
492+ </ div >
493+ ) ;
494+ }
495+
388496 const renderNonAccessibleApp = ( ) => {
389497 return (
390498 < >
@@ -406,8 +514,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
406514 < div className = "inner-application-detail-container" >
407515 < div className = { `application-detail ${ anonymous ? "" : "stand-alone" } ` } >
408516 < div className = "meta-data" >
409- { metaData [ "logo:0:url" ] && < img src = { metaData [ "logo:0:url" ] } alt = "" /> }
410- { ! metaData [ "logo:0:url" ] && < PlaceHolderImage /> }
517+ { renderLogo ( metaData ) }
411518 < div className = "meta-data-name" >
412519 < p className = "organization" >
413520 { providerOrganizationName ( I18n . locale , serviceProvider ) }
@@ -426,59 +533,7 @@ const ApplicationDetail = ({anonymous, refreshUser}) => {
426533 txt = { I18n . t ( `applicationConnect.${ ! isAdminUser ? "requestMember" :
427534 connectWithoutInteraction ? "connect" : "request" } `) } /> }
428535 </ div >
429- < div className = "details" >
430- < div className = "left" >
431- < p > { providerDescription ( I18n . locale , serviceProvider ) } </ p >
432- { renderAppAttributes ( ) }
433- { renderAppPrivacy ( ) }
434- </ div >
435- < div className = "right" >
436- < p className = "license" > { I18n . t ( `applicationDetail.license.${ metaData [ 'coin:ss:license_status' ] || 'license_not_required' } ` ) } </ p >
437- < p className = "info" > { I18n . t ( "applicationDetail.quickLinks" ) } </ p >
438- < div className = "app-info-block" >
439- { APPLICATION_LINKS . map ( ( link , index ) =>
440- externalLink ( link , metaData , index )
441- ) }
442- </ div >
443- < p className = "info" > { I18n . t ( "applicationDetail.contractual" ) } </ p >
444- < p >
445- < span >
446- { metaData [ "coin:contractual_base" ] ?
447- I18n . t ( `applicationDetail.contractualBase.${ metaData [ "coin:contractual_base" ] . toLowerCase ( ) } ` ,
448- { organisation : providerOrganizationName ( I18n . locale , serviceProvider ) } )
449- : I18n . t ( "applicationDetail.noInformation" ) }
450- </ span >
451- < span
452- dangerouslySetInnerHTML = { { __html : I18n . t ( "applicationDetail.wiki" ) } } />
453- </ p >
454- < p > { I18n . t ( "applicationDetail.contractualInfoOrganization" ,
455- { name : providerOrganizationName ( I18n . locale , serviceProvider ) } ) } </ p >
456- < p className = "info" > { I18n . t ( "applicationDetail.supportedEntityCategories" ) } </ p >
457- < div className = "app-info-block" >
458- { [ 1 , 2 , 3 , 4 ] . map ( nbr =>
459- externalLink ( {
460- locale : "applicationDetail.entityCategory" ,
461- localeAttribute : true ,
462- metaData : `coin:entity_categories:${ nbr } ` ,
463- languageProperty : false
464- } , metaData , nbr )
465- ) }
466- { [ 1 , 2 , 3 , 4 ] . every ( nbr => isEmpty ( metaData [ `coin:entity_categories:${ nbr } ` ] ) ) &&
467- < p > { I18n . t ( "applicationDetail.none" ) } </ p >
468- }
469- </ div >
470- { metaData [ "mdrpi:RegistrationInfo" ] && (
471- < div className = "federation-source" >
472- < p className = "info" > { I18n . t ( 'applicationDetail.interfedSource' ) } </ p >
473- < span
474- dangerouslySetInnerHTML = { {
475- __html : I18n . t ( 'applicationDetail.registrationInfo' , { url : metaData [ "mdrpi:RegistrationInfo" ] } ) ,
476- } }
477- />
478- </ div >
479- ) }
480- </ div >
481- </ div >
536+ { renderDetailsApp ( ) }
482537 </ div >
483538 </ div >
484539 </ >
0 commit comments