Skip to content

Commit

Permalink
#648 Ontology Edit view
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps authored and joepio committed Nov 2, 2023
1 parent 661873f commit 760bce7
Show file tree
Hide file tree
Showing 36 changed files with 1,463 additions and 314 deletions.
92 changes: 0 additions & 92 deletions browser/data-browser/src/components/CQWrapper.tsx

This file was deleted.

52 changes: 35 additions & 17 deletions browser/data-browser/src/components/ResourceContextMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,40 @@ import { ResourceInline } from '../../views/ResourceInline';
import { ResourceUsage } from '../ResourceUsage';
import { useCurrentSubject } from '../../helpers/useCurrentSubject';

export enum ContextMenuOptions {
View = 'view',
Data = 'data',
Edit = 'edit',
Refresh = 'refresh',
Scope = 'scope',
Share = 'share',
Delete = 'delete',
History = 'history',
Import = 'import',
}

export interface ResourceContextMenuProps {
subject: string;
// ID's of actions that are hidden
hide?: string[];
// If given only these options will appear in the list.
showOnly?: ContextMenuOptions[];
trigger?: DropdownTriggerRenderFunction;
simple?: boolean;
/** If it's the primary menu in the navbar. Used for triggering keyboard shortcut */
isMainMenu?: boolean;
bindActive?: (active: boolean) => void;
/** Callback that is called after the resource was deleted */
onAfterDelete?: () => void;
}

