Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c544e47
#25 Table editor
Polleps Nov 4, 2022
04c9083
#25 WIP Add columns
Polleps Dec 23, 2022
aa40d5b
WIP New Column Dialog
Polleps Jan 12, 2023
9a6a746
#25 Add new text column dialog
Polleps Jan 27, 2023
c63d7d6
#25 Add select, number and checkbox columns
Polleps Feb 16, 2023
71b3957
#240 Better error display in sidebar
Polleps Feb 21, 2023
870bf11
#25 Fix ResourceListInput not setting values
Polleps Feb 21, 2023
d7fbdc2
#25 Date columns
Polleps Feb 24, 2023
c281835
#25 File and Relation Column
Polleps Mar 9, 2023
c448f3c
Fix importer and replace table urls
Polleps Mar 13, 2023
bbf7fa9
#25 New table button
Polleps Mar 13, 2023
cdd48dd
#25 Fix rebase mistake with dependency version
Polleps Mar 13, 2023
feec987
Fix search documentation + small refactor
Polleps Mar 13, 2023
74272d9
#25 Fix tables not loading on first visit
Polleps Mar 13, 2023
75bcb64
Fix tests & linter
joepio Mar 29, 2023
8f194d3
#25 Improve File Column Popover
Polleps Mar 15, 2023
2d98f78
#25 Table pasting
Polleps Apr 3, 2023
958e1f6
#25 Update table when column is added
Polleps Apr 3, 2023
7402f78
View Transitions
Polleps Apr 14, 2023
09ef971
#25 Save column widths
Polleps Apr 18, 2023
5794aa0
#25 Edit columns
Polleps Apr 24, 2023
52515e1
#25 Delete table columns and add usage info to data page and delete …
Polleps May 2, 2023
66f2ec9
Update build action
Polleps May 2, 2023
620eb04
#25 Allow sorting of columns in table
Polleps May 16, 2023
5c83823
#25 Add column reorder feature to tables
Polleps May 25, 2023
e21131d
#25 Improve accessibility
Polleps Jun 5, 2023
eea1657
#25 Improve keyboard controls for tables
Polleps Jun 12, 2023
dc4a69c
#25 Cursor continues from multiselect corner instead of original pos…
Polleps Jun 12, 2023
cc31ecb
#25 Table wide undo history
Polleps Jun 14, 2023
2c6ba5a
#25 Fix scroll snap bug when indicator loads in
Polleps Jun 14, 2023
0fce17a
#25 Expand row feature
Polleps Jun 19, 2023
36f4f31
#25 Add external properties to tables
Polleps Jun 19, 2023
5e14569
#25 Fix some styling issues
Polleps Jun 27, 2023
0267822
#25 Add flaky table test and fix a lot of smaller issues
Polleps Jul 11, 2023
dbed062
#25 Add beta badge to new table dialog
Polleps Jul 11, 2023
cf03443
Fix History Page test
Polleps Jul 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
#25 Allow sorting of columns in table
  • Loading branch information
