Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions app/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ func FetchTasks(conn *thingsdb.Conn, scope string) ([]Task, error) {
res, err := conn.QueryRaw(scope, `
// TiCode query tasks
assert(tasks().len() <= 100, 'too many tasks; use "tasks()" instead');
tasks().map(|task| {
return tasks().map(|task| {
id: task.id(),
owner: task.owner(),
at: task.at(),
error: task.err(),
});
}), 1;
`, nil)
if err != nil {
return nil, err
Expand Down Expand Up @@ -194,13 +194,13 @@ func FetchTask(conn *thingsdb.Conn, scope string, taskId uint64) (*TaskDetail, e
var taskDetail TaskDetail
res, err := conn.QueryRaw(scope, `
task = task(task_id);
{
return {
id: task.id(),
owner: task.owner(),
at: task.at(),
error: task.err(),
closure: str(task.closure()),
};
}, 1;
`, map[string]any{"task_id": taskId})
if err != nil {
return nil, err
Expand All @@ -216,7 +216,7 @@ func FetchThing(conn *thingsdb.Conn, scope string, thingsId uint64) (any, error)
// Thing ID 1 is always the root for containers, except for old ThingsDB
// collections. However, in an old ThingsDB collecion there is no "1",
// so we can in this case just return the root.
return conn.Query(scope, "root();", nil)
return conn.Query(scope, "return root(), 1;", nil)
}
return conn.Query(scope, "thing(id);", map[string]any{"id": thingsId})
return conn.Query(scope, "return thing(id), 1;", map[string]any{"id": thingsId})
}
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default defineConfig([
},
rules: {
"semi": ["error", "always"],
"indent": ["error", 2]
"indent": ["error", 2],
}
},
]);
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@monaco-editor/react": "^4.7.0",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/themes": "^3.3.0",
"elkjs": "^0.11.1",
"lossless-json": "^4.3.0",
"radix-ui": "^1.4.3",
"react": "^19.2.6",
Expand Down
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function App() {
{errorMessage && (
<NotificationToast
message={errorMessage}
onClear={() => setErrorMessage(null)}
onClear={() => { setErrorMessage(null); }}
/>
)}
</>
Expand All @@ -32,7 +32,7 @@ export default function App() {
{errorMessage && (
<NotificationToast
message={errorMessage}
onClear={() => setErrorMessage(null)}
onClear={() => { setErrorMessage(null); }}
/>
)}
</ActiveWorkspaceProvider>
Expand Down
2 changes: 1 addition & 1 deletion src/components/AboutModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function AboutModal({ isOpen, onOpenChange }: AboutModalProps) {
<Dialog.Root open={isOpen} onOpenChange={onOpenChange}>
<Dialog.Content
style={{ maxWidth: 440, padding: '24px', textAlign: 'center' }}
onOpenAutoFocus={(e) => e.preventDefault()}
onOpenAutoFocus={(e) => { e.preventDefault(); }}
>
<Flex direction="column" align="center" gap="2" mb="4" mt="2">
<img
Expand Down
4 changes: 1 addition & 3 deletions src/components/ConfirmDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AlertDialog, Button, Flex } from '@radix-ui/themes';

interface ConfirmDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
title?: string;
description: string;
Expand All @@ -12,7 +11,6 @@ interface ConfirmDialogProps {
}

export default function ConfirmDialog({
open,
onOpenChange,
title = 'Are you sure?',
description,
Expand All @@ -22,7 +20,7 @@ export default function ConfirmDialog({
onConfirm,
}: ConfirmDialogProps) {
return (
<AlertDialog.Root open={open} onOpenChange={onOpenChange}>
<AlertDialog.Root defaultOpen onOpenChange={onOpenChange}>
<AlertDialog.Content style={{ maxWidth: 400 }}>
<AlertDialog.Title>{title}</AlertDialog.Title>
<AlertDialog.Description size="2" mb="4">
Expand Down
2 changes: 1 addition & 1 deletion src/components/ConnectionOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function ConnectionOverlay() {
setShowOverlay(false);
}, 500);

return () => clearTimeout(timer);
return () => { clearTimeout(timer); };
}, [status]);

if (!showOverlay) return null;
Expand Down
14 changes: 7 additions & 7 deletions src/components/FieldsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function FieldsTab({ tp, onNavigateToType }: FieldsTabProps) {
<TextField.Root
placeholder="Search name or definition..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onChange={(e) => { setSearchQuery(e.target.value); }}
size="1"
m="1"
style={{ flexShrink: 0 }}
Expand All @@ -80,7 +80,7 @@ export default function FieldsTab({ tp, onNavigateToType }: FieldsTabProps) {
size="1"
variant="ghost"
color="gray"
onClick={() => setSearchQuery('')}
onClick={() => { setSearchQuery(''); }}
style={{ cursor: 'pointer', height: '16px', width: '16px' }}
>
<Cross2Icon height="12" width="12" />
Expand Down Expand Up @@ -124,10 +124,10 @@ export default function FieldsTab({ tp, onNavigateToType }: FieldsTabProps) {
} as React.CSSProperties}
>
{filtered.map(([name, definition]) => {
const relation: Relation | undefined = tp.relations?.[name];
const relation: Relation | undefined = tp.relations[name];

const isComplex = typeof definition !== 'string';
const isRowOpen = !!expandedFields[name];
const isRowOpen = expandedFields[name];

const stringifiedThisDef = getDefinitionString(definition);
const cardinality = relation ? determineCardinality(stringifiedThisDef, relation.definition) : null;
Expand All @@ -140,7 +140,7 @@ export default function FieldsTab({ tp, onNavigateToType }: FieldsTabProps) {
return (
<React.Fragment key={name}>
<DataList.Item
onClick={() => isComplex && toggleFieldExpand(name)}
onClick={() => { if (isComplex) toggleFieldExpand(name); }}
style={{
display: 'grid',
gridTemplateColumns: '180px 200px auto',
Expand Down Expand Up @@ -185,15 +185,15 @@ export default function FieldsTab({ tp, onNavigateToType }: FieldsTabProps) {

<DataList.Value style={{ display: 'flex', alignItems: 'center', minWidth: 0 }}>
{relation ? (
<Flex align="center" gap="2" style={{ width: '100%' }} onClick={(e) => e.stopPropagation()}>
<Flex align="center" gap="2" style={{ width: '100%' }} onClick={(e) => { e.stopPropagation(); }}>
<Badge size="1" color={cardinalityColor} variant="surface" style={{ fontVariantNumeric: 'tabular-nums', fontWeight: 'bold' }}>
{cardinality}
</Badge>

<Flex
align="center"
gap="1"
onClick={() => onNavigateToType(relation.type)}
onClick={() => { onNavigateToType(relation.type); }}
style={{
cursor: 'pointer',
padding: '2px 6px',
Expand Down
16 changes: 8 additions & 8 deletions src/components/MethodsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function MethodsTab({
}

return methodNames.filter((name) => {
const nameMatch = name?.toLowerCase().includes(cleanedQuery);
const nameMatch = name.toLowerCase().includes(cleanedQuery);

return nameMatch;
});
Expand All @@ -41,9 +41,9 @@ export default function MethodsTab({
useEffect(() => {
if (methodNames.length > 0) {
const name = methodNames[0];
queueMicrotask(() => setSelectedMethodName(name));
queueMicrotask(() => { setSelectedMethodName(name); });
} else {
queueMicrotask(() => setSelectedMethodName(null));
queueMicrotask(() => { setSelectedMethodName(null); });
}
}, [methodNames]);

Expand All @@ -58,7 +58,7 @@ export default function MethodsTab({
);
}

const activeMethod: Method | undefined = methods?.[selectedMethodName || ''];
const activeMethod: Method | undefined = methods?.[selectedMethodName ?? ''];

return (
<Flex gap="3" style={{ height: '100%', minHeight: 0 }}>
Expand All @@ -67,7 +67,7 @@ export default function MethodsTab({
<TextField.Root
placeholder="Search name..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onChange={(e) => { setSearchQuery(e.target.value); }}
size="1"
style={{ flexShrink: 0 }}
>
Expand All @@ -80,7 +80,7 @@ export default function MethodsTab({
size="1"
variant="ghost"
color="gray"
onClick={() => setSearchQuery('')}
onClick={() => { setSearchQuery(''); }}
style={{ cursor: 'pointer', height: '16px', width: '16px' }}
>
<Cross2Icon height="12" width="12" />
Expand Down Expand Up @@ -121,7 +121,7 @@ export default function MethodsTab({
return (
<Box
key={mName}
onClick={() => setSelectedMethodName(mName)}
onClick={() => { setSelectedMethodName(mName); }}
px="2"
py="1"
style={{
Expand Down Expand Up @@ -156,7 +156,7 @@ export default function MethodsTab({

<CodeIcon color="gray" />
<Text size="1" weight="bold" style={{ fontFamily: 'monospace' }}>
{selectedMethodName}({activeMethod.arguments?.join(', ') || ''})
{selectedMethodName}({activeMethod.arguments.join(', ') || ''})
</Text>
</Flex>

Expand Down
30 changes: 14 additions & 16 deletions src/components/NewWorkspaceModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ export default function NewWorkspaceModal() {
const [showToken, setShowToken] = useState(false);

const sanitizedName = name.replace(/[^a-zA-Z0-9-_ ]/g, '');
const workfolder = customWorkfolder !== null
? customWorkfolder
: `~/ThingsCode/${sanitizedName}`;
const workfolder = customWorkfolder ?? `~/ThingsCode/${sanitizedName}`;

const resetForm = () => {
setName('');
Expand All @@ -44,10 +42,10 @@ export default function NewWorkspaceModal() {
setWorkspaceType('development');
};

const handleSubmit = (e: React.ChangeEvent) => {
const handleSubmit = async (e: React.ChangeEvent) => {
e.preventDefault();

addWorkspace({
await addWorkspace({
name,
host,
port,
Expand Down Expand Up @@ -92,15 +90,15 @@ export default function NewWorkspaceModal() {
Add a node config profile and link it to a local workspace path.
</Dialog.Description>

<form onSubmit={handleSubmit}>
<form onSubmit={(e) => { void handleSubmit(e); }}>
<Flex direction="column" gap="4">
{/* Name Input */}
<label>
<Text as="div" size="2" weight="bold" mb="1">Workspace Name</Text>
<TextField.Root
placeholder="e.g. Production Node"
value={name}
onChange={(e) => setName(e.target.value)}
onChange={(e) => { setName(e.target.value); }}
required
/>
</label>
Expand All @@ -124,7 +122,7 @@ export default function NewWorkspaceModal() {
<Text size="1" color="gray">Controls a visual badge to warn you of the current context</Text>
<Select.Root
value={workspaceType}
onValueChange={(val) => setWorkspaceType(val as WorkspaceType)}
onValueChange={(val) => { setWorkspaceType(val as WorkspaceType); }}
>
<Select.Trigger style={{ width: '100%', cursor: 'pointer' }} />
<Select.Content>
Expand Down Expand Up @@ -156,14 +154,14 @@ export default function NewWorkspaceModal() {
<Flex gap="3">
<Box style={{ flexGrow: 1 }}>
<Text as="div" size="2" weight="bold" mb="1">Host / IP</Text>
<TextField.Root value={host} onChange={(e) => setHost(e.target.value)} required />
<TextField.Root value={host} onChange={(e) => { setHost(e.target.value); }} required />
</Box>
<Box style={{ width: 100 }}>
<Text as="div" size="2" weight="bold" mb="1">Port</Text>
<TextField.Root
type="number"
value={port}
onChange={(e) => setPort(parseInt(e.target.value) || 0)}
onChange={(e) => { setPort(parseInt(e.target.value) || 0); }}
required
/>
</Box>
Expand All @@ -185,7 +183,7 @@ export default function NewWorkspaceModal() {
<Text as="div" size="2" weight="bold" mb="2">Authentication Mode</Text>
<RadioGroup.Root
value={authType}
onValueChange={(value) => setAuthType(value as 'credentials' | 'token')}
onValueChange={(value) => { setAuthType(value as 'credentials' | 'token'); }}
size="2"
variant="surface"
>
Expand All @@ -209,15 +207,15 @@ export default function NewWorkspaceModal() {
<TextField.Root
type={showToken ? "text" : "password"}
value={token}
onChange={e => setToken(e.target.value)}
onChange={e => { setToken(e.target.value); }}
required
>
<TextField.Slot side="right" px="1">
<IconButton
type="button"
variant="ghost"
color="gray"
onClick={() => setShowToken(!showToken)}
onClick={() => { setShowToken(!showToken); }}
className="cursor-pointer"
>
{showToken ? <EyeNoneIcon width="16" height="16" /> : <EyeOpenIcon width="16" height="16" />}
Expand All @@ -229,21 +227,21 @@ export default function NewWorkspaceModal() {
<Flex gap="3">
<Box style={{ flexGrow: 1 }}>
<Text as="div" size="2" weight="bold" mb="1">Username</Text>
<TextField.Root value={username} onChange={e => setUsername(e.target.value)} />
<TextField.Root value={username} onChange={e => { setUsername(e.target.value); }} />
</Box>
<Box style={{ flexGrow: 1 }}>
<Text as="div" size="2" weight="bold" mb="1">Password</Text>
<TextField.Root
type={showPassword ? "text" : "password"}
value={password}
onChange={e => setPassword(e.target.value)}
onChange={e => { setPassword(e.target.value); }}
>
<TextField.Slot side="right" px="1">
<IconButton
type="button"
variant="ghost"
color="gray"
onClick={() => setShowPassword(!showPassword)}
onClick={() => { setShowPassword(!showPassword); }}
className="cursor-pointer"
>
{showPassword ? <EyeNoneIcon width="16" height="16" /> : <EyeOpenIcon width="16" height="16" />}
Expand Down
2 changes: 1 addition & 1 deletion src/components/NodeStatusBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function NodeStatusBadge() {
return null;
}

const color = nodeStatus ? STATUS_COLOR_MAP[nodeStatus.Status] || 'gray' : 'gray';
const color = STATUS_COLOR_MAP[nodeStatus.Status] ?? 'gray';

return (
<Flex align="center" px="1">
Expand Down
Loading