/** Dropdown menu that opens a bunch of actions for some resource */
function ResourceContextMenu({
subject,
hide,
showOnly,
trigger,
simple,
isMainMenu,
bindActive,
onAfterDelete,
}: ResourceContextMenuProps) {
const store = useStore();
const navigate = useNavigate();
Expand All @@ -69,6 +84,7 @@ function ResourceContextMenu({

try {
await resource.destroy(store);
onAfterDelete?.();
toast.success('Resource deleted!');

if (currentSubject === subject) {
Expand All @@ -77,7 +93,7 @@ function ResourceContextMenu({
} catch (error) {
toast.error(error.message);
}
}, [resource, navigate, currentSubject]);
}, [resource, navigate, currentSubject, onAfterDelete]);

if (subject === undefined) {
return null;
Expand All @@ -93,22 +109,22 @@ function ResourceContextMenu({
: [
{
disabled: location.pathname.startsWith(paths.show),
id: 'view',
id: ContextMenuOptions.View,
label: 'normal view',
helper: 'Open the regular, default View.',
onClick: () => navigate(constructOpenURL(subject)),
},
{
disabled: location.pathname.startsWith(paths.data),
id: 'data',
id: ContextMenuOptions.Data,
label: 'data view',
helper: 'View the resource and its properties in the Data View.',
shortcut: shortcuts.data,
onClick: () => navigate(dataURL(subject)),
},
DIVIDER,
{
id: 'refresh',
id: ContextMenuOptions.Refresh,
icon: <FaRedo />,
label: 'refresh',
helper:
Expand All @@ -118,55 +134,57 @@ function ResourceContextMenu({
]),
{
// disabled: !canWrite || location.pathname.startsWith(paths.edit),
id: 'edit',
id: ContextMenuOptions.Edit,
label: 'edit',
helper: 'Open the edit form.',
icon: <FaEdit />,
shortcut: simple ? '' : shortcuts.edit,
onClick: () => navigate(editURL(subject)),
},
{
id: 'scope',
id: ContextMenuOptions.Scope,
label: 'search in',
helper: 'Scope search to resource',
icon: <FaSearch />,
onClick: enableScope,
},
{
// disabled: !canWrite || history.location.pathname.startsWith(paths.edit),
id: 'share',
id: ContextMenuOptions.Share,
label: 'share',
icon: <FaShareSquare />,
helper: 'Open the share menu',
onClick: () => navigate(shareURL(subject)),
},
{
// disabled: !canWrite,
id: 'delete',
id: ContextMenuOptions.Delete,
icon: <FaTrash />,
label: 'delete',
helper:
'Fetch the resouce again from the server, possibly see new changes.',
helper: 'Delete this resource.',
onClick: () => setShowDeleteDialog(true),
},
{
id: 'history',
id: ContextMenuOptions.History,
icon: <FaClock />,
label: 'history',
helper: 'Show the history of this resource',
onClick: () => navigate(historyURL(subject)),
},
{
id: 'import',
id: ContextMenuOptions.Import,
icon: <FaDownload />,
label: 'import',
helper: 'Import Atomic Data to this resource',
onClick: () => navigate(importerURL(subject)),
},
];

const filteredItems = hide
? items.filter(item => !isItem(item) || !hide.includes(item.id))
const filteredItems = showOnly
? items.filter(
item =>
!isItem(item) || showOnly.includes(item.id as ContextMenuOptions),
)
: items;

const triggerComp = trigger ?? buildDefaultTrigger(<FaEllipsisV />);
Expand Down
68 changes: 68 additions & 0 deletions browser/data-browser/src/components/forms/AtomicSelectInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Resource, useValue } from '@tomic/react';
import React from 'react';
import { InputWrapper } from './InputStyles';
import styled, { css } from 'styled-components';

interface AtomicSelectInputProps {
resource: Resource;
property: string;
options: {
value: string;
label: string;
}[];
commit?: boolean;
}

type Props = AtomicSelectInputProps &
Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange' | 'resource'>;

export function AtomicSelectInput({
resource,
property,
options,
commit = false,
...props
}: Props): JSX.Element {
const [value, setValue] = useValue(resource, property, { commit });

const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setValue(e.target.value);
};

return (
<InputWrapper>
<SelectWrapper disabled={!!props.disabled}>
<Select {...props} onChange={handleChange} value={value as string}>
{options.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</Select>
</SelectWrapper>
</InputWrapper>
);
}

const SelectWrapper = styled.span<{ disabled: boolean }>`
width: 100%;
padding-inline: 0.2rem;
${p =>
p.disabled &&
css`
background-color: ${props => props.theme.colors.bg1};
`}
`;

const Select = styled.select`
width: 100%;
border: none;
outline: none;
height: 2rem;
&:disabled {
color: ${props => props.theme.colors.textLight};
background-color: transparent;
}
`;
29 changes: 22 additions & 7 deletions browser/data-browser/src/components/forms/ErrorChip.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import { styled, keyframes } from 'styled-components';
import { styled, keyframes, css } from 'styled-components';

const fadeIn = keyframes`
from {
opacity: 0;
top: var(--error-chip-starting-position);
top: var(--error-chip-start);
}
to {
opacity: 1;
top: 0.5rem;
top: var(--error-chip-end);
}
`;

export const ErrorChip = styled.span<{ noMovement?: boolean }>`
--error-chip-starting-position: ${p => (p.noMovement ? '0.5rem' : '0rem')};
export const ErrorChip = styled.span<{
noMovement?: boolean;
top?: string;
}>`
--error-chip-end: ${p => p.top ?? '0.5rem'};
--error-chip-start: calc(var(--error-chip-end) - 0.5rem);
position: relative;
top: 0.5rem;
top: var(--error-chip-end);
background-color: ${p => p.theme.colors.alert};
color: white;
padding: 0.25rem 0.5rem;
border-radius: ${p => p.theme.radius};
animation: ${fadeIn} 0.1s ease-in-out;
box-shadow: ${p => p.theme.boxShadowSoft};
${p =>
!p.noMovement
? css`
animation: ${fadeIn} 0.1s ease-in-out;
`
: ''}
&::before {
--triangle-size: 0.5rem;
content: '';
Expand All @@ -34,3 +44,8 @@ export const ErrorChip = styled.span<{ noMovement?: boolean }>`
clip-path: polygon(0% 100%, 100% 100%, 50% 0%);
}
`;

export const ErrorChipInput = styled(ErrorChip)`
position: absolute;
--error-chip-end: ${p => p.top ?? '2rem'};
`;
4 changes: 3 additions & 1 deletion browser/data-browser/src/components/forms/InputBoolean.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import { ErrMessage, InputStyled } from './InputStyles';
export default function InputBoolean({
resource,
property,
commit,
...props
}: InputProps): JSX.Element {
const [err, setErr] = useState<Error | undefined>(undefined);
const [value, setValue] = useBoolean(resource, property.subject, {
handleValidationError: setErr,
commit,
});

function handleUpdate(e) {
function handleUpdate(e: React.ChangeEvent<HTMLInputElement>) {
setValue(e.target.checked);
}

Expand Down
Loading

0 comments on commit 760bce7

Please sign in to comment.