Skip to content

Commit

Permalink
feat(variant): SKFP-900 add summary variant v2 (Ferlab-Ste-Justine#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
AltefrohneGaelle authored Feb 22, 2024
1 parent d253315 commit 5d73e4d
Show file tree
Hide file tree
Showing 10 changed files with 344 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/ui/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module.exports = {
],
'arrow-body-style': ['error', 'as-needed'],

'react/jsx-sort-default-props': 'error',
'react/sort-default-props': 'error',
'react/jsx-sort-props': 'error',
'react/jsx-props-no-spreading': 'off',

Expand Down
3 changes: 3 additions & 0 deletions packages/ui/Release.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 9.5.0 2024-02-22
- feat: SKFP-900 add variant summary

### 9.4.0 2024-02-22
- feat: FLUI-121 update pathogenicity utils to use new types

Expand Down
4 changes: 2 additions & 2 deletions packages/ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ferlab/ui",
"version": "9.4.0",
"version": "9.5.0",
"description": "Core components for scientific research data portals",
"publishConfig": {
"access": "public"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
}

.highImpact {
fill: $red-5;
fill: $red-7;
}

.lowImpact {
fill: $green-6;
fill: $green-7;
}

.moderateImpact {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Consequences/Cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const impactToColorClassName = Object.freeze({
[Impact.Modifier]: <ModifierBadgeIcon className={`${style.bullet} ${style.modifierImpact}`} />,
});

const pickImpactBadge = (impact: Impact) => impactToColorClassName[impact];
export const pickImpactBadge = (impact: Impact): JSX.Element => impactToColorClassName[impact];

const ConsequencesCell = ({
aaChangeWrapperClassName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
@import 'colors';

.summaryWrapper {
margin-bottom: 40px;
width: 100%;
overflow-x: scroll;
min-width: 530px;
}

.card {
border: 1px solid;
border-radius: 2px;
border-color: $gray-4;
}

.space {
width: 100%;
}

.bannerWrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
padding: 12px 16px;
border: 1px solid $gray-4;
border-radius: 2px;
background-color: $gray-2;
justify-content: space-between;
}

.infoWrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(5, minmax(min-content, max-content));
gap: 8px;
padding: 12px;
border: 1px solid $gray-4;
border-radius: 2px;
}

.infoWrapper > *:not(:last-child) {
border-right: 1px solid $gray-5;
padding-right: 8px;
}

.canonicalIcon {
fill: $blue-8;
}

.score {
grid-area: score;
border: 1px solid $gray-4;
padding: 12px;
}

.geneSplice {
grid-area: geneSplice;
border: 1px solid $gray-4;
padding: 12px;
}

.omim {
grid-area: omim;
border: 1px solid $gray-4;
padding: 12px;
}

.detailsWrapper {
display: grid;
gap: 8px;
grid-template-columns: 2fr 1fr 1fr;
grid-template-areas: 'score geneSplice omim';

:global(.ant-descriptions-row) {
td {
padding-bottom: 4px;
}
}

:global(.ant-descriptions-item-label::after) {
margin: 0 8px 0 0;
}

:global(.ant-descriptions-header) {
margin-bottom: 8px;
}
}

.detailsTitle {
color: $gray-9;
font-size: 14px;
font-weight: 600;
line-height: 22px;
margin-bottom: 8px;
}

.detailsItemLabel {
color: $gray-7;
}
.ant-descriptions-item-label::after {
margin: 0 8px 0 0;
}

.detailsItemValue {
color: $gray-8;
}

@media (max-width: 1024px) {
.bannerWrapper {
grid-template-columns: repeat(3, 1fr);
}

.detailsWrapper {
grid-template-columns: 1fr 1fr;
grid-template-areas:
'score score'
'geneSplice omim';
}
}
139 changes: 139 additions & 0 deletions packages/ui/src/pages/EntityPage/EntityVariantSummary/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React, { ReactNode } from 'react';
import { Card, Descriptions, Space } from 'antd';

import Empty from '../../../components/Empty';

import style from './index.module.scss';

export interface IDataItem {
label: ReactNode;
value: ReactNode;
}

export interface IDetailData {
title: string;
items: IDataItem[];
}

export interface IVariantSummaryData {
banner: IDataItem[];
info: ReactNode[];
details: {
leftSection: IDetailData;
middleSection: IDetailData[];
rightSection: IDetailData;
};
}

export interface ISummaryProps {
id: string;
loading: boolean;
noDataLabel: string;
data?: IVariantSummaryData;
}

export const EntityVariantSummary = ({ data, id, loading, noDataLabel }: ISummaryProps): JSX.Element => {
const detailsLeftSectionLength = data?.details.leftSection.items.length || 0;
const detailsLeftSectionCol1 = data?.details.leftSection.items.slice(0, detailsLeftSectionLength / 2);
const detailsLeftSectionCol2 = data?.details.leftSection.items.slice(
detailsLeftSectionLength / 2,
detailsLeftSectionLength,
);

return (
<div className={style.summaryWrapper} id={id}>
<Card className={style.card} loading={loading}>
{data ? (
<Space className={style.space} direction="vertical" size="middle">
{data.banner && (
<div className={style.bannerWrapper}>
{data.banner.map((item: IDataItem, index: number) => (
<Space direction="vertical" key={index} size={4}>
<div>{item.label}</div>
<div>{item.value}</div>
</Space>
))}
</div>
)}

{data.info && (
<div className={style.infoWrapper}>
{data.info.map((item: ReactNode, index: number) => (
<div key={index}>{item}</div>
))}
</div>
)}

{data.details && (
<div className={style.detailsWrapper}>
<div className={style.score}>
<div className={style.detailsTitle}>{data.details.leftSection.title}</div>
<Space direction="horizontal" size="middle">
<Descriptions column={1}>
{detailsLeftSectionCol1?.map((item: IDataItem, index: number) => (
<Descriptions.Item
key={index}
label={<span className={style.detailsItemLabel}>{item.label}</span>}
>
<span className={style.detailsItemValue}>{item.value}</span>
</Descriptions.Item>
))}
</Descriptions>
<Descriptions column={1}>
{detailsLeftSectionCol2?.map((item: IDataItem, index: number) => (
<Descriptions.Item
key={index}
label={<span className={style.detailsItemLabel}>{item.label}</span>}
>
<span className={style.detailsItemValue}>{item.value}</span>
</Descriptions.Item>
))}
</Descriptions>
</Space>
</div>
<div className={style.geneSplice}>
{data.details.middleSection.map((detail: IDetailData, index: number) => (
<Descriptions
column={1}
key={index}
title={<span className={style.detailsTitle}>{detail.title}</span>}
>
{detail.items.map((item: IDataItem, index: number) => (
<Descriptions.Item
key={index}
label={<span className={style.detailsItemLabel}>{item.label}</span>}
>
<span className={style.detailsItemValue}>{item.value}</span>
</Descriptions.Item>
))}
</Descriptions>
))}
</div>
<div className={style.omim}>
<Descriptions
column={1}
title={
<span className={style.detailsTitle}>
{data.details.rightSection.title}
</span>
}
>
{data.details.rightSection.items.map((item: IDataItem, index: number) => (
<Descriptions.Item key={index}>
<span className={style.detailsItemValue}>{item.value}</span>
</Descriptions.Item>
))}
</Descriptions>
</div>
</div>
)}
</Space>
) : (
<Empty align="left" description={noDataLabel} noPadding showImage={false} />
)}
</Card>
</div>
);
};

export default EntityVariantSummary;
2 changes: 1 addition & 1 deletion storybook/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5d73e4d

Please sign in to comment.