Skip to content

Commit

Permalink
#770 Search results display more info
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps authored and joepio committed Jan 11, 2024
1 parent 438d05a commit e04ceb9
Show file tree
Hide file tree
Showing 15 changed files with 136 additions and 106 deletions.
16 changes: 9 additions & 7 deletions browser/data-browser/src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ type CardProps = {
/** A Card with a border. */
export const Card = styled.div<CardProps>`
background-color: ${props => props.theme.colors.bg};
/** Don't put side margins in this component - use a wrapping component */
border: solid 1px ${props => props.theme.colors.bg2};
box-shadow: ${props => props.theme.boxShadow};
border: solid 1px
${props =>
props.highlight ? props.theme.colors.main : props.theme.colors.bg2};
box-shadow: ${props =>
props.highlight
? `0 0 0 1px ${props.theme.colors.main}, ${props.theme.boxShadow}`
: props.theme.boxShadow};
padding: ${props => props.theme.margin}rem;
/* margin-bottom: ${props => props.theme.margin}rem; */
padding-bottom: 0;
border-radius: ${props => props.theme.radius};
max-height: ${props => (props.small ? '10rem' : 'none')};
overflow: ${props => (props.small ? 'hidden' : 'visible')};
border-color: ${props =>
props.highlight ? props.theme.colors.main : props.theme.colors.bg2};
${p => transitionName('resource-page', p.about)};
`;
Expand Down
10 changes: 9 additions & 1 deletion browser/data-browser/src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ const NavBarBase = styled.div<NavBarStyledProps>`
/** Width of the floating navbar in rem */
const NavBarFloating = styled(NavBarBase)`
box-shadow: ${props => props.theme.boxShadow};
box-sizing: border-box;
border-radius: 999px;
overflow: hidden;
max-width: calc(100% - 2rem);
Expand All @@ -179,6 +178,11 @@ const NavBarFloating = styled(NavBarBase)`
top: ${props => (props.top ? '2rem' : 'auto')};
bottom: ${props => (props.top ? 'auto' : '1rem')};
&:has(input:focus) {
box-shadow: 0px 0px 0px 1px ${props => props.theme.colors.main};
border-color: ${props => props.theme.colors.main};
}
@media (max-width: ${props => props.theme.containerWidth}rem) {
max-width: calc(100% - 1rem);
left: auto;
Expand All @@ -198,6 +202,10 @@ const NavBarFixed = styled(NavBarBase)`
props.top ? 'solid 1px ' + props.theme.colors.bg2 : 'none'};
border-top: ${props =>
!props.top ? 'solid 1px ' + props.theme.colors.bg2 : 'none'};
&:has(input:focus) {
box-shadow: 0px 0px 0px 2px ${props => props.theme.colors.main};
}
`;

const SideBarWrapper = styled('div')`
Expand Down
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/PropVal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function PropVal({
</PropertyLabel>
</AtomicLink>
{editable ? (
<ValueForm resource={resource} propertyURL={propertyURL} noMargin />
<ValueForm resource={resource} propertyURL={propertyURL} />
) : (
<ValueComp
datatype={property.datatype}
Expand Down
10 changes: 5 additions & 5 deletions browser/data-browser/src/components/Searchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ const Input = styled.input`
flex: 1;
min-width: 1rem;
background-color: ${props => props.theme.colors.bg};
outline: 0;
// Outline is handled by the Navbar.
outline: none;
color: ${p => p.theme.colors.textLight};
`;

Expand All @@ -172,9 +173,7 @@ const Form = styled.form`
border-radius: 999px;
:hover {
box-shadow: inset 0 0 0 2px
${props => transparentize(0.6, props.theme.colors.main)};
${props => transparentize(0.6, props.theme.colors.main)};
${Input} {
color: ${p => p.theme.colors.text};
}
Expand All @@ -183,8 +182,9 @@ const Form = styled.form`
${Input} {
color: ${p => p.theme.colors.text};
}
// Outline is handled by the Navbar.
outline: none;
box-shadow: inset 0 0 0 2px ${props => props.theme.colors.main};
}
`;

Expand Down
5 changes: 2 additions & 3 deletions browser/data-browser/src/components/ValueComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ import { ErrMessage } from './forms/InputStyles';
type Props = {
value: JSONValue;
datatype: Datatype;
noMargin?: boolean;
};

/** Renders a value in a fitting way, depending on its DataType */
function ValueComp({ value, datatype, noMargin }: Props): JSX.Element {
function ValueComp({ value, datatype }: Props): JSX.Element {
try {
switch (datatype) {
case Datatype.ATOMIC_URL: {
Expand All @@ -36,7 +35,7 @@ function ValueComp({ value, datatype, noMargin }: Props): JSX.Element {
case (Datatype.DATE, Datatype.TIMESTAMP):
return <DateTime date={valToDate(value)} />;
case Datatype.MARKDOWN:
return <Markdown text={valToString(value)} noMargin={noMargin} />;
return <Markdown text={valToString(value)} />;
case Datatype.RESOURCEARRAY:
return <ResourceArray subjects={valToArray(value)} />;
default:
Expand Down
26 changes: 6 additions & 20 deletions browser/data-browser/src/components/datatypes/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,21 @@ import { styled } from 'styled-components';
import remarkGFM from 'remark-gfm';
import { Button } from '../Button';
import { truncateMarkdown } from '../../helpers/markdown';
import { useState } from 'react';
import { FC, useState } from 'react';

type Props = {
text: string;
/**
* By default, all bottom Markdown elements have some margin (e.g. the last
* paragraph). If you set noMargin, this is corrected.
*/
noMargin?: boolean;
renderGFM?: boolean;
/**
* If this is set, and the markdown is more characters than this number, the
* text will be truncated and a button will be shown
*/
maxLength?: number;
className?: string;
};

/** Renders a markdown value */
function Markdown({
text,
noMargin,
renderGFM,
maxLength,
}: Props): JSX.Element | null {
const Markdown: FC<Props> = ({ text, renderGFM, maxLength, className }) => {
const [collapsed, setCollapsed] = useState(true);

maxLength = maxLength || 5000;
Expand All @@ -36,7 +27,7 @@ function Markdown({
}

return (
<MarkdownWrapper noMargin={noMargin}>
<MarkdownWrapper className={className}>
<ReactMarkdown remarkPlugins={renderGFM ? [remarkGFM] : []}>
{collapsed ? truncateMarkdown(text, maxLength) : text}
</ReactMarkdown>
Expand All @@ -47,19 +38,14 @@ function Markdown({
)}
</MarkdownWrapper>
);
}
};

Markdown.defaultProps = {
renderGFM: true,
};

interface MarkdownWrapperProps {
noMargin?: boolean;
}

const MarkdownWrapper = styled.div<MarkdownWrapperProps>`
const MarkdownWrapper = styled.div`
/* Corrects the margin added by <p> and other HTML elements */
margin-bottom: -${p => (p.noMargin ? p.theme.margin : 0)}rem;
width: 100%;
overflow-x: hidden;
Expand Down
14 changes: 2 additions & 12 deletions browser/data-browser/src/components/forms/ValueForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,13 @@ interface ValueFormProps {
* also override it manually
*/
datatype?: Datatype;
noMargin?: boolean;
}

/**
* A form for a single Value. Presents a normal value, but let's the user click
* on a button to turn it into an input.
*/
export function ValueForm({
resource,
noMargin,
propertyURL,
datatype,
}: ValueFormProps) {
export function ValueForm({ resource, propertyURL, datatype }: ValueFormProps) {
const [editMode, setEditMode] = useState(false);
const property = useProperty(propertyURL);
const [value] = useValue(resource, propertyURL);
Expand Down Expand Up @@ -86,11 +80,7 @@ export function ValueForm({
if (!editMode) {
return (
<ValueFormWrapper>
<ValueComp
value={value}
datatype={datatype || property.datatype}
noMargin={noMargin}
/>
<ValueComp value={value} datatype={datatype || property.datatype} />
<EditButton title='Edit value'>
<FaEdit onClick={() => setEditMode(!editMode)} />
</EditButton>
Expand Down
1 change: 0 additions & 1 deletion browser/data-browser/src/routes/SearchRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ export function Search(): JSX.Element {
{results.map((subject, index) => (
<ResourceCard
initialInView={index < 5}
small
subject={subject}
key={subject}
highlight={index === selectedIndex}
Expand Down
16 changes: 3 additions & 13 deletions browser/data-browser/src/views/Card/BookmarkCard.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { urls, useString, useTitle } from '@tomic/react';
import { urls, useString } from '@tomic/react';

import { styled } from 'styled-components';
import { AtomicLink } from '../../components/AtomicLink';
import Markdown from '../../components/datatypes/Markdown';
import {
ExternalLink,
ExternalLinkVariant,
} from '../../components/ExternalLink';
import { CardViewProps } from './CardViewProps';
import { ResourceCardTitle } from './ResourceCardTitle';

export function BookmarkCard({ resource }: CardViewProps): JSX.Element {
const [title] = useTitle(resource);
const [url] = useString(resource, urls.properties.bookmark.url);
const [preview] = useString(resource, urls.properties.bookmark.preview);

return (
<>
<AtomicLink subject={resource.getSubject()}>
<Title>{title}</Title>
</AtomicLink>
<ResourceCardTitle resource={resource} />
<ExternalLink to={url!} variant={ExternalLinkVariant.Button}>
Open site
</ExternalLink>
Expand All @@ -31,13 +28,6 @@ export function BookmarkCard({ resource }: CardViewProps): JSX.Element {
);
}

const Title = styled.h2`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.2;
`;

const MarkdownWrapper = styled.div`
margin-top: ${p => p.theme.margin}rem;
margin-inline: -${p => p.theme.margin}rem;
Expand Down
13 changes: 5 additions & 8 deletions browser/data-browser/src/views/Card/CollectionCard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useArray, useString, useTitle, properties } from '@tomic/react';
import { useArray, useString, core, collections } from '@tomic/react';
import { useState } from 'react';

import Markdown from '../../components/datatypes/Markdown';
import { AtomicLink } from '../../components/AtomicLink';
import { CardInsideFull, CardRow } from '../../components/Card';
import { ResourceInline } from '../ResourceInline';
import { CardViewProps } from './CardViewProps';
import { Button } from '../../components/Button';
import { ResourceCardTitle } from './ResourceCardTitle';

const MAX_COUNT = 5;

Expand All @@ -15,9 +15,8 @@ const MAX_COUNT = 5;
* (shortname) is rendered prominently at the top.
*/
function CollectionCard({ resource, small }: CardViewProps): JSX.Element {
const [title] = useTitle(resource);
const [description] = useString(resource, properties.description);
const [members] = useArray(resource, properties.collection.members);
const [description] = useString(resource, core.properties.description);
const [members] = useArray(resource, collections.properties.members);
const [showAll, setShowMore] = useState(false);

const tooMany = members.length > MAX_COUNT;
Expand All @@ -29,9 +28,7 @@ function CollectionCard({ resource, small }: CardViewProps): JSX.Element {

return (
<>
<AtomicLink subject={resource.getSubject()}>
<h2>{title}</h2>
</AtomicLink>
<ResourceCardTitle resource={resource} />
{description && <Markdown text={description} />}
{!small && (
<CardInsideFull>
Expand Down
9 changes: 3 additions & 6 deletions browser/data-browser/src/views/Card/ElementCard.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { urls, useResource, useString, useTitle } from '@tomic/react';
import { urls, useResource, useString } from '@tomic/react';

import { AtomicLink } from '../../components/AtomicLink';
import Markdown from '../../components/datatypes/Markdown';
import { CardViewProps } from './CardViewProps';
import { ResourceCardTitle } from './ResourceCardTitle';

export function ElementCard({ resource }: CardViewProps): JSX.Element {
const [documentSubject] = useString(resource, urls.properties.parent);
const document = useResource(documentSubject);
const [documentTitle] = useTitle(document);

const [text] = useString(resource, urls.properties.description);

return (
<>
<AtomicLink subject={document.getSubject()}>
<h2>{documentTitle}</h2>
</AtomicLink>
<ResourceCardTitle resource={document} />
<Markdown text={text ?? ''} />
</>
);
Expand Down
24 changes: 11 additions & 13 deletions browser/data-browser/src/views/Card/ResourceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import { CardViewProps, CardViewPropsBase } from './CardViewProps';
import { ElementCard } from './ElementCard';
import { ArticleCard } from '../Article';
import { styled } from 'styled-components';
import { ViewTransitionProps } from '../../helpers/ViewTransitionProps';
import { transitionName } from '../../helpers/transitionName';
import { ResourceCardTitle } from './ResourceCardTitle';

interface ResourceCardProps extends CardViewPropsBase {
/** The subject URL - the identifier of the resource. */
Expand Down Expand Up @@ -120,15 +119,13 @@ export function ResourceCardDefault({
}: CardViewProps): JSX.Element {
return (
<>
<AtomicLink subject={resource.getSubject()}>
<DefaultCardTitle subject={resource.getSubject()}>
{resource.title}
</DefaultCardTitle>
</AtomicLink>
<ValueForm
resource={resource}
propertyURL={core.properties.description}
/>
<ResourceCardTitle resource={resource} />
<DescriptionWrapper>
<ValueForm
resource={resource}
propertyURL={core.properties.description}
/>
</DescriptionWrapper>
{!small && (
<AllProps
basic
Expand All @@ -143,6 +140,7 @@ export function ResourceCardDefault({

export default ResourceCard;

const DefaultCardTitle = styled.h2<ViewTransitionProps>`
${props => transitionName('page-title', props.subject)}
const DescriptionWrapper = styled.div`
max-height: 10rem;
overflow: hidden;
`;
Loading

0 comments on commit e04ceb9

Please sign in to comment.