Compare commits

..
12 changed files with 43 additions and 30 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
{
"monorepoCommit": "4c88728f144add3457b4273d4b9a04ee53c53be3",
"monorepoCommit": "1227e3672a5a24b7331567fc3f431e422e1513c1",
"sourcePath": "quixos-instance/packages/project-react-runtime"
}
+1 -1
View File
@@ -12,7 +12,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370",
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=86933aa97f3ea386a4c5cfeb28386fd8d2722075",
"react": "^18.3.1"
},
"devDependencies": {
+1 -1
View File
@@ -1,4 +1,4 @@
query TaggedTasks($first: Int!, $after: Cursor, $statuses: [String!]!, $tags: [QxRef_TagData!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}, _qx: {relations: {tags: {some: {_qx: {ref: {in: $tags}}}}}}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title status priority dueDate repeatDays estimatedHours
query TaggedTasks($first: Int!, $after: Cursor, $statuses: [String!]!, $tags: [QxRef_TagData!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}, _qx: {relations: {tags: {some: {_qx: {ref: {in: $tags}}}}}}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title @live status priority dueDate repeatDays estimatedHours
tags(all: 100) {entries {node {_qx {ref} name color}}}
_qx {relations {completions {aggregate {count max {completedAt}}}}}
}} pageInfo {hasNextPage endCursor}}}}
+1 -1
View File
@@ -1,4 +1,4 @@
query Tasks($first: Int!, $after: Cursor, $statuses: [String!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title status priority dueDate repeatDays estimatedHours
query Tasks($first: Int!, $after: Cursor, $statuses: [String!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title @live status priority dueDate repeatDays estimatedHours
tags(all: 100) {entries {node {_qx {ref} name color}}}
_qx {relations {completions {aggregate {count max {completedAt}}}}}
}} pageInfo {hasNextPage endCursor}}}}
+1 -1
View File
@@ -1,4 +1,4 @@
query UntaggedTasks($first: Int!, $after: Cursor, $statuses: [String!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}, _qx: {relations: {tags: {none: {}}}}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title status priority dueDate repeatDays estimatedHours
query UntaggedTasks($first: Int!, $after: Cursor, $statuses: [String!]!) {root {tasks(first: $first, after: $after, where: {status: {in: $statuses}, _qx: {relations: {tags: {none: {}}}}}, orderBy: [{dueDate: ASC}, {title: ASC}]) {entries { key node {_qx {ref} title @live status priority dueDate repeatDays estimatedHours
tags(all: 100) {entries {node {_qx {ref} name color}}}
_qx {relations {completions {aggregate {count max {completedAt}}}}}
}} pageInfo {hasNextPage endCursor}}}}
+8 -8
View File
@@ -1,34 +1,34 @@
quixos-lock version 1 {
quixos source {
repository "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git";
commit "4c88728f144add3457b4273d4b9a04ee53c53be3";
commit "1227e3672a5a24b7331567fc3f431e422e1513c1";
}
interface Named source {
repository "https://repos.quixos.org/quixos-templates/interface-named.git";
commit "fbd8d695bcb49c7a2bd3394002bc828a75cdc11b";
commit "1aa05d6b5b953126adcaa85c4a5f17d444246273";
}
interface ProjectTasks source {
repository "https://repos.quixos.org/quixos-templates/interface-project-tasks.git";
commit "7cb6436aa1c2a455e4dc649ac3fe9d15de136360";
commit "0b4f9fecf2a367b207575bae6ec5114ea28f408a";
}
interface TagData source {
repository "https://repos.quixos.org/quixos-templates/interface-tag-data.git";
commit "944d1186ff82c2b00fe0db4fd839bbbfc66b0a72";
commit "353491e12fd5ef16f4253817dc48178043e7cc40";
}
interface CompletionData source {
repository "https://repos.quixos.org/quixos-templates/interface-completion-data.git";
commit "6af9cc41f203378dce92f14b716708ba053d30fc";
commit "79c5046dfe5d4172af77e39f19fb572afb7cf84c";
}
interface TaskData source {
repository "https://repos.quixos.org/quixos-templates/interface-task-data.git";
commit "73d0b65861ab7d4194e431a6a38e28a288687fe9";
commit "67adb8a9f8d3c13126ed503a4ddc1bcf1153aef5";
}
interface TaskActions source {
repository "https://repos.quixos.org/quixos-templates/interface-task-actions.git";
commit "75c1f0cc6d201d34adf5d75695f7bab687157500";
commit "a129c7a65aa4027d36a43f87c1f2e65afe066d1a";
}
interface ProjectActions source {
repository "https://repos.quixos.org/quixos-templates/interface-project-actions.git";
commit "a332fdb4014d3ef5df11886ed33588cd1f4b52af";
commit "2336dd32216641fb94361962d015008a82d0776f";
}
}
+3 -3
View File
@@ -12,7 +12,7 @@ export type QueryResults = { "Tasks": { "root": { "tasks": { "entries": Array<{
export const queries: { "Tasks": QxQueryDescriptor<QueryVariables["Tasks"], QueryResults["Tasks"], "interface:project-tasks@1">; "TaggedTasks": QxQueryDescriptor<QueryVariables["TaggedTasks"], QueryResults["TaggedTasks"], "interface:project-tasks@1">; "UntaggedTasks": QxQueryDescriptor<QueryVariables["UntaggedTasks"], QueryResults["UntaggedTasks"], "interface:project-tasks@1">; "Catalog": QxQueryDescriptor<QueryVariables["Catalog"], QueryResults["Catalog"], "interface:project-tasks@1">; "Summary": QxQueryDescriptor<QueryVariables["Summary"], QueryResults["Summary"], "interface:project-tasks@1"> } = {
"Tasks": {
"id": "package:project-react-runtime@1:query:Tasks",
"definitionDigest": "90fb955b4306497b7e779b659b52982cca7d5e5e9a640170b22b8b88beb55071",
"definitionDigest": "5a6297f95f2174c4401905fa9c8a0eb9095084bf1f0bf77023e0846ad61e0b44",
"rootInterfaceRevisionId": "interface:project-tasks@1",
"variables": {
"kind": "record",
@@ -194,7 +194,7 @@ export const queries: { "Tasks": QxQueryDescriptor<QueryVariables["Tasks"], Quer
},
"TaggedTasks": {
"id": "package:project-react-runtime@1:query:TaggedTasks",
"definitionDigest": "040521ef951ed94ddd7b74d2cc05bed6eec0095f30dcf5930a1e59585068abcd",
"definitionDigest": "0355f9312eb2d66854f0b2dda18b5e3735eb2ccae9471e9b782651b7879825cf",
"rootInterfaceRevisionId": "interface:project-tasks@1",
"variables": {
"kind": "record",
@@ -386,7 +386,7 @@ export const queries: { "Tasks": QxQueryDescriptor<QueryVariables["Tasks"], Quer
},
"UntaggedTasks": {
"id": "package:project-react-runtime@1:query:UntaggedTasks",
"definitionDigest": "e4efe0274b9cb1cd2ea1b32c986f71a8637fa2fb62f9a3c062cd8f08a391ff22",
"definitionDigest": "fff38746b238c721338f4e05b6d9b6678d265ab61ddeb9db81f1f52e43133902",
"rootInterfaceRevisionId": "interface:project-tasks@1",
"variables": {
"kind": "record",
File diff suppressed because one or more lines are too long
+12 -5
View File
@@ -3,6 +3,8 @@ declare module "@quixos/web-studio-react-runtime" {
import type * as React from "react";
export function useComponentOverlayContainer(): HTMLElement;
export function useComponentStyleRoot(): ShadowRoot;
/** Aggregate transport counters only; contains no object identities or values. */
export function getFieldTransportMetrics(): Partial<Record<"get" | "watch" | "register" | "crdt" | "setter", Readonly<{started: number; active: number; completed: number; failed: number; totalMs: number}>>>;
export type ObjectRef<AtomId extends string> = string & {
readonly $quixosAtom: AtomId;
};
@@ -20,8 +22,9 @@ declare module "@quixos/web-studio-react-runtime" {
export function useTryConform<View>(object: string | {readonly $quixosRef: string}, contract: ReactInterfaceContract<View>): ConformanceResult<View>;
export type QueryValueType = {kind: "builtin" | "scalar"; name: string} | {kind: "record"; fields: Record<string, QueryValueType>} | {kind: "optional" | "list"; value: QueryValueType} | {kind: "object-ref"; expectation: {kind: "atom"; atomId: string} | {kind: "interface"; interfaceRevisionId: string}};
export type QueryReference<Contract extends string = string> = {readonly $quixosRef: string; readonly queryContract: Contract};
export interface QueryDescriptor<Variables, Result> {readonly id: string; readonly definitionDigest: string; readonly rootInterfaceRevisionId: string; readonly variables: QueryValueType; readonly output: QueryValueType; readonly watch: boolean; readonly $types?: (variables: Variables, result: Result) => [Variables, Result]}
export type QueryPartial<T> = T extends QueryReference ? T : T extends readonly (infer Item)[] ? QueryPartial<Item>[] : T extends object ? {[Key in keyof T]?: QueryPartial<T[Key]>} : T;
export type QueryLiveProjection = {path: readonly string[]; selectionId: string; interfaceRevisionId: string; getOperationId: string; setOperationId?: string; watchOperationId?: string; inputKind: "fields" | "value"; valueType: QueryValueType; conditions: {include: boolean; defaultValue?: boolean; value: {kind: "variable"; name: string} | {kind: "literal"; value: unknown}}[]};
export interface QueryDescriptor<Variables, Result> {readonly id: string; readonly definitionDigest: string; readonly rootInterfaceRevisionId: string; readonly variables: QueryValueType; readonly output: QueryValueType; readonly watch: boolean; readonly liveFields?: readonly QueryLiveProjection[]; readonly $types?: (variables: Variables, result: Result) => [Variables, Result]}
export type QueryPartial<T> = T extends {readonly $quixosRef: string} | {readonly capability: {readonly getOperationId: string}} ? T : T extends readonly (infer Item)[] ? QueryPartial<Item>[] : T extends object ? {[Key in keyof T]?: QueryPartial<T[Key]>} : T;
export type QueryFieldState = {path: readonly (string | number)[]; status: "pending" | "error"; error?: string};
export type QueryState<T> = {refreshing: boolean; fields: QueryFieldState[]; runId?: string; sequence?: bigint; consistency?: string} & ({status: "loading"; data?: undefined; error?: undefined} | {status: "ready"; data: T; error?: undefined} | {status: "partial"; data: QueryPartial<T>; error?: undefined} | {status: "error"; data?: T | QueryPartial<T>; error: Error});
export function useQuery<Variables, Result>(descriptor: QueryDescriptor<Variables, Result>, options: {root: string | {readonly $quixosRef: string}; variables: Variables}): QueryState<Result> & {refresh(): void};
@@ -53,7 +56,11 @@ declare module "@quixos/web-studio-react-runtime" {
options?: {clientMutationId?: string; signal?: AbortSignal},
) => Promise<Result>;
export const h: typeof React.createElement;
export function useLiveField<T>(field: ReadableField<T>, options: {write: (value: T) => Promise<void>}): readonly [T, (value: T) => Promise<void>];
export function useLiveField<T>(field: WritableField<T>): readonly [T, (value: T) => Promise<void>];
export function useLiveField<T>(field: ReadableField<T>): readonly [T];
export type LiveFieldState<T> = {refreshing: boolean; stale: boolean; pendingWrites: number; writeError?: Error; refresh(): Promise<void>; discard(): void} & ({status: "loading"; value?: undefined; error?: undefined} | {status: "ready"; value: T; error?: Error} | {status: "error"; value?: undefined; error: Error});
export type WritableLiveFieldState<T> = LiveFieldState<T> & {set(value: T): Promise<void>; retry(): Promise<void>};
export function useLiveField<T>(field: ReadableField<T>, options: {id: string; write: (value: T) => Promise<void>}): WritableLiveFieldState<T>;
export function useLiveField<T>(field: WritableField<T>): WritableLiveFieldState<T>;
export function useLiveField<T>(field: ReadableField<T>): LiveFieldState<T>;
export function useSuspenseLiveField<T>(field: WritableField<T>): WritableLiveFieldState<T> & {status: "ready"; value: T};
export function useSuspenseLiveField<T>(field: ReadableField<T>): LiveFieldState<T> & {status: "ready"; value: T};
}
+8 -2
View File
@@ -31,6 +31,10 @@ type ListProps = {
next(cursor: string | null): void;
reset(): void;
};
function TaskTitle({ field }: { field: QueryResults["Tasks"]["root"]["tasks"]["entries"][number]["node"]["title"] }) {
const title = useLiveField(field);
return <strong>{title.value ?? "Loading…"}</strong>;
}
function Rows({ result, selected, select, next, reset }: ListProps & { result: QueryState<QueryResults["Tasks"]> }) {
if (result.status === "error")
return (
@@ -56,7 +60,7 @@ function Rows({ result, selected, select, next, reset }: ListProps & { result: Q
{task.status === "DONE" ? "✓" : task.status === "ARCHIVED" ? "—" : "○"}
</span>
<span className="tt-row-body">
<strong>{task.title}</strong>
<TaskTitle field={task.title} />
<span className="tt-row-meta">
{task.dueDate || "No due date"}
{task.repeatDays > 0 ? ` · Every ${task.repeatDays}d` : ""}
@@ -102,7 +106,9 @@ function TaggedRows(props: ListProps & { tags: Tag["_qx"]["ref"][] }) {
);
}
export default function ProjectComponent({ camino }: Props) {
const [name, setName] = useLiveField(camino.named.fields.name);
const nameField = useLiveField(camino.named.fields.name);
const name = nameField.value ?? "";
const setName = nameField.set;
const root = camino.tasks.$quixosRef;
const catalog = useQuery(queries.Catalog, { root, variables: {} });
const summary = useQuery(queries.Summary, { root, variables: {} });
+1 -1
View File
@@ -161,7 +161,7 @@ cacheEntries = {
"@connectrpc/connect@npm:2.1.2" = { filename = "@connectrpc-connect-npm-2.1.2-ab34825de3-4e15000890.zip"; hash = "sha512-ThUACJAjt1Lv1E+pQKWuHh+gDhvrxLoM7ScruTWSDYw7hbd0UOZErUQruMqaJ1sMFxNviWuo7/A2F4Ex2wHWFQ=="; };
"@esbuild/linux-arm64@npm:0.25.12" = { filename = "@esbuild-linux-arm64-npm-0.25.12-a5aaa0e70e-10c0.zip"; hash = "sha512-tm9zhnNR4GZv4A+Sgbt9jdCJ0iGlzvYxGCaxaScbhFH14mX7QWJRYaCvFCZB1dseApmaq6mNwbilL0wJnbB8tw=="; };
"@esbuild/linux-x64@npm:0.25.12" = { filename = "@esbuild-linux-x64-npm-0.25.12-07c7c22cce-10c0.zip"; hash = "sha512-U2QGT8ZIZN8q2WPSFDC32+sZGKgp49gvnHzIf/vKVR4xIzjcgBbjAIKI+FqfGBmGBWu8eCpS7lR9JDXdUHOFkw=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370" = { filename = "@quixos-camino-package-runtime-https-84d8fd5109-6d173f9220.zip"; hash = "sha512-bRc/kiD/ODsJqBNX4+RTqdsczILibHLhB+X8MckDCoK+j32c4Hszh87obb1Rwjb5o35aI0fzArQqCwK270zzlw=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=86933aa97f3ea386a4c5cfeb28386fd8d2722075" = { filename = "@quixos-camino-package-runtime-https-af3a6c1cce-afad508367.zip"; hash = "sha512-r61Qg2cI8jRSzUs4m5vOZl92VMkd/eQB0KedVjGLAkpnhg5dt1FAVptjUOcs746empJUj/HEIau5rq0a+hyRhA=="; };
"@types/node@npm:24.13.3" = { filename = "@types-node-npm-24.13.3-b512a0bbeb-a5bc08f49b.zip"; hash = "sha512-pbwI9JuVgdzcqQ4CzXcZejx5mECAdmSULlzVFhpVPU0q6AZPfjKUQQ10jX0Ji1wYSL5/pQwG8pxBk6sWvk5Z6w=="; };
"@types/prop-types@npm:15.7.15" = { filename = "@types-prop-types-npm-15.7.15-cefe16a1fa-b59aad1ad1.zip"; hash = "sha512-tZqtGtGb8XM89ST9TmGBlsbHaQ9I7nCjJ+tFCkKquOigY/vlnKClcBrr4tktWCKSwPuEXqV0dPahX2mUsOJgsg=="; };
"@types/react@npm:18.3.31" = { filename = "@types-react-npm-18.3.31-d376eb19a5-44180549dd.zip"; hash = "sha512-RBgFSd0EX1Nuzs0545qs34KOdq3BxKkLEy9FPiPMNwxGSNkQKuQBFy69j9ixl3qQGjniFOU+x3FxsnUUtYjBeQ=="; };
+4 -4
View File
@@ -213,14 +213,14 @@ __metadata:
languageName: node
linkType: hard
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370":
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=86933aa97f3ea386a4c5cfeb28386fd8d2722075":
version: 0.1.0
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370"
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=86933aa97f3ea386a4c5cfeb28386fd8d2722075"
dependencies:
"@bufbuild/protobuf": "npm:^2.12.1"
"@connectrpc/connect": "npm:^2.1.2"
"@connectrpc/connect-node": "npm:^2.1.2"
checksum: 10c0/6d173f9220ff383b09a81357e3e453a9db1ccc82e26c72e107e5fc31c9030a82be8f7d9ce07b3387cee86dbd51c236f9a37e5a2347f302b42a0b02b6ef4cf397
checksum: 10c0/afad50836708f23452cd4b389b9bce665f7654c91dfde401d0a79d56318b024a67860e5db75140569b6350e72cef8e9e9a92548ff1c421abb9aead1afa1c9184
languageName: node
linkType: hard
@@ -228,7 +228,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@quixos/project-react-runtime@workspace:."
dependencies:
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=86933aa97f3ea386a4c5cfeb28386fd8d2722075"
"@types/node": "npm:^24"
"@types/react": "npm:^18.3.12"
esbuild: "npm:^0.25.12"