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: show build version #900

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions .changeset/pr-900-2239364209.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

---
"fusion-project-portal": patch
---
Better styling for better layout
- Displaying deleted apps better
- Displaying version information
- Not allowing context app connections on non context portals
- Better AG grid configuration
2 changes: 1 addition & 1 deletion client/apps/portal-administration/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "portal-administration",
"version": "1.1.2",
"version": "1.1.3",
"description": "",
"private": true,
"type": "module",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { ColDef } from '@equinor/workspace-ag-grid';
import { format } from 'date-fns/format';

export const defaultColDef: ColDef = {
valueFormatter: (a) => tryFormat(a.value),
resizable: true,
filter: true,
sortable: true,
};

function tryFormat(value: unknown): string {
switch (typeof value) {
case 'string': {
const maybeDate = new Date(value);
if (Number.isNaN(maybeDate.valueOf())) {
return value;
}
return formatDate(maybeDate);
}

case 'number': {
return formatNumber(value);
}

case 'object': {
if (value === null) {
return formatNull();
}

if (value instanceof Date) {
return formatDate(value);
}
}

case 'undefined': {
return formatUndefined();
}

case 'boolean': {
return formatBoolean(value);
}

default: {
return '-';
}
}
}

function formatNumber(val: number) {
return val.toLocaleString('no');
}

function formatNull() {
return '-';
}

function formatUndefined() {
return '-';
}

function formatBoolean(val: boolean) {
return val ? 'yes' : 'no';
}

