Skip to content

Commit cc89ad7

Browse files
committed
Add documentation for tables
1 parent 4a1bbd7 commit cc89ad7

File tree

9 files changed

+137
-101
lines changed

9 files changed

+137
-101
lines changed

browser/data-browser/src/components/ResourceContextMenu/index.tsx

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { useCallback, useState } from 'react';
22
import { useLocation, useNavigate } from 'react-router-dom';
3-
import {
4-
Client,
5-
core,
6-
dataBrowser,
7-
useCanWrite,
8-
useResource,
9-
} from '@tomic/react';
3+
import { Client, core, useCanWrite, useResource } from '@tomic/react';
104
import {
115
editURL,
126
dataURL,
@@ -31,7 +25,6 @@ import {
3125
FaShare,
3226
FaTrash,
3327
FaPlus,
34-
FaFileCsv,
3528
} from 'react-icons/fa6';
3629
import { useQueryScopeHandler } from '../../hooks/useQueryScope';
3730
import {
@@ -44,7 +37,6 @@ import { useCurrentSubject } from '../../helpers/useCurrentSubject';
4437
import { ResourceCodeUsageDialog } from '../../views/CodeUsage/ResourceCodeUsageDialog';
4538
import { useNewRoute } from '../../helpers/useNewRoute';
4639
import { addIf } from '../../helpers/addIf';
47-
import { TableExportDialog } from '../../views/TablePage/TableExportDialog';
4840

4941
export enum ContextMenuOptions {
5042
View = 'view',
@@ -90,7 +82,6 @@ function ResourceContextMenu({
9082
const resource = useResource(subject);
9183
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
9284
const [showCodeUsageDialog, setShowCodeUsageDialog] = useState(false);
93-
const [showExportDialog, setShowExportDialog] = useState(false);
9485
const handleAddClick = useNewRoute(subject);
9586
const [currentSubject] = useCurrentSubject();
9687
const [canWrite] = useCanWrite(resource);
@@ -208,13 +199,6 @@ function ResourceContextMenu({
208199
onClick: () => setShowDeleteDialog(true),
209200
},
210201
),
211-
...addIf(resource.hasClasses(dataBrowser.classes.table), {
212-
id: ContextMenuOptions.Export,
213-
icon: <FaFileCsv />,
214-
label: 'Export to csv',
215-
helper: 'Export the table as a CSV file',
216-
onClick: () => setShowExportDialog(true),
217-
}),
218202
];
219203

220204
const filteredItems = showOnly
@@ -254,11 +238,6 @@ function ResourceContextMenu({
254238
<ResourceUsage resource={resource} />
255239
</>
256240
</ConfirmationDialog>
257-
<TableExportDialog
258-
subject={subject}
259-
show={showExportDialog}
260-
bindShow={setShowExportDialog}
261-
/>
262241
{currentSubject && (
263242
<ResourceCodeUsageDialog
264243
subject={currentSubject}

browser/data-browser/src/components/SideBar/AppMenu.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ import { constructOpenURL } from '../../helpers/navigation';
1010
import { useCurrentSubject } from '../../helpers/useCurrentSubject';
1111
import { SideBarMenuItem } from './SideBarMenuItem';
1212
import { paths } from '../../routes/paths';
13-
import { unknownSubject, useCurrentAgent, useResource } from '@tomic/react';
13+
import {
14+
core,
15+
unknownSubject,
16+
useCurrentAgent,
17+
useResource,
18+
} from '@tomic/react';
1419

1520
// Non standard event type so we have to type it ourselfs for now.
1621
type BeforeInstallPromptEvent = {
@@ -59,7 +64,11 @@ export function AppMenu({ onItemClick }: AppMenuProps): JSX.Element {
5964
<section aria-label='App menu'>
6065
<SideBarMenuItem
6166
icon={<FaUser />}
62-
label={agent ? agentResource.title : 'Login'}
67+
label={
68+
agent
69+
? agentResource.get(core.properties.name) ?? 'User Settings'
70+
: 'Login'
71+
}
6372
helper='See and edit the current Agent / User (u)'
6473
path={paths.agentSettings}
6574
onClick={onItemClick}

browser/data-browser/src/views/TablePage/TablePage.tsx

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@ import {
1616
createResourceDeletedHistoryItem,
1717
useTableHistory,
1818
} from './helpers/useTableHistory';
19+
import { Row as FlexRow, Column } from '../../components/Row';
1920
import { useHandleClearCells } from './helpers/useHandleClearCells';
2021
import { useHandleCopyCommand } from './helpers/useHandleCopyCommand';
2122
import { ExpandedRowDialog } from './ExpandedRowDialog';
23+
import { IconButton } from '../../components/IconButton/IconButton';
24+
import { FaCode, FaFileCsv } from 'react-icons/fa6';
25+
import { ResourceCodeUsageDialog } from '../CodeUsage/ResourceCodeUsageDialog';
26+
import { TableExportDialog } from './TableExportDialog';
2227

2328
const columnToKey = (column: Property) => column.subject;
2429

2530
export function TablePage({ resource }: ResourcePageProps): JSX.Element {
2631
const store = useStore();
2732
const titleId = useId();
2833

34+
const [showCodeUsageDialog, setShowCodeUsageDialog] = useState(false);
35+
const [showExportDialog, setShowExportDialog] = useState(false);
2936
const { tableClass, sorting, setSortBy, collection, invalidateCollection } =
3037
useTableData(resource);
3138

@@ -114,32 +121,60 @@ export function TablePage({ resource }: ResourcePageProps): JSX.Element {
114121
return (
115122
<ContainerFull>
116123
<TablePageContext.Provider value={tablePageContext}>
117-
<EditableTitle resource={resource} id={titleId} />
118-
<FancyTable
119-
columns={columns}
120-
columnSizes={columnSizes}
121-
itemCount={collection.totalMembers + 1}
122-
columnToKey={columnToKey}
123-
labelledBy={titleId}
124-
onClearRow={handleDeleteRow}
125-
onCellResize={handleColumnResize}
126-
onClearCells={handleClearCells}
127-
onCopyCommand={handleCopyCommand}
128-
onPasteCommand={handlePaste}
129-
onUndoCommand={undoLastItem}
130-
onColumnReorder={reorderColumns}
131-
onRowExpand={handleRowExpand}
132-
HeadingComponent={TableHeading}
133-
NewColumnButtonComponent={NewColumnButton}
134-
>
135-
{Row}
136-
</FancyTable>
124+
<Column>
125+
<FlexRow justify='space-between'>
126+
<EditableTitle resource={resource} id={titleId} />
127+
<FlexRow style={{ marginRight: '1rem' }}>
128+
<IconButton
129+
title='Use in code'
130+
onClick={() => setShowCodeUsageDialog(true)}
131+
>
132+
<FaCode />
133+
</IconButton>
134+
<IconButton
135+
title='Use in code'
136+
onClick={() => setShowExportDialog(true)}
137+
>
138+
<FaFileCsv />
139+
</IconButton>
140+
</FlexRow>
141+
</FlexRow>
142+
<FancyTable
143+
columns={columns}
144+
columnSizes={columnSizes}
145+
itemCount={collection.totalMembers + 1}
146+
columnToKey={columnToKey}
147+
labelledBy={titleId}
148+
onClearRow={handleDeleteRow}
149+
onCellResize={handleColumnResize}
150+
onClearCells={handleClearCells}
151+
onCopyCommand={handleCopyCommand}
152+
onPasteCommand={handlePaste}
153+
onUndoCommand={undoLastItem}
154+
onColumnReorder={reorderColumns}
155+
onRowExpand={handleRowExpand}
156+
HeadingComponent={TableHeading}
157+
NewColumnButtonComponent={NewColumnButton}
158+
>
159+
{Row}
160+
</FancyTable>
161+
</Column>
137162
<ExpandedRowDialog
138163
subject={expandedRowSubject ?? unknownSubject}
139164
open={showExpandedRowDialog}
140165
bindOpen={setShowExpandedRowDialog}
141166
/>
142167
</TablePageContext.Provider>
168+
<ResourceCodeUsageDialog
169+
subject={resource.subject}
170+
show={showCodeUsageDialog}
171+
bindShow={setShowCodeUsageDialog}
172+
/>
173+
<TableExportDialog
174+
subject={resource.subject}
175+
show={showExportDialog}
176+
bindShow={setShowExportDialog}
177+
/>
143178
</ContainerFull>
144179
);
145180
}

docs/src/SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
- [AtomicServer](atomic-server.md)
1313
- [When (not) to use it](atomicserver/when-to-use.md)
1414
- [Installation](atomicserver/installation.md)
15-
- [Getting started with the GUI](atomicserver/gui.md)
15+
- [Using the GUI](atomicserver/gui.md)
16+
- [Tables](atomicserver/gui/tables.md)
1617
- [API](atomicserver/API.md)
1718
- [Creating a JSON-AD file](create-json-ad.md)
1819
- [FAQ & troubleshooting](atomicserver/faq.md)
74.3 KB
Binary file not shown.
57.6 KB
Binary file not shown.

docs/src/atomicserver/gui.md

Lines changed: 35 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,55 @@
11
# Using the AtomicServer GUI
22

3-
## Creating the first Agent on AtomicData.dev
4-
5-
Before you can create new things on AtomicData.dev, you'll need an _Agent_.
6-
This is your virtual User, which can create, sign and own things.
7-
8-
Simply open the [demo invite](https://atomicdata.dev/invites/1) and press accept.
9-
10-
Copy the `secret` from the user settings page and save it somewhere safe, like in a password manager.
11-
12-
## Using your local AtomicServer
13-
143
After [running the server](installation.md), open it in your browser.
154
By default, that's at [`http://localhost:9883`](http://localhost:9883).
16-
<!-- (Fun fact: `&#9883;` is HTML entity code for the Atom icon: ⚛.) -->
5+
> Fun fact: `&#9883;` is HTML entity code for the Atom icon: ⚛
176
187
The first screen should show you your main [_Drive_](https://atomicdata.dev/classes/Drive).
19-
You can think of this as your root folder.
8+
You can think of this as the root of the server.
209
It is the resource hosted at the root URL, effectively being the home page of your server.
2110

22-
There's an instruction on the screen about the `/setup` page.
23-
Click this, and you'll get a screen showing an [_Invite_](https://atomicdata.dev/classes/Invite).
24-
Normally, you could `Accept as new user`, but **since you're running on `localhost`, you won't be able to use the newly created Agent on non-local Atomic-Servers**.
25-
26-
Therefore, it may be best to create an Agent on some _other_ running server, such as the [demo Invite on AtomicData.dev](https://atomicdata.dev/invites/1).
27-
And after that, copy the Secret from the `User settings` panel from AtomicData.dev, go back to your `localhost` version, and press `sign in`.
28-
Paste the Secret, and voila! You're signed in.
29-
30-
Now, again go to `/setup`. This time, you can `Accept as {user}`.
31-
After clicking, your Agent has gotten `write` rights for the Drive!
32-
You can verify this by hovering over the description field, clicking the edit icon, and making a few changes.
33-
You can also press the menu button (three dots, top left) and press `Data view` to see your agent after the `write` field.
34-
Note that you can now edit every field.
35-
You can also fetch your data now as various formats.
36-
37-
Try checking out the other features in the menu bar, and check out the `collections`.
11+
In the sidebar you will see a list of resources in the current drive.
12+
At the start these will be:
3813

39-
Again, check out the [README](https://github.com/atomicdata-dev/atomic-server) for more information and guides!
14+
- The setup invite that's used to configure the root agent.
15+
- A resource named `collections`. This is a group of collections that shows collections for all classes in the server, essentially a list of all resources.
16+
- The default ontology. Ontologies are used to define new classes and properties and show to relation between them.
4017

41-
Now, let's create some data.
18+
![The AtomicServer GUI](../assets/ui-guide/ui-guide-fresh-install.avif)
4219

43-
## Creating your first Atomic Data
20+
## Creating an agent
21+
To create data in AtomicServer you'll need an agent.
22+
An agent is like a user account, it signs the changes (commits) you make to data so that others can verify that you made them.
23+
Agents can be used on any AtomicServer as long as they have permission to do so.
4424

45-
Now let's create a [_Table_](https://atomicdata.dev/classes/Table).
46-
A Class represents an abstract concept, such as a `BlogPost` (which we'll do here).
47-
We can do this in a couple of ways:
25+
If your AtomicServer is not reachable from the outside we recommend you create an agent on a public server like [atomicdata.dev](https://atomicdata.dev) as an agent created on a local server can only be used on that server.
26+
The server that hosts your agent cannot do anything on your behalf because your private key is not stored on the server. They can however delete your agent making it unusable.
4827

49-
- Press the `+ icon` button on the left menu (only visible when logged in), and selecting Class
50-
- Opening [Class](https://atomicdata.dev/classes/Class) and pressing `new class`
51-
- Going to the [Classes Collection](https://atomicdata.dev/classes/) and pressing the plus icon
28+
To create an agent on atomicdata.dev you can use the [demo invite](https://atomicdata.dev/invites/1).
29+
If you want to create the agent on your own server you can use the `/setup` invite that was created when you first started the server.
5230

53-
The result is the same: we end up with a form in which we can fill in some details.
31+
Click the "Accept as new user" button and navigate to the User Settings page.
32+
Here you'll find the agent secret. This secret is what you use to login so keep it somewhere safe, like in a password manager. If you lose it you won't be able to recover your account.
5433

55-
Let's add a shortname (singular), and then a description.
56-
After that, we'll add the `required` properties.
57-
This form you're looking at is constructed by using the `required` and `recommended` Properties defined in `Class`.
58-
We can use these same fields to generate our BlogPost resource!
59-
Which fields would be required in a `BlogPost`?
60-
A `name`, and a `description`, probably.
34+
### Setting up the root Agent
35+
Next, we'll set up the root Agent that has write access to the Drive.
36+
If you've chosen to create an Agent on this server using the `/setup` invite, you can skip this step.
6137

62-
So click on the `+ icon` under `requires` and search for these Properties to add them.
38+
Head to the `setup` page by selecting it in the sidebar.
39+
You'll see a button that either says `Accept as <Your agent>` or `Accept as new user`.
40+
If it says 'as new user`, click on login, paste your secret in the input field and return to the invite page.
6341

64-
Now, we can skip the `recommended` properties, and get right to saving our newly created `BlogPost` class.
65-
So, press save, and now look at what you created.
42+
After clicking the accept button you'll be redirected to the home page and you will have write access to the Drive.
43+
You can verify this by hovering over the description field, clicking the edit icon, and making a few changes.
44+
You can also press the menu button (three dots, top left) and press `Data view` to see your agent after the `write` field.
45+
Note that you can now edit every field.
6646

67-
Notice a couple of things:
47+
The `/setup`-invite can only be used once use and will therefore not work anymore.
48+
If you want to re-enable the invite to change the root agent you can start AtomicServer with the `--initialize` flag.
6849

69-
- Your Class has its own URL.
70-
- It has a `parent`, shown in the top of the screen. This has impact on the visibility and rights of your Resource. We'll get to that [later in the documentation](../hierarchy.md).
50+
## Creating your first Atomic Data
7151

72-
Now, go to the navigation bar, which is by default at the bottom of the window. Use its context menu to open the `Data View`.
73-
This view gives you some more insight into your newly created data, and various ways in which you can serialize it.
52+
Now that everything is up and running you can start creating some resources.
53+
To create a new resource, click the + button in the sidebar.
54+
You will be presented with a list of resource types to choose from like Tables, Folders, Documents etc.
55+
You can also create your own types by using ontologies.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Tables
2+
3+
Tables are a way to create and group large amounts of structured data.
4+
5+
![Table](../../assets/ui-guide/gui-tables-example.avif)
6+
7+
Tables consist of rows of resources that share the same parent and class.
8+
The properties of that class are represented as columns in the table.
9+
This means that each column is type-safe, a number column can not contain text data for example.
10+
11+
## Creating a table
12+
13+
To create a table, click the "+" button in the sidebar or a folder and select "Table".
14+
A dialog will appear prompting you to enter a name.
15+
This name will be used as the title of the table as well as the name for the underlying class of the rows.
16+
This new class will already have a `name` property. Using the `name` property as titles on your resources is a best practice as it helps with compatibility between other tools and makes your resources findable by AtomicServer's search functionality.
17+
If you do not want to use the `name` property, you can remove it by clicking on the three dots in the column header and selecting "Remove".
18+
19+
While creating a new table you can also choose to use an existing class by selecting "Use existing class" in the dialog and selecting the desired class from the dropdown.
20+
21+
Classes created by tables are automatically added to the default ontology of the drive. Same goes for the columns of the table.
22+
If you chose to use an existing class, any columns created will be added to the ontology containing that class.
23+
24+
## Features
25+
26+
- **Rearange columns**: You can drag and drop columns to rearrange them.
27+
- **Resize columns**: You can resize columns by dragging the edges of the column header.
28+
- **Sort rows**: Click on a column header to sort the rows by that column.
29+
- **Fast keyboard navigation**: Use the arrow keys to navigate the table with hotkeys similar to Excel.
30+
- **Copy & paste multiple cells**: You can copy and paste multiple cells by selecting them and using `Ctrl/Cmd + C` and `Ctrl/Cmd + V`. Pasting also works across different tables and even different applications that support HTML Table data (Most spreadsheet applications).
31+
- **Export data to CSV**: You can export the data of a table to a CSV file by clicking the "Export" button in the top right.

docs/src/atomicserver/installation.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ You can run AtomicServer in different ways:
88
3. Using [Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) from crates.io: `cargo install atomic-server`
99
4. Manually from source
1010

11-
When you're running AtomicServer, go to [Initial setup and configuration](#Initial-setup-and-configuration).
12-
If you want to run this locally as a developer / contributor, check out [the Contributors guide](https://github.com/atomicdata-dev/atomic-server/blob/develop/CONTRIBUTING.md).
11+
If you want to run AtomicServer locally as a developer / contributor, check out [the Contributors guide](https://github.com/atomicdata-dev/atomic-server/blob/develop/CONTRIBUTING.md).
1312

1413
## 1. Run using docker
1514

@@ -59,7 +58,7 @@ sudo apt-get install -y build-essential pkg-config libssl-dev --fix-missing
5958
- The server loads the `.env` from the current path by default. Create a `.env` file from the default template in your current directory with `atomic-server generate-dotenv`
6059
- After running the server, check the logs and take note of the `Agent Subject` and `Private key`. You should use these in the [`atomic-cli`](https://crates.io/crates/atomic-cli) and [atomic-data-browser](https://github.com/atomicdata-dev/atomic-data-browser) clients for authorization.
6160
- A directory is made: `~/.config/atomic`, which stores your newly created Agent keys, the HTTPS certificates other configuration. Depending on your OS, the actual data is stored in different locations. See use the `show-config` command to find out where, if you need the files.
62-
- Visit `http://localhost:9883/setup` to **register your first (admin) user**. You can use an existing Agent, or create a new one. Note that if you create a `localhost` agent, it cannot be used on the web (since, well, it's local).
61+
- Visit `http://localhost:9883/setup` to **register your first (admin) user**. You can use an existing Agent, or create a new one. Note that if you create a `localhost` agent, it cannot be used on the web (since, well, it's local). More info and steps in [getting started with the GUI](gui.md).
6362

6463
## Running using a tunneling service (easy mode)
6564

0 commit comments

Comments
 (0)