Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:loading apps form new apps service #832

Merged
merged 12 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/pr-832-2140944985.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

---
"fusion-project-portal": major
---
- Updating to new app manifest types
- Refactor and performance enhancements on portal configuration module
- Update menu and favorites
- loading router config from portal config service
- filter portal service messages
- Update all list laded from new app service.
- user portal config to filter full applist
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,25 @@ export const FavoriteCard = ({ app, onClick, loading, colorsStyle }: FavoriteCar
return (
<Styled.Favorite
$loading={loading}
to={app.url || `/apps/${app.key}/`}
to={app.url || `/apps/${app.appKey}/`}
style={colorsStyle}
onClick={() => onClick(app)}
>
<Styled.Content>
<AppIconContainer loading={loading} display="card" app={app} />
<Styled.Details>
<Styled.Name group="paragraph" variant="body_short_bold">
{loading ? <Skeleton size={SkeletonSize.small} variant={SkeletonVariant.Text} /> : app.name}
{loading ? (
<Skeleton size={SkeletonSize.small} variant={SkeletonVariant.Text} />
) : (
app.displayName
)}
</Styled.Name>
<Styled.Category group="paragraph" variant="caption">
{loading ? (
<Skeleton size={SkeletonSize.XSmall} variant={SkeletonVariant.Text} />
) : (
app.category?.name
app.category?.displayName
)}
</Styled.Category>
</Styled.Details>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,21 @@ export const ListCard = ({ app, onClick, loading, pinButton, dark, onFavorite }:
<Styled.Bg
dark={dark}
isDisabled={app.isDisabled}
title={app.isDisabled ? `${app.name} is not available in the selected context` : app.name}
title={app.isDisabled ? `${app.displayName} is not available in the selected context` : app.displayName}
>
<Styled.Item
to={app.isDisabled ? '#' : app.url || `/apps/${app.key}/`}
to={app.isDisabled ? '#' : app.url || `/apps/${app.appKey}/`}
style={getAppCardColor(app)}
onClick={(e) => onClick && onClick(app, e)}
>
<Styled.Content $loading={loading}>
<AppIconContainer loading={loading} display="item" app={app} />
<Styled.Name group="navigation" variant="menu_title">
{loading ? <Skeleton size={SkeletonSize.small} variant={SkeletonVariant.Text} /> : app.name}
{loading ? (
<Skeleton size={SkeletonSize.small} variant={SkeletonVariant.Text} />
) : (
app.displayName
)}
</Styled.Name>
</Styled.Content>
{pinButton && <PinButtonContainer isLoading={loading} app={app} onFavorite={onFavorite} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ export const PortalCard = ({ app, onClick, isLoading }: PortalCardProps): JSX.El
<AppIconContainer loading={isLoading} display="portal" app={app} />
<Styled.Details>
<FavoriteStyled.Name group="heading" variant="h5">
{isLoading ? <Skeleton size={SkeletonSize.Medium} variant={SkeletonVariant.Text} /> : app.name}
{isLoading ? (
<Skeleton size={SkeletonSize.Medium} variant={SkeletonVariant.Text} />
) : (
app.displayName
)}
</FavoriteStyled.Name>
<Styled.Description group="paragraph" variant="caption">
{isLoading ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,22 @@ type AppGroupProps = {

export const AppGroup = ({ group, onFavorite, dark, onClick }: AppGroupProps) => {
const { appKey } = useParams();
const isGroupActive = !!group.apps.find((a) => a.key === appKey);
const isGroupActive = !!group.apps.find((a) => a.appKey === appKey);

return (
<Styles.Group id={`groupe-${group.name}`}>
<Styles.Group id={`groupe-${group.displayName}`}>
<Styles.Nav>
<Styles.Title isActive={isGroupActive} id={`groupe-${group.name}-name`} title={group.name || ''}>
{group.name}
<Styles.Title
isActive={isGroupActive}
id={`groupe-${group.displayName}-name`}
title={group.displayName || ''}
>
{group.displayName}
</Styles.Title>
<Styles.List>
{group.apps.map((app) => (
<ListCard
key={app.key}
key={app.appKey}
app={app}
pinButton
dark={dark}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ export const AppSearchBar = (): JSX.Element => {
const alteredAsDropdownItems = apps
? apps.map((app) => {
return {
id: app.key,
title: app.name,
id: app.appKey,
title: app.displayName,
subTitle: app.category?.name,
graphic: getSearchAppIcon(app),
graphicType: 'inline-svg',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ export const GroupWrapper = ({ appCategories, maxAppsInColumn }: GroupWrapperPro
},

{
appKey: app.key,
appKey: app.appKey,
isFavorite: app.isPinned,
source: 'app-menu',
}
);
}}
onFavorite={(app) => addFavorite(app.key)}
key={appCategories.name}
onFavorite={(app) => addFavorite(app.appKey)}
key={appCategories.displayName}
/>
))
) : (
Expand Down
10 changes: 5 additions & 5 deletions client/packages/core/src/app/hooks/use-app-loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('use-app-loader', () => {
const app = createApp(appRender);
initialize.mockImplementation(() => app.asObservable());

const { result } = renderHook(() => useAppLoader('handover'));
const { result } = renderHook(() => useAppLoader({ appKey: 'handover' }));

act(() => {
app.complete();
Expand All @@ -97,7 +97,7 @@ describe('use-app-loader', () => {
const app = createApp(appRender);
initialize.mockImplementation(() => app.asObservable());

const { result } = renderHook(() => useAppLoader('handover'));
const { result } = renderHook(() => useAppLoader({ appKey: 'handover' }));

act(() => {
app.complete();
Expand All @@ -109,7 +109,7 @@ describe('use-app-loader', () => {
test('should get error when no render is provider from script', () => {
const app = createApp();
initialize.mockImplementation(() => app.asObservable());
const { result } = renderHook(() => useAppLoader('handover'));
const { result } = renderHook(() => useAppLoader({ appKey: 'handover' }));
act(() => {
app.complete();
});
Expand All @@ -129,7 +129,7 @@ describe('use-app-loader', () => {
const app = createApp(appRender, true);
initialize.mockImplementation(() => app.asObservable());

const { result } = renderHook(() => useAppLoader('handover'));
const { result } = renderHook(() => useAppLoader({ appKey: 'handover' }));

act(() => {
app.complete();
Expand All @@ -148,7 +148,7 @@ describe('use-app-loader', () => {
)
);

const { result } = renderHook(() => useAppLoader('handover'));
const { result } = renderHook(() => useAppLoader({ appKey: 'handover' }));
act(() => {
app.complete();
});
Expand Down
7 changes: 4 additions & 3 deletions client/packages/core/src/app/hooks/use-app-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { getLegacyClientConfig, getFusionLegacyEnvIdentifier, getLegacyFusionCon
import { AppConfig } from '@equinor/fusion-framework-app';
import { ConfigEnvironment } from '@equinor/fusion-framework-module-app';
import { Client } from '@portal/types';
import { cleanBasePath } from '../utils/clean-base-path';

export const useAppLoader = (appKey: string) => {
export const useAppLoader = (args: { appKey: string; path?: string }) => {
const { appKey } = args;
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error | undefined>();

Expand All @@ -33,7 +35,7 @@ export const useAppLoader = (appKey: string) => {

// Generate basename for application regex extracts /apps/:appKey
const [basename] = window.location.pathname.match(/\/?apps\/[a-z|-]+\//g) ?? [
window.location.pathname,
cleanBasePath(args.path) ?? window.location.pathname,
];

try {
Expand Down Expand Up @@ -90,7 +92,6 @@ export const useAppLoader = (appKey: string) => {
}
} catch (error) {
console.error('App loading Error: ', error);

setError(error as Error);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AppCategory, AppManifest } from '@portal/core';

const appGroups: AppCategory[] = [
{
name: 'Construction',
displayName: 'Construction',
color: '1',
defaultIcon: '1',
apps: [
Expand All @@ -23,7 +23,7 @@ const appGroups: AppCategory[] = [
] as AppManifest[],
},
{
name: 'Collaboration',
displayName: 'Collaboration',
color: '2',
defaultIcon: '2',
apps: [
Expand All @@ -42,7 +42,7 @@ describe('appsMatchingSearch', () => {
test('Should return Construction appGroups with swcr app', () => {
const expected: AppCategory[] = [
{
name: 'Construction',
displayName: 'Construction',
defaultIcon: '1',
color: '1',
apps: [
Expand All @@ -60,7 +60,7 @@ describe('appsMatchingSearch', () => {
test('Should return all appGroups', () => {
const expected: AppCategory[] = [
{
name: 'Construction',
displayName: 'Construction',
color: '1',
defaultIcon: '1',
apps: [
Expand All @@ -75,7 +75,7 @@ describe('appsMatchingSearch', () => {
] as AppManifest[],
},
{
name: 'Collaboration',
displayName: 'Collaboration',
color: '2',
defaultIcon: '2',
apps: [
Expand Down
3 changes: 3 additions & 0 deletions client/packages/core/src/app/utils/clean-base-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function cleanBasePath(path?: string): string | undefined {
return `/${path?.replace('/*', '')}`;
}
10 changes: 6 additions & 4 deletions client/packages/core/src/modules/portal-config/configurator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable class-methods-use-this */
import { BaseConfigBuilder, ConfigBuilderCallbackArgs } from '@equinor/fusion-framework-module';
import { AppManifestResponse, IClient, PortalConfiguration, PortalRoutes, PortalState } from './types';
import { AppManifestResponse, IClient, PortalConfiguration, PortalRouter, PortalState } from './types';
import { IHttpClient } from '@equinor/fusion-framework-module-http';

export const createDefaultClient = (httpClient: IHttpClient): IClient => {
Expand All @@ -11,7 +11,7 @@ export const createDefaultClient = (httpClient: IHttpClient): IClient => {
},
key: (args) => JSON.stringify(args),
},
getApps: {
getPortalApps: {
client: {
fn: async (args) => {
if (!args.contextId) return [];
Expand All @@ -20,7 +20,9 @@ export const createDefaultClient = (httpClient: IHttpClient): IClient => {
);
// Mapping AppMAnifestREsponse to AppManifest, this is done so our solution
// is working with at application manifest similar to fusion classic.
return apps.map((app) => app.appManifest);
return apps.map((app) =>
typeof app === 'string' ? app : app.appManifest.key || app.appManifest.appKey
);
},
},
key: (args) => JSON.stringify(args),
Expand All @@ -37,7 +39,7 @@ export class PortalConfigConfigurator extends BaseConfigBuilder<PortalConfigurat
this._set('client', async () => client);
}

public setRoutes(client: PortalRoutes) {
public setRoutes(client: PortalRouter) {
this._set('portalConfig.routes', async () => client);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const useCurrentAppGroup = (key?: string) => {
const { appCategories, isLoading } = usePortalApps();

const currentAppGroup = useMemo(() => {
const nextAppGroup = appCategories?.find((app) => !!app.apps?.find((a) => a.key === key));
const nextAppGroup = appCategories?.find((app) => !!app.apps?.find((a) => a.appKey === key));
return nextAppGroup ? nextAppGroup : undefined;
}, [key, appCategories]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export const useFavorites = () => {

const favorite$ = useMemo(
() =>
combineLatest([app?.getAppManifests(), menuFavoritesController.favorites$]).pipe(
map(([apps, favorites]) => apps.filter((app) => favorites.includes(app.key ?? '')))
),
combineLatest([
app?.getAppManifests({ filterByCurrentUser: true }),
menuFavoritesController.favorites$,
]).pipe(map(([apps, favorites]) => apps.filter((app) => favorites.includes(app.appKey)))),
[apps]
) as Observable<AppManifest[]>;

Expand All @@ -32,7 +33,7 @@ export const useFavorites = () => {
const enabledApps = (appCategories?.map((group) => group.apps) ?? []).flat();
return getDisabledApps(enabledApps, favorites ?? [])
.filter((app) => app.isDisabled)
.map((app) => app.key);
.map((app) => app.appKey);
}, [appCategories, favorites]);

const isPinned = useCallback(
Expand All @@ -51,13 +52,13 @@ export const useFavorites = () => {
);

const favoritesWithDisabled =
useMemo(() => favorites.map((p) => ({ ...p, isDisabled: isDisabled(p.key ?? '') })), [favorites, isDisabled]) ||
useMemo(() => favorites.map((p) => ({ ...p, isDisabled: isDisabled(p.appKey) })), [favorites, isDisabled]) ||
[];

const appGroupsWithPinned = useMemo(() => {
return (appCategories || []).map((group) => ({
...group,
apps: group.apps.map((app) => ({ ...app, isPinned: isPinned(app.key ?? '') })),
apps: group.apps.map((app) => ({ ...app, isPinned: isPinned(app.appKey) })),
})) as AppCategory[];
}, [isPinned, appCategories]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { usePortalConfig } from './use-portal-config';
import { usePortalAppsConfig } from './use-portal-config';
import { appsToAppCategory } from '../utils/appsToAppCategory';

/**
Expand All @@ -8,7 +8,7 @@ import { appsToAppCategory } from '../utils/appsToAppCategory';
* The Return Object containing apps data, categorized apps, loading state, and error state.
*/
export const usePortalApps = () => {
const { data: apps, isLoading, error } = usePortalConfig().queryApps;
const { apps, isLoading, error } = usePortalAppsConfig();

// Organize apps into categories using memoized the result
const appCategories = useMemo(() => {
Expand Down
Loading
Loading