function formatDate(date: Date) {
return format(date, 'dd/MM/yy').toString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { GridOptions } from '@equinor/workspace-ag-grid';
import { defaultColDef } from './defaultColDef';

export const defaultGridOptions: GridOptions = {
defaultColDef: defaultColDef,
serverSideInitialRowCount: 100,
enableBrowserTooltips: true,
enableCellTextSelection: true,
ensureDomOrder: true,
onFirstDataRendered: (event) => {
const api = event.api;
api.sizeColumnsToFit();
},
suppressColumnVirtualisation: true,
autoSizePadding: 10,
rowHeight: 36,
};

export const bottomPadding = 70;

export function capitalizeFirstLetter(str?: string) {
if (!str) return ''; // Handle empty string
return str.charAt(0).toUpperCase() + str.slice(1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const AgStyles = {
TableContent: styled.div`
padding-top: 1rem;
position: relative;
height: calc(100% - 3rem);
height: calc(100% - 1rem);
width: 100%;
`,

Expand Down Expand Up @@ -68,5 +68,9 @@ export const AgStyles = {
font-weight: bold;
background-color: ${tokens.colors.ui.background__danger.hex} !important;
}
.noBuilds {
font-weight: bold;
background-color: ${tokens.colors.ui.background__warning.hex} !important;
}
`,
};
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { CustomCellRendererProps } from '@ag-grid-community/react';
import { Button, Icon } from '@equinor/eds-core-react';
import { ClientGrid } from '@equinor/workspace-ag-grid';

import { useRef, useState } from 'react';
import { useMemo, useRef, useState } from 'react';

import { useDeleteOnboardedApp } from '../../hooks/use-onboarded-apps';
import { PortalApp } from '../../types';

import { delete_to_trash, edit } from '@equinor/eds-icons';
import { AgStyles } from '../AgStyle';
import { OnboardedAppsActionBar } from './OnboardedAppsActionBar';
import { useResizeObserver } from '../../hooks/use-resise-observer';
import { Message } from '../Message';

const FAIL_MESSAGE = 'Application Error!';
import { AgStyles } from '../AgStyle';
import { appsColDefs } from './appsColDef';
import { defaultGridOptions } from '../Ag-Grid/defaultGridOptions';

export const AppsTable = ({ onboardedApps }: { onboardedApps: PortalApp[] | undefined }) => {
const [selectedApps, setSelectedApps] = useState<PortalApp[]>([]);
Expand All @@ -22,114 +19,28 @@ export const AppsTable = ({ onboardedApps }: { onboardedApps: PortalApp[] | unde
const ref = useRef(null);
const [_, height] = useResizeObserver(ref);

const coldDef = useMemo(() => appsColDefs(deleteAppByAppKey), [deleteAppByAppKey]);

return (
<AgStyles.Wrapper>
<AgStyles.TableContent ref={ref}>
<ClientGrid<PortalApp>
height={selectedApps.length === 0 ? height : height - 150}
{...defaultGridOptions}
rowData={onboardedApps || []}
noRowsOverlayComponent={() => <Message title="No data available" />}
rowSelection="multiple"
rowHeight={36}
defaultColDef={{
filter: true,
flex: 1,
sortable: true,
resizable: true,
}}
rowClassRules={{
notActive: (params) => !Boolean(params.data?.displayName || params.data?.description),
}}
autoSizeStrategy={{
type: 'fitGridWidth',
defaultMinWidth: 80,
defaultMaxWidth: 700,
}}
onGridReady={(event) => {
const api = event.api;
api.sizeColumnsToFit();
}}
onRowDataUpdated={() => {
setSelectedApps([]);
}}
onRowSelected={(event) => {
const selectedRows = event.api!.getSelectedRows();
setSelectedApps(selectedRows);
}}
colDefs={[
{
field: 'id',
headerName: 'Id',
hide: true,
},
{
field: 'displayName',
headerName: 'Display Name',
filter: true,
valueFormatter: (params) => {
return params.value ? params.value : FAIL_MESSAGE;
},
},
{
field: 'appKey',
headerName: 'App Key',
filter: true,
},
{
field: 'description',
headerName: 'Description',
width: 700,
},

{
field: 'contexts',
headerName: 'Contexts Types',
filter: true,

cellRenderer: (
params: CustomCellRendererProps<{
contextTypes: string[];
appKey: string;
}>
) => {
return (
<AgStyles.CellWrapper key={params.context?.appKey}>
{params?.data?.contextTypes?.map((type) => {
return (
<AgStyles.Chip variant="default" key={type}>
{type}
</AgStyles.Chip>
);
})}
</AgStyles.CellWrapper>
);
},
},
{
field: 'appKey',
headerName: 'Action',
maxWidth: 100,
resizable: false,
cellRenderer: (params: CustomCellRendererProps<PortalApp>) => {
return (
<AgStyles.CellWrapper key={params.context?.appKey}>
<Button
title={`Delete ${params.data?.name} from system`}
variant="ghost"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
const appKey = params.data?.appKey;
appKey && deleteAppByAppKey(appKey);
}}
>
<Icon data={delete_to_trash} size={16} />
</Button>
</AgStyles.CellWrapper>
);
},
},
]}
colDefs={coldDef}
/>
<OnboardedAppsActionBar selection={selectedApps} />
</AgStyles.TableContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { OnboardAppInputs, onboardAppInput } from '../../schema/app';
import { useAddOnboardedApp, useOnboardedApps } from '../../hooks/use-onboarded-apps';
import { useGetContextTypes } from '../../hooks/use-context-type-query';
import { AppSelector } from './AppSelector';
import { Row } from '@equinor/eds-core-react/dist/types/components/Table/Row';
import { arrow_back, arrow_drop_left, chevron_down, chevron_left } from '@equinor/eds-icons';
import { chevron_down, chevron_left } from '@equinor/eds-icons';
import { InfoPopover } from '../InfoPopover';

const Style = {
Expand Down Expand Up @@ -89,7 +88,7 @@ export const OnboardApp = () => {
return (
<Style.Wrapper>
<Style.Card>
<Style.RowHead onClick={() => setActive((s) => !s)}>
<Style.RowHead>
<Style.Row>
<Typography variant="h6">Onboard App</Typography>
<InfoPopover title="Onboard App">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export const OnboardedAppsActionBar = ({ selection }: { selection: PortalApp[] }
}
}, [selection]);
const { data: contextTypes } = useGetContextTypes();

if (selection.length === 0) return null;

return (
<Styles.Wrapper>
<Styles.Content>
Expand All @@ -59,7 +61,6 @@ export const OnboardedAppsActionBar = ({ selection }: { selection: PortalApp[] }
return item === compare;
}}
onOptionsChange={(change) => {
console.log(change.selectedItems);
setSelected(change.selectedItems);
editSelected(
selection.map((s) => ({ appKey: s.appKey, contextTypes: change.selectedItems }))
Expand Down
Loading
Loading