Skip to content

Commit 98f652e

Browse files
committed
Applications - Token URL column and error handling improvements
1 parent 3f6c973 commit 98f652e

File tree

12 files changed

+69
-20
lines changed

12 files changed

+69
-20
lines changed

src/components/applications/application-details/applicationDetails.design.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export class ApplicationDetailsDesignModule implements IInjectorModule {
4646
handlerComponent: ApplicationDetailsHandlers
4747
});
4848
}
49+
})
50+
.catch((error) => {
51+
logger.trackError(error, { message: "Failed to get feature value for client applications in ApplicationDetailsDesignModule." });
4952
}
5053
);
5154
}

src/components/applications/application-details/applicationDetails.publish.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export class ApplicationDetailsPublishModule implements IInjectorModule {
3333
componentFlow: ComponentFlow.Block
3434
});
3535
}
36+
})
37+
.catch((error) => {
38+
logger.trackError(error, { message: "Failed to get feature value for client applications in ApplicationDetailsPublishModule." });
3639
}
3740
);
3841
}

src/components/applications/application-details/react/runtime/ApplicationDetails.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from "react";
22
import { useEffect, useState } from "react";
3+
import { Logger } from "@paperbits/common/logging";
34
import {
45
Button,
56
MessageBar,
@@ -38,12 +39,14 @@ export const ApplicationDetails = ({
3839
usersService,
3940
productService,
4041
applicationService,
42+
logger,
4143
applicationName,
4244
getProductReferenceUrl
4345
}: {
4446
usersService: UsersService,
4547
applicationService: ApplicationService,
4648
productService: ProductService,
49+
logger: Logger,
4750
applicationName: string,
4851
getProductReferenceUrl: (productName: string) => string
4952
}) => {
@@ -74,7 +77,7 @@ export const ApplicationDetails = ({
7477
return;
7578
}
7679

77-
throw new Error(`Unable to load application ${applicationName}. Error: ${error.message}`);
80+
logger.trackError(error, { message: `Unable to load application ${applicationName}.` });
7881
});
7982

8083
loadApplicationProducts(applicationName)
@@ -94,8 +97,8 @@ export const ApplicationDetails = ({
9497
try {
9598
application = await applicationService.getApplication(userId, applicationName);
9699
} catch (error) {
97-
setError("Application is not selected.");
98-
//throw new Error(`Unable to load application ${applicationName}. Error: ${error.message}`);
100+
setError(`Unable to load application.`);
101+
logger.trackError(error, { message: `Unable to load application ${applicationName}.` });
99102
}
100103

101104
return application;
@@ -107,7 +110,7 @@ export const ApplicationDetails = ({
107110
try {
108111
clientSecret = await applicationService.createNewSecret(userId, applicationName);
109112
} catch (error) {
110-
throw new Error(`Unable to generate client secret for application ${applicationName}. Error: ${error.message}`);
113+
logger.trackError(error, { message: `Unable to generate client secret for application ${applicationName}.` });
111114
}
112115

113116
return clientSecret;
@@ -119,7 +122,7 @@ export const ApplicationDetails = ({
119122
try {
120123
products = await applicationService.getApplicationProducts(userId, applicationName);
121124
} catch (error) {
122-
//throw new Error(`Unable to load products for application ${applicationName}. Error: ${error.message}`);
125+
logger.trackError(error, { message: `Unable to load products for application ${applicationName}.` });
123126
}
124127

125128
return products;
@@ -133,14 +136,22 @@ export const ApplicationDetails = ({
133136

134137
return (
135138
<>
136-
{error ? (
139+
{(error || !application) ? (
137140
<MessageBar intent="error">
138141
<MessageBarBody>{error}</MessageBarBody>
139142
</MessageBar>
140143
) : (
141144
<>
142145
<h1>{application.name}</h1>
143146
<span className="caption1">Application</span>
147+
<MessageBar intent="info" className="mt-15 mb-20">
148+
<MessageBarBody>
149+
<span className="caption1">
150+
To call the API, you will need to retrieve the OAuth token and call the API gateway endpoint.{` `}
151+
<a href="http://aka.ms/apimappsclientcredflow" target="_blank">View documentation</a>
152+
</span>
153+
</MessageBarBody>
154+
</MessageBar>
144155
<div className={"fui-application-details-container"}>
145156
<h3>Application</h3>
146157
<ScrollableTableContainer>
@@ -149,6 +160,7 @@ export const ApplicationDetails = ({
149160
<TableRow className={"fui-table-headerRow"}>
150161
<TableHeaderCell><span className="strong">Entra Application ID</span></TableHeaderCell>
151162
<TableHeaderCell><span className="strong">Client Secret</span></TableHeaderCell>
163+
<TableHeaderCell><span className="strong">Token URL</span></TableHeaderCell>
152164
</TableRow>
153165
</TableHeader>
154166
<TableBody>
@@ -216,13 +228,15 @@ export const ApplicationDetails = ({
216228
</PopoverSurface>
217229
</Popover>
218230
</TableCell>
231+
<TableCell>{application.entraTenantId && `https://login.microsoftonline.com/${application.entraTenantId}/oauth2/v2.0/token`}</TableCell>
219232
</TableRow>
220233
</TableBody>
221234
</Table>
222235
</ScrollableTableContainer>
223236
<ApplicationsProducts
224237
products={products}
225238
productService={productService}
239+
logger={logger}
226240
getProductReferenceUrl={getProductReferenceUrl}
227241
/>
228242
</div>

src/components/applications/application-details/react/runtime/ApplicationProducts.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from "react";
22
import { useEffect, useState } from "react";
3+
import { Logger } from "@paperbits/common/logging";
34
import { Spinner, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableRow } from "@fluentui/react-components";
45
import { CheckmarkCircleFilled, ChevronDownRegular, ChevronRightRegular } from "@fluentui/react-icons";
56
import { Product } from "../../../../../models/product";
@@ -53,10 +54,12 @@ const ProductRow = ({
5354
export const ApplicationsProducts = ({
5455
products,
5556
productService,
57+
logger,
5658
getProductReferenceUrl
5759
}: {
5860
products: Product[],
5961
productService: ProductService,
62+
logger: Logger,
6063
getProductReferenceUrl: (productName: string) => string
6164
}) => {
6265
const [loadedProducts, setLoadedProducts] = useState<Product[]>([]);
@@ -81,7 +84,7 @@ export const ApplicationsProducts = ({
8184
try {
8285
product = await productService.getProduct(productName);
8386
} catch (error) {
84-
throw new Error(`Unable to load product ${productName}. Error: ${error.message}`);
87+
logger.trackError(error, { message: `Unable to load product ${productName}.` });
8588
}
8689

8790
return product;

src/components/applications/application-details/react/runtime/ApplicationsDetailsRuntime.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from "react";
22
import { FluentProvider } from "@fluentui/react-components";
33
import { Resolve } from "@paperbits/react/decorators";
44
import { Router } from "@paperbits/common/routing";
5+
import { Logger } from "@paperbits/common/logging";
56
import { RouteHelper } from "../../../../../routing/routeHelper";
67
import { ProductService } from "../../../../../services/productService";
78
import { UsersService } from "../../../../../services";
@@ -33,6 +34,9 @@ export class ApplicationsDetailsRuntime extends React.Component<ApplicationsDeta
3334
@Resolve("router")
3435
public router: Router;
3536

37+
@Resolve("logger")
38+
public logger: Logger;
39+
3640
constructor(props) {
3741
super(props);
3842

@@ -63,6 +67,7 @@ export class ApplicationsDetailsRuntime extends React.Component<ApplicationsDeta
6367
usersService={this.usersService}
6468
productService={this.productService}
6569
applicationService={this.applicationService}
70+
logger={this.logger}
6671
applicationName={this.state.applicationName}
6772
getProductReferenceUrl={(productName) => this.getProductReferenceUrl(productName)}
6873
/>

src/components/applications/application-list/applicationList.design.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export class ApplicationListDesignModule implements IInjectorModule {
4646
handlerComponent: ApplicationListHandlers
4747
});
4848
}
49+
})
50+
.catch((error) => {
51+
logger.trackError(error, { message: "Failed to get feature value for client applications in ApplicationListDesignModule." });
4952
}
5053
);
5154
}

src/components/applications/application-list/applicationList.publish.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export class ApplicationListPublishModule implements IInjectorModule {
3232
componentFlow: ComponentFlow.Block
3333
});
3434
}
35+
})
36+
.catch((error) => {
37+
logger.trackError(error, { message: "Failed to get feature value for client applications in ApplicationListPublishModule." });
3538
}
3639
);
3740
}

src/components/applications/application-list/react/runtime/ApplicationsListRuntime.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from "react";
22
import { FluentProvider } from "@fluentui/react-components";
33
import { Resolve } from "@paperbits/react/decorators";
4+
import { Logger } from "@paperbits/common/logging";
45
import { ApplicationService } from "../../../../../services/applicationService";
56
import { UsersService } from "../../../../../services";
67
import { Application } from "../../../../../models/application";
@@ -26,6 +27,7 @@ export type TApplicationsListRuntimeFCProps = Omit<ApplicationsListProps, "detai
2627
getReferenceUrl: (applicationName: string) => string;
2728
userId: string;
2829
applicationService: ApplicationService;
30+
logger: Logger;
2931
selectedApplication?: Application | null;
3032
};
3133

@@ -39,6 +41,9 @@ export class ApplicationsListRuntime extends React.Component<ApplicationsListPro
3941
@Resolve("routeHelper")
4042
public routeHelper: RouteHelper;
4143

44+
@Resolve("logger")
45+
public logger: Logger;
46+
4247
constructor(props) {
4348
super(props);
4449

@@ -80,6 +85,7 @@ export class ApplicationsListRuntime extends React.Component<ApplicationsListPro
8085
{...this.props}
8186
userId={this.state.userId}
8287
applicationService={this.applicationService}
88+
logger={this.logger}
8389
getReferenceUrl={(applicationName) => this.getReferenceUrl(applicationName)}
8490
/>
8591
</FluentProvider>

src/components/applications/application-list/react/runtime/ApplicationsTableCards.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type TApplicationTableCards = TApplicationsListRuntimeFCProps;
1616

1717
export const ApplicationsTableCards = ({
1818
getReferenceUrl,
19+
logger,
1920
userId,
2021
applicationService,
2122
layoutDefault,
@@ -38,18 +39,19 @@ export const ApplicationsTableCards = ({
3839
setWorking(true);
3940
setError(null);
4041
loadApplications(query)
41-
.then((loadedApplications) => setApplications(loadedApplications))
42-
.finally(() => setWorking(false));
43-
}, [applicationService, pageNumber, pattern]);
42+
.then((loadedApplications) => {
43+
loadedApplications instanceof Page ? setApplications(loadedApplications) : setError(loadedApplications);
44+
}).finally(() => setWorking(false));
45+
}, [applicationService, pageNumber, pattern, userId]);
4446

4547
const loadApplications = async (query: SearchQuery) => {
46-
let applications: Page<Application>;
48+
let applications: Page<Application> | string;
4749

4850
try {
4951
applications = await applicationService.getClientApplications(userId, query);
5052
} catch (error) {
51-
setError("Application is not selected.");
52-
//throw new Error(`Unable to load applications. Error: ${error.message}`);
53+
setError("Unable to load applications.");
54+
logger.trackError(error, { message: "Unable to load applications." });
5355
}
5456

5557
return applications;

src/contracts/application.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ export interface ApplicationContract {
1414
*/
1515
entraApplicationId: string;
1616

17+
/**
18+
* Tenant identifier in Entra platform.
19+
*/
20+
entraTenantId?: string;
21+
1722
/**
1823
* Application state.
1924
* Possible values: pending, active, rejected, approved.

0 commit comments

Comments
 (0)