Skip to content

Commit

Permalink
#682 #675 Proxy resources instead of clone for react
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps committed Oct 30, 2023
1 parent 50d1afc commit 1abbb78
Show file tree
Hide file tree
Showing 20 changed files with 158 additions and 107 deletions.
18 changes: 11 additions & 7 deletions browser/data-browser/src/components/forms/InputResourceArray.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { ArrayError, useArray, validateDatatype } from '@tomic/react';
import { Button } from '../Button';
import { InputProps } from './ResourceField';
Expand All @@ -20,6 +20,7 @@ export default function InputResourceArray({
validate: false,
commit,
});

/** Add focus to the last added item */
const [lastIsNew, setLastIsNew] = useState(false);

Expand Down Expand Up @@ -63,13 +64,16 @@ export default function InputResourceArray({
[property.datatype, setArray],
);

function errMaybe(index: number) {
if (err && err.index === index) {
return err;
}
const errMaybe = useCallback(
(index: number) => {
if (err && err.index === index) {
return err;
}

return undefined;
}
return undefined;
},
[err],
);

return (
<Column>
Expand Down
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/forms/InputSlug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function InputSlug({

return (
<Wrapper>
<InputWrapper invalid={!!err}>
<InputWrapper $invalid={!!err}>
<InputStyled
value={inputValue ?? ''}
onChange={handleUpdate}
Expand Down
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/forms/InputString.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function InputString({

return (
<Wrapper>
<InputWrapper invalid={!!err}>
<InputWrapper $invalid={!!err}>
<InputStyled
value={value === undefined ? '' : value}
onChange={handleUpdate}
Expand Down
6 changes: 3 additions & 3 deletions browser/data-browser/src/components/forms/InputStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ export const LabelHelper = styled.label`
`;

export interface InputWrapperProps {
invalid?: boolean;
$invalid?: boolean;
}

/** A wrapper for inputs, for example when you want to add a button to some field */
export const InputWrapper = styled.div<InputWrapperProps>`
display: flex;
flex: 1;
--border-color: ${({ invalid, theme }) =>
invalid ? theme.colors.alert : theme.colors.bg2};
--border-color: ${({ $invalid, theme }) =>
$invalid ? theme.colors.alert : theme.colors.bg2};
border: solid 1px var(--border-color);
border-radius: ${props => props.theme.radius};
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useState, useCallback } from 'react';
import { useEffectOnce } from '../../../hooks/useEffectOnce';
import { Button } from '../../Button';
import { DialogTitle, DialogContent, DialogActions } from '../../Dialog';
import { ErrorLook } from '../../ErrorLook';
import { ErrorBlock, ErrorLook } from '../../ErrorLook';
import { useSaveResource } from '../hooks/useSaveResource';
import { InlineErrMessage } from '../InputStyles';
import { ResourceForm, ResourceFormVariant } from '../ResourceForm';
Expand Down Expand Up @@ -32,7 +32,7 @@ export const NewFormDialog = ({
const [className] = useTitle(klass);
const store = useStore();

const [subject, setSubject] = useState(store.createSubject());
const [subject, setSubject] = useState<string>();

const { subjectErr, subjectValue, setSubjectValue, resource } = useNewForm({
klass,
Expand Down Expand Up @@ -70,6 +70,10 @@ export const NewFormDialog = ({
return <ErrorLook>No parent set</ErrorLook>;
}

if (resource.error) {
return <ErrorBlock error={resource.error}></ErrorBlock>;
}

return (
<>
<DialogTitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ export const NewFormFullPage = ({
const [subject, setSubject] = useQueryString('newSubject');
const [parentSubject] = useQueryString('parent');

const { subjectErr, subjectValue, setSubjectValue, resource } = useNewForm({
klass,
setSubject,
initialSubject: subject,
parent: parentSubject,
});
const { initialized, subjectErr, subjectValue, setSubjectValue, resource } =
useNewForm({
klass,
setSubject,
initialSubject: subject,
parent: parentSubject,
});

if (!initialized) return <>Initializing Resource</>;

return (
<>
Expand Down
26 changes: 17 additions & 9 deletions browser/data-browser/src/components/forms/NewForm/useNewForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
useResource,
useArray,
Core,
core,
} from '@tomic/react';
import { useState, useEffect } from 'react';

Expand All @@ -23,6 +24,8 @@ export const useNewForm = (args: UseNewForm) => {
const { klass, setSubject, initialSubject, parent } = args;

const store = useStore();
const [initialized, setInitialized] = useState(false);

const [subjectValue, setSubjectValueInternal] = useState<string>(() => {
if (initialSubject === undefined) {
return store.createSubject(klass.props.shortname);
Expand All @@ -33,19 +36,23 @@ export const useNewForm = (args: UseNewForm) => {

const [subjectErr, setSubjectErr] = useState<Error | undefined>(undefined);
const resource = useResource(subjectValue, resourseOpts);
const [parentVal, setParent] = useString(resource, properties.parent);
const [isAVal, setIsA] = useArray(resource, properties.isA);
const [parentVal] = useString(resource, properties.parent);
const [isAVal] = useArray(resource, properties.isA);

// When the resource is created or updated, make sure that the parent and class are present
useEffect(() => {
if (parentVal !== parent) {
setParent(parent);
}
(async () => {
if (parentVal !== parent) {
await resource.set(core.properties.parent, parent, store);
}

if (isAVal.length === 0) {
setIsA([klass.getSubject()]);
}
}, [resource, parent]);
if (isAVal.length === 0) {
await resource.addClasses(store, klass.getSubject());
}

setInitialized(true);
})();
}, [resource]);

async function setSubjectValue(newSubject: string) {
setSubjectValueInternal(newSubject);
Expand All @@ -69,5 +76,6 @@ export const useNewForm = (args: UseNewForm) => {
subjectValue,
setSubjectValue,
resource,
initialized,
};
};
4 changes: 2 additions & 2 deletions browser/data-browser/src/components/forms/RangeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function RangeInput({

return (
<Row center gap='0.5rem'>
<InputWrapper invalid={invalid}>
<InputWrapper $invalid={invalid}>
<InputStyled
type='number'
max={maxValue}
Expand All @@ -84,7 +84,7 @@ export function RangeInput({
/>
</InputWrapper>
{' - '}
<InputWrapper invalid={invalid}>
<InputWrapper $invalid={invalid}>
<InputStyled
type='number'
placeholder='max'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function SearchBox({
onChange(newValue);
setInputValue('');
} catch (e) {
console.error(e);
// not a URL
}

Expand Down Expand Up @@ -129,7 +130,7 @@ export function SearchBox({
disabled={disabled}
ref={triggerRef}
tabIndex={0}
empty={inputValue.length === 0}
$empty={inputValue.length === 0}
onFocus={handleTriggerFocus}
onClick={() => {
setOpen(true);
Expand Down Expand Up @@ -182,7 +183,7 @@ export function SearchBox({
);
}

const TriggerButton = styled.button<{ empty: boolean }>`
const TriggerButton = styled.button<{ $empty: boolean }>`
display: flex;
align-items: center;
padding: 0.5rem;
Expand All @@ -194,7 +195,7 @@ const TriggerButton = styled.button<{ empty: boolean }>`
width: 100%;
overflow: hidden;
cursor: text;
color: ${p => (p.empty ? p.theme.colors.textLight : p.theme.colors.text)};
color: ${p => (p.$empty ? p.theme.colors.textLight : p.theme.colors.text)};
&:disabled {
background-color: ${props => props.theme.colors.bg1};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { urls, useServerSearch } from '@tomic/react';
import { core, useServerSearch } from '@tomic/react';
import React, { useMemo, useState } from 'react';
import styled, { css } from 'styled-components';
import { ResourceResultLine, ResultLine } from './ResultLine';
Expand Down Expand Up @@ -40,23 +40,22 @@ export function SearchBoxWindow({
const [realIndex, setIndex] = useState<number | undefined>(undefined);
const { below } = useAvailableSpace(true, triggerRef);
const wrapperRef = React.useRef<HTMLDivElement>(null);
const filters = useMemo(

const searchOptions = useMemo(
() => ({
...(isA ? { [urls.properties.isA]: isA } : {}),
filters: {
...(isA ? { [core.properties.isA]: isA } : {}),
},
parents: scopes ?? [drive, 'https://atomicdata.dev'],
}),
[isA],
[isA, scopes],
);

const parents = useMemo(
() => scopes ?? [drive, 'https://atomicdata.dev'],
[scopes],
const { results, error: searchError } = useServerSearch(
searchValue,
searchOptions,
);

const { results } = useServerSearch(searchValue, {
filters,
parents,
});

const isAboveTrigger = below < remToPixels(BOX_HEIGHT_REM);

const offset = onCreateItem ? 1 : 0;
Expand Down Expand Up @@ -156,8 +155,16 @@ export function SearchBoxWindow({
}
};

if (searchError) {
return (
<Wrapper onBlur={handleBlur} ref={wrapperRef} $above={isAboveTrigger}>
<CenteredMessage>Error: {searchError.message}</CenteredMessage>
</Wrapper>
);
}

return (
<Wrapper onBlur={handleBlur} ref={wrapperRef} above={isAboveTrigger}>
<Wrapper onBlur={handleBlur} ref={wrapperRef} $above={isAboveTrigger}>
<Input
autoFocus
placeholder={placeholder}
Expand Down Expand Up @@ -220,7 +227,7 @@ const ResultBox = styled.div`
overflow: hidden;
`;

const Wrapper = styled.div<{ above: boolean }>`
const Wrapper = styled.div<{ $above: boolean }>`
display: flex;
background-color: ${p => p.theme.colors.bg};
Expand All @@ -230,8 +237,8 @@ const Wrapper = styled.div<{ above: boolean }>`
height: ${BOX_HEIGHT_REM}rem;
position: absolute;
width: var(--radix-popover-trigger-width);
${({ above, theme }) =>
above
${({ $above, theme }) =>
$above
? css`
bottom: 0;
flex-direction: column-reverse;
Expand Down
14 changes: 8 additions & 6 deletions browser/data-browser/src/handlers/sideBarHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ export function buildSideBarRemoveResourceHandler(store: Store) {
const parent = await store.getResourceAsync(parentSubject);
const subResources = parent.getSubjects(urls.properties.subResources);

await parent.set(
urls.properties.subResources,
subResources.filter(r => r !== resource.getSubject()),
store,
);
if (subResources.length > 0) {
await parent.set(
urls.properties.subResources,
subResources.filter(r => r !== resource.getSubject()),
store,
);

parent.save(store);
await parent.save(store);
}
};
}
4 changes: 2 additions & 2 deletions browser/data-browser/src/helpers/getNamePartFromProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const getNamePartFromProps = (
props: Record<string, JSONValue>,
): string =>
normalizeName(
(props?.[core.properties.shortname] as string) ??
(props?.[core.properties.name] as string) ??
(props?.[core.properties.shortname] as string | undefined) ??
(props?.[core.properties.name] as string | undefined) ??
randomString(8),
);
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function PropertyFormCommon({
const [ontologySubject] = useCurrentSubject();
const ontologyResource = useResource(ontologySubject);
const allowsOnly = useProperty(urls.properties.allowsOnly);

const handleCreateClass = useCallback(
async (shortname: string) => {
const createdSubject = await newClass(shortname, ontologyResource, store);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function DecimalPlacesInput({
Decimal Places
</FormGroupHeading>
<div>
<InputWrapper invalid={error !== undefined}>
<InputWrapper $invalid={error !== undefined}>
<InputStyled
id={id}
type='number'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function PropertyForm({
}}
>
<div>
<InputWrapper invalid={!!nameError}>
<InputWrapper $invalid={!!nameError}>
<InputStyled
type='text'
value={name}
Expand Down
2 changes: 0 additions & 2 deletions browser/lib/src/commit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,10 @@ export function parseAndApplyCommit(jsonAdObjStr: string, store: Store) {
const { subject, id, destroy, signature } = commit;

let resource = store.resources.get(subject) as Resource;
let isNew = false;

// If the resource doesn't exist in the store, create the resource
if (!resource) {
resource = new Resource(subject);
isNew = true;
} else {
// Commit has already been applied here, ignore the commit
if (resource.appliedCommitSignatures.has(signature)) {
Expand Down
Loading

0 comments on commit 1abbb78

Please sign in to comment.