Polleps committed Jul 12, 2023
commit 620eb0400453ec2d015256a557da08aeca482ce8
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ export function NewTableButton({
await instanceResource.set(properties.shortname, stringToSlug(name), store);
await instanceResource.set(
properties.description,
`A row in the ${name} table`,
`Represents a row in the ${name} table`,
store,
);
await instanceResource.set(properties.isA, [classes.class], store);
await instanceResource.set(properties.parent, parent, store);
await instanceResource.set(properties.recommends, [properties.name], store);
await instanceResource.save(store);

createResourceAndNavigate('table', {
Expand Down
4 changes: 2 additions & 2 deletions data-browser/src/hooks/useGlobalStylesWhileMounted.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useId } from 'react';
import { useId, useInsertionEffect } from 'react';

const getNode = (id: string) => {
const existingNode = document.getElementById(id);
Expand All @@ -21,7 +21,7 @@ const getNode = (id: string) => {
export function useGlobalStylesWhileMounted(cssText: string) {
const id = useId();

useEffect(() => {
useInsertionEffect(() => {
const node = getNode(id);

node.innerHTML = cssText;
Expand Down
13 changes: 10 additions & 3 deletions data-browser/src/views/File/useFileImageTransitionStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import { getTransitionName } from '../../helpers/transitionName';
import { useGlobalStylesWhileMounted } from '../../hooks/useGlobalStylesWhileMounted';

export function useFileImageTransitionStyles(subject: string) {
const name = getTransitionName('file-image', subject);
let css = '';
let name = 'none';

useGlobalStylesWhileMounted(`
try {
name = getTransitionName('file-image', subject);
css = `
::view-transition-old(${name}),
::view-transition-new(${name}) {
mix-blend-mode: normal;
Expand All @@ -20,8 +23,12 @@ export function useFileImageTransitionStyles(subject: string) {
animation: none;
object-fit: cover;
}
`;
} catch (e) {
// Do nothing
}

`);
useGlobalStylesWhileMounted(css);

return { viewTransitionName: name } as Record<string, string>;
}
17 changes: 8 additions & 9 deletions data-browser/src/views/ResourcePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ import styled from 'styled-components';
import { FolderPage } from './FolderPage';
import { ArticlePage } from './Article';
import { ViewTransitionProps } from '../helpers/ViewTransitionProps';
import { getTransitionName } from '../helpers/transitionName';
import { transitionName } from '../helpers/transitionName';
import { TablePage } from './TablePage';

/** These properties are passed to every View at Page level */
export type ResourcePageProps = {
resource: Resource;
};

type Props = {
subject: string;
};
Expand All @@ -48,7 +53,7 @@ function ResourcePage({ subject }: Props): JSX.Element {
// we remove it to make the page becomes interavtive again.
useEffect(() => {
document.body.removeAttribute('inert');
});
}, []);

if (resource.loading) {
return (
Expand Down Expand Up @@ -82,15 +87,9 @@ const Main = React.memo(styled.main<ViewTransitionProps>`
height: calc(
100% - (${p => p.theme.heights.breadCrumbBar} + ${PARENT_PADDING_BLOCK} * 2)
);
view-transition-name: ${props =>
getTransitionName('resource-page', props.subject)};
${p => transitionName('resource-page', p.subject)}
`);

/** There properties are passed to every View at Page level */
export type ResourcePageProps = {
resource: Resource;
};

function selectComponent(klass: string) {
switch (klass) {
case urls.classes.collection:
Expand Down
25 changes: 5 additions & 20 deletions data-browser/src/views/TablePage/TableCell.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
JSONValue,
Property,
Resource,
urls,
useStore,
useValue,
} from '@tomic/react';
import { JSONValue, Property, Resource, urls, useValue } from '@tomic/react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Cell } from '../../components/TableEditor';
import { CellAlign } from '../../components/TableEditor/Cell';
Expand All @@ -28,11 +21,6 @@ interface TableCell {
invalidateTable?: () => void;
}

const createdAtOpts = {
commitDebounce: 0,
commit: false,
};

function useIsEditing(row: number, column: number) {
const { cursorMode, selectedColumn, selectedRow } = useTableEditorContext();

Expand All @@ -56,13 +44,12 @@ export function TableCell({
property,
invalidateTable,
}: TableCell): JSX.Element {
const store = useStore();
const [markForInvalidate, setMarkForInvalidate] = useState(false);
const [value, setValue] = useValue(resource, property.subject, valueOpts);
const [createdAt, setCreatedAt] = useValue(
resource,
urls.properties.commit.createdAt,
createdAtOpts,
valueOpts,
);

const dataType = property.datatype;
Expand All @@ -78,8 +65,8 @@ export function TableCell({
const onChange = useCallback(
async (v: JSONValue) => {
if (!createdAt) {
await setCreatedAt(Date.now());
await setValue(v);
await setCreatedAt(Date.now());
setMarkForInvalidate(true);

return;
Expand All @@ -99,10 +86,8 @@ export function TableCell({

useEffect(() => {
if (!isEditing && markForInvalidate) {
resource.save(store).then(() => {
invalidateTable?.();
setMarkForInvalidate(false);
});
setMarkForInvalidate(false);
invalidateTable?.();
}
}, [isEditing, markForInvalidate]);

Expand Down
48 changes: 44 additions & 4 deletions data-browser/src/views/TablePage/TableHeading.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
import { Property, useResource, useTitle } from '@tomic/react';
import {
Datatype,
Property,
Resource,
useResource,
useTitle,
} from '@tomic/react';
import React from 'react';
import { FaAtom } from 'react-icons/fa';
import { FaAngleDown, FaAngleUp, FaAtom } from 'react-icons/fa';
import styled from 'styled-components';
import { dataTypeIconMap } from './dataTypeMaps';
import { TableHeadingMenu } from './TableHeadingMenu';
import { TablePageContext } from './tablePageContext';
import { IconType } from 'react-icons';
import { TableSorting } from './tableSorting';

export interface TableHeadingProps {
column: Property;
}

function getIcon(
propResource: Resource,
sorting: TableSorting,
dataType: Datatype,
): IconType {
if (sorting.prop === propResource.getSubject()) {
return sorting.sortDesc ? FaAngleDown : FaAngleUp;
}

return dataTypeIconMap.get(dataType) ?? FaAtom;
}

export function TableHeading({ column }: TableHeadingProps): JSX.Element {
const Icon = dataTypeIconMap.get(column.datatype!) ?? FaAtom;
const propResource = useResource(column.subject);
const [title] = useTitle(propResource);
const { setSortBy, sorting } = React.useContext(TablePageContext);

const Icon = getIcon(propResource, sorting, column.datatype);
const isSorted = sorting.prop === propResource.getSubject();

return (
<>
<Wrapper>
<Icon />
{title || column.shortname}
<NameButton
onClick={() => setSortBy(propResource.getSubject())}
bold={isSorted}
>
{title || column.shortname}
</NameButton>
</Wrapper>
<TableHeadingMenu resource={propResource} />
</>
Expand All @@ -34,3 +63,14 @@ const Wrapper = styled.div`
color: ${p => p.theme.colors.textLight};
}
`;

interface NameButtonProps {
bold?: boolean;
}

const NameButton = styled.button<NameButtonProps>`
background: none;
border: none;
cursor: pointer;
font-weight: ${p => (p.bold ? 'bold' : 'normal')};
`;
18 changes: 13 additions & 5 deletions data-browser/src/views/TablePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TableNewRow, TableRow } from './TableRow';
import { useTableData } from './useTableData';
import { getValuesFromSubject } from './helpers/clipboard';
import { NewColumnButton } from './NewColumnButton';
import { TablePageContext } from './tablePageContext';
import { TablePageContext, TablePageContextType } from './tablePageContext';
import { useHandlePaste } from './helpers/useHandlePaste';
import { useHandleColumnResize } from './helpers/useHandleColumnResize';

Expand All @@ -33,8 +33,14 @@ const transformToPropertiesPerSubject = async (

export function TablePage({ resource }: ResourcePageProps): JSX.Element {
const store = useStore();
const { tableClass, collection, invalidateCollection, collectionVersion } =
useTableData(resource);
const {
tableClass,
sorting,
setSortBy,
collection,
invalidateCollection,
collectionVersion,
} = useTableData(resource);

const columns = useTableColumns(tableClass);

Expand All @@ -46,11 +52,13 @@ export function TablePage({ resource }: ResourcePageProps): JSX.Element {
collectionVersion,
);

const tablePageContext = useMemo(
const tablePageContext: TablePageContextType = useMemo(
() => ({
tableClassResource: tableClass,
sorting,
setSortBy,
}),
[tableClass],
[tableClass, setSortBy, sorting],
);

const handleDeleteRow = useCallback(
Expand Down
8 changes: 8 additions & 0 deletions data-browser/src/views/TablePage/tablePageContext.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { Resource, unknownSubject } from '@tomic/react';
import { createContext } from 'react';
import { TableSorting } from './tableSorting';

export interface TablePageContextType {
tableClassResource: Resource;
sorting: TableSorting;
setSortBy: React.Dispatch<string>;
}

export const TablePageContext = createContext<TablePageContextType>({
tableClassResource: new Resource(unknownSubject),
sorting: {
prop: '',
sortDesc: true,
},
setSortBy: () => undefined,
});
8 changes: 8 additions & 0 deletions data-browser/src/views/TablePage/tableSorting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { urls } from '@tomic/react';

export interface TableSorting {
prop: string;
sortDesc: boolean;
}

export const DEFAULT_SORT_PROP = urls.properties.commit.createdAt;
46 changes: 41 additions & 5 deletions data-browser/src/views/TablePage/useTableData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,63 @@ import {
useResource,
useSubject,
} from '@tomic/react';
import { useMemo } from 'react';
import { useMemo, useReducer } from 'react';
import { TableSorting, DEFAULT_SORT_PROP } from './tableSorting';

const PAGE_SIZE = 30;
const DEFAULT_SORT = urls.properties.commit.createdAt;
const DEFAULT_SORT = {
prop: DEFAULT_SORT_PROP,
sortDesc: false,
};

type UseTableDataResult = {
tableClass: Resource;
sorting: TableSorting;
setSortBy: React.Dispatch<string>;
} & UseCollectionResult;

const useTableSorting = () =>
useReducer<(state: TableSorting, property: string) => TableSorting>(
(state, property) => {
if (state.prop === property && state.sortDesc) {
return DEFAULT_SORT;
}

if (state.prop === property) {
return {
...state,
sortDesc: true,
};
}

return {
prop: property,
sortDesc: false,
};
},
DEFAULT_SORT,
);

export function useTableData(resource: Resource): UseTableDataResult {
const [sorting, setSortBy] = useTableSorting();

const [classSubject] = useSubject(resource, urls.properties.classType);
const tableClass = useResource(classSubject);

const queryFilter = useMemo(
() => ({
property: urls.properties.parent,
value: resource.getSubject(),
sort_by: DEFAULT_SORT,
sort_by: sorting.prop,
sort_desc: sorting.sortDesc,
}),
[resource.getSubject()],
[resource.getSubject(), sorting.prop, sorting.sortDesc],
);

return { tableClass, ...useCollection(queryFilter, PAGE_SIZE) };
return {
tableClass,
sorting,
setSortBy,
...useCollection(queryFilter, PAGE_SIZE),
};
}
5 changes: 5 additions & 0 deletions lib/src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface QueryFilter {
property?: string;
value?: string;
sort_by?: string;
sort_desc?: boolean;
}

export interface CollectionParams extends QueryFilter {
Expand Down Expand Up @@ -59,6 +60,10 @@ export class Collection {
return this.params.sort_by;
}

public get sortDesc(): boolean {
return !!this.params.sort_desc;
}

public get pageSize(): number {
return parseInt(this.params.page_size, 10);
}
Expand Down
Loading