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

#873 Add support for resource arrays in tables #879

Merged
merged 12 commits into from
May 14, 2024
10 changes: 6 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
PR Checklist:
## Related Issues

- [ ] Link to related issues: #number
closes #number

## Checklist
- [ ] Add changelog entry linking to issue, describe API changes
- [ ] Add tests (optional)
- [ ] (If new feature) add to description / readme
- [ ] Add or update tests if needed
- [ ] Update docs if needed
8 changes: 5 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"eslint.alwaysShowStatus": true,
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"eslint.packageManager": "pnpm",
"eslint.quiet": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
Expand All @@ -32,6 +31,9 @@
"eslint.workingDirectories": [
"./data-browser",
"./react",
"./lib"
]
"./lib",
"./cli",
"./svelte"
],
"typescript.preferences.preferTypeOnlyAutoImports": true,
}
1 change: 1 addition & 0 deletions browser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This changelog covers all five packages, as they are (for now) updated as a whol
- [#842](https://github.com/atomicdata-dev/atomic-server/issues/842) Add media picker for properties with classtype file.
- [#850](https://github.com/atomicdata-dev/atomic-server/issues/850) Add drag & drop sorting to ResourceArray inputs.
- [#757](https://github.com/atomicdata-dev/atomic-server/issues/757) Add drag & drop sorting to sidebar.
- [#873](https://github.com/atomicdata-dev/atomic-server/issues/873) Add option to allow multiple resources in relation columns (Tables).

### @tomic/lib

Expand Down
2 changes: 1 addition & 1 deletion browser/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"prettier": "3.0.3"
},
"devDependencies": {
"typescript": "^4.8"
"typescript": "^5.4.5"
},
"description": "",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions browser/data-browser/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
roots: ['<rootDir>/src'],
testMatch: [
Expand Down
7 changes: 5 additions & 2 deletions browser/data-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"react-intersection-observer": "^9.4.1",
"react-is": "^18",
"react-markdown": "^8.0.3",
"react-pdf": "^6.2.2",
"react-pdf": "^8.0.2",
"react-router": "^6.9.0",
"react-router-dom": "^6.9.0",
"react-virtualized-auto-sizer": "^1.0.7",
Expand All @@ -45,6 +45,7 @@
"yamde": "^1.7.1"
},
"devDependencies": {
"vite": "^5.2.10",
"@swc/plugin-styled-components": "^1.5.110",
"@types/react-pdf": "^6.2.0",
"@types/react-window": "^1.8.7",
Expand All @@ -55,8 +56,10 @@
"types-wm": "^1.1.0",
"vite-plugin-pwa": "^0.17.0",
"vite-plugin-webfont-dl": "^3.9.1",
"workbox-cli": "^6.4.1"
"workbox-cli": "^6.4.1",
"typescript": "^5.4.5"
},
"type": "module",
"homepage": "https://atomicdata.dev/",
"husky": {
"hooks": {
Expand Down
4 changes: 3 additions & 1 deletion browser/data-browser/src/components/ButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ const Label = styled.label`
color: ${p => p.theme.colors.textLight};
cursor: pointer;

transition: background-color 0.1s ease-in-out, color 0.1s ease-in-out;
transition:
background-color 0.1s ease-in-out,
color 0.1s ease-in-out;

input:checked + & {
background-color: ${p => p.theme.colors.bg1};
Expand Down
3 changes: 2 additions & 1 deletion browser/data-browser/src/components/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ const IconButton = styled.button<IconButtonProps>`
align-items: center;
padding: 0.2rem;
visibility: ${props => (props.hide ? 'hidden' : 'visible')};
transition: transform var(--speed) ease-in-out,
transition:
transform var(--speed) ease-in-out,
background-color var(--speed) ease;
transform: rotate(${props => (props.turn ? '90deg' : '0deg')});
background-color: transparent;
Expand Down
6 changes: 4 additions & 2 deletions browser/data-browser/src/components/Dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,15 @@ const StyledDialog = styled.dialog<{ $width?: CSS.Property.Width }>`
opacity: 0;
transform: translateY(5rem);
// Use a transition when animating out (for some reason keyframe animations don't work on outgoing dialog).
transition: opacity ${ANIM_SPEED} ease-in-out,
transition:
opacity ${ANIM_SPEED} ease-in-out,
transform ${ANIM_SPEED} ease-in-out;

&::backdrop {
background-color: rgba(0, 0, 0, 0);
backdrop-filter: blur(0px);
transition: background-color ${ANIM_SPEED} ease-out,
transition:
background-color ${ANIM_SPEED} ease-out,
backdrop-filter ${ANIM_SPEED} ease-out;
// Make sure the browser paints the backdrop on another layer so the animation is less expensive.
will-change: background-color, backdrop-filter;
Expand Down
6 changes: 5 additions & 1 deletion browser/data-browser/src/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ const ExternalLinkButton = styled.a`
justify-content: center;
color: ${props => props.theme.colors.main};
white-space: nowrap;
transition: 0.1s transform, 0.1s background-color, 0.1s box-shadow, 0.1s color;
transition:
0.1s transform,
0.1s background-color,
0.1s box-shadow,
0.1s color;

&:hover,
&:focus-within {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ const OutlineIconButton = styled(IconButtonBase)<ButtonStyleProps>`
&:hover,
&:focus-visible {
color: ${p => p.theme.colors.main};
box-shadow: 0px 0px 0px 1.5px ${p => p.theme.colors.main},
box-shadow:
0px 0px 0px 1.5px ${p => p.theme.colors.main},
${p => p.theme.boxShadowSoft};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { ResourceInline } from '../views/ResourceInline';

interface InlineFormattedResourceListProps {
subjects: string[];
/** Optional component to render items instead of an inline resource */
RenderComp?: React.FC<{ subject: string }>;
}

const formatter = new Intl.ListFormat('en-GB', {
Expand All @@ -11,6 +13,7 @@ const formatter = new Intl.ListFormat('en-GB', {

export function InlineFormattedResourceList({
subjects,
RenderComp,
}: InlineFormattedResourceListProps): JSX.Element {
// There are rare cases where a resource array can locally have an undefined value, we filter these out to prevent the formatter from throwing an error.
const filteredSubjects = subjects.filter(subject => subject !== undefined);
Expand All @@ -22,6 +25,10 @@ export function InlineFormattedResourceList({
return value;
}

if (RenderComp) {
return <RenderComp subject={value} key={value} />;
}

return <ResourceInline subject={value} key={value} />;
})}
</>
Expand Down
4 changes: 3 additions & 1 deletion browser/data-browser/src/components/NewCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const Thing = styled(GridCard)`
width: 100%;
font-size: 3rem;
color: ${p => p.theme.colors.textLight};
transition: color 0.1s ease-in-out, font-size 0.1s ease-out,
transition:
color 0.1s ease-in-out,
font-size 0.1s ease-out,
border-color 0.1s ease-in-out;
&:hover,
&:focus {
Expand Down
5 changes: 2 additions & 3 deletions browser/data-browser/src/components/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,8 @@ const Arrow = styled(RadixPopover.Arrow)`
fill: ${p => p.theme.colors.bg2};
`;

const PopoverContainerContext = createContext<RefObject<HTMLDivElement>>(
createRef(),
);
const PopoverContainerContext =
createContext<RefObject<HTMLDivElement>>(createRef());

export const PopoverContainer: FC<PropsWithChildren> = ({ children }) => {
const popoverContainerRef = useRef<HTMLDivElement>(null);
Expand Down
4 changes: 3 additions & 1 deletion browser/data-browser/src/components/SideBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ const SideBarStyled = styled.nav.attrs<SideBarStyledProps>(p => ({
z-index: ${p => p.theme.zIndex.sidebar};
box-sizing: border-box;
background: ${p => p.theme.colors.bg};
transition: opacity 0.3s, left 0.3s;
transition:
opacity 0.3s,
left 0.3s;
left: ${p => (p.exposed ? '0' : `calc(var(--width) * -1 + 0.5rem)`)};
/* When the user is hovering, show half opacity */
opacity: ${p => (p.exposed ? 1 : 0)};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ const Indicator = styled.div.attrs<IndicatorProps>(p => ({
border: 2px solid ${p => p.theme.colors.main};
pointer-events: none;
will-change: transform, width;
transition: transform var(--speed) ease-out, width var(--speed) ease-out,
transition:
transform var(--speed) ease-out,
width var(--speed) ease-out,
height var(--speed) ease-out;
z-index: 1;
background-color: ${p =>
Expand Down
9 changes: 8 additions & 1 deletion browser/data-browser/src/components/TableEditor/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,14 @@ export function Cell({
setCursorMode(CursorMode.Visual);
setActiveCell(rowIndex, columnIndex);
},
[setActiveCell, columnIndex, shouldEnterEditMode, cursorMode, isActive],
[
setActiveCell,
columnIndex,
shouldEnterEditMode,
cursorMode,
isActive,
disabledKeyboardInteractions,
],
);

const handleClick = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { InputStyled, InputWrapper } from '../InputStyles';
import { FaPlus, FaSearch } from 'react-icons/fa';
import { core, server, useServerSearch } from '@tomic/react';
import { styled } from 'styled-components';
import { FilePickerItem } from './FIlePickerItem';
import { FilePickerItem } from './FilePickerItem';
import { Button } from '../../Button';
import { Row } from '../../Row';
import { useSettings } from '../../../helpers/AppSettings';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ const ItemCard = styled.div`
touch-action: none;
pointer-events: none;
user-select: none;
transition: border 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
transition:
border 0.1s ease-in-out,
box-shadow 0.1s ease-in-out;
`;

const ItemWrapper = styled.button`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export const NewDriveDialog: FC<CustomResourceDialogProps> = ({
parent: resource.subject,
propVals: {
[core.properties.shortname]: ontologyName,
[core.properties
.description]: `Default ontology for the ${name} drive`,
[core.properties.description]:
`Default ontology for the ${name} drive`,
[core.properties.classes]: [],
[core.properties.properties]: [],
[core.properties.instances]: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ export const NewTableDialog: FC<NewTableDialogProps> = ({
onClose,
}) => {
const store = useStore();
const [useExistingClass, setUseExistingClass] = useState(
!!initialExistingClass,
);
const [useExistingClass, setUseExistingClass] =
useState(!!initialExistingClass);
const [existingClass, setExistingClass] = useState<string | undefined>(
initialExistingClass,
);
Expand All @@ -52,8 +51,8 @@ export const NewTableDialog: FC<NewTableDialogProps> = ({
isA: core.classes.class,
propVals: {
[core.properties.shortname]: stringToSlug(name),
[core.properties
.description]: `Represents a row in the ${name} table`,
[core.properties.description]:
`Represents a row in the ${name} table`,
[core.properties.recommends]: [core.properties.name],
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,17 @@ export function SearchBox({
const openLink =
!value || selectedResource.error
? '#'
: constructOpenURL(selectedResource.getSubject());
: constructOpenURL(selectedResource.subject);

const navigateToSelectedResource: MouseEventHandler<HTMLAnchorElement> =
e => {
e.preventDefault();
navigate(openLink);
};
const navigateToSelectedResource: MouseEventHandler<
HTMLAnchorElement
> = e => {
e.preventDefault();
navigate(openLink);
};

const title = selectedResource.error
? selectedResource.getSubject()
? selectedResource.subject
: selectedResource.title;

return (
Expand Down
29 changes: 15 additions & 14 deletions browser/data-browser/src/views/Card/ResourceCardTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ interface ResourceCardTitleProps {
resource: Resource;
}

export const ResourceCardTitle: FC<PropsWithChildren<ResourceCardTitleProps>> =
({ resource, children }) => {
const [isA] = useArray(resource, core.properties.isA);
const Icon = getIconForClass(isA[0]);
export const ResourceCardTitle: FC<
PropsWithChildren<ResourceCardTitleProps>
> = ({ resource, children }) => {
const [isA] = useArray(resource, core.properties.isA);
const Icon = getIconForClass(isA[0]);

return (
<TitleRow center gap='1ch'>
<Icon />
<AtomicLink subject={resource.getSubject()}>
<Title subject={resource.getSubject()}>{resource.title}</Title>
</AtomicLink>
{children}
</TitleRow>
);
};
return (
<TitleRow center gap='1ch'>
<Icon />
<AtomicLink subject={resource.getSubject()}>
<Title subject={resource.getSubject()}>{resource.title}</Title>
</AtomicLink>
{children}
</TitleRow>
);
};

const Title = styled.h2<ViewTransitionProps>`
font-size: 1.4rem;
Expand Down
Loading
Loading