openuispec 0.1.27 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -19
- package/cli/init.ts +7 -7
- package/docs/implementation-notes.md +5 -1
- package/docs/release-notes-v0.1.28.md +25 -0
- package/docs/stress-test-maturity-report.md +1 -1
- package/drift/index.ts +21 -4
- package/examples/taskflow/AGENTS.md +112 -0
- package/examples/taskflow/CLAUDE.md +112 -0
- package/examples/taskflow/generated/android/TaskFlow/README.md +43 -0
- package/examples/taskflow/generated/android/TaskFlow/app/build.gradle.kts +76 -0
- package/examples/taskflow/generated/android/TaskFlow/app/proguard-rules.pro +1 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/AndroidManifest.xml +21 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/MainActivity.kt +19 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/TaskFlowApp.kt +283 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/DomainModels.kt +106 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/model/SampleData.kt +57 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/components/Common.kt +109 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/HomeScreen.kt +112 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/ProjectsScreen.kt +61 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/SettingsScreen.kt +82 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/screens/TaskDetailScreen.kt +111 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/sheets/Sheets.kt +77 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Color.kt +30 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Theme.kt +86 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/java/uz/rsteam/taskflow/ui/theme/Type.kt +57 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/strings.xml +155 -0
- package/examples/taskflow/generated/android/TaskFlow/app/src/main/res/values/themes.xml +4 -0
- package/examples/taskflow/generated/android/TaskFlow/build.gradle.kts +5 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/gradle-daemon-jvm.properties +12 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/examples/taskflow/generated/android/TaskFlow/gradle.properties +4 -0
- package/examples/taskflow/generated/android/TaskFlow/gradlew +18 -0
- package/examples/taskflow/generated/android/TaskFlow/gradlew.bat +12 -0
- package/examples/taskflow/generated/android/TaskFlow/settings.gradle.kts +18 -0
- package/examples/taskflow/generated/ios/TaskFlow/README.md +21 -0
- package/examples/taskflow/generated/ios/TaskFlow/Resources/en.lproj/Localizable.strings +115 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/App/TaskFlowApp.swift +24 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Components/AppChrome.swift +150 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Flows/TaskEditorSheet.swift +220 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Models/DomainModels.swift +122 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/CalendarView.swift +21 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/HomeView.swift +201 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProfileEditView.swift +48 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectDetailView.swift +59 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/ProjectsView.swift +63 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/SettingsView.swift +85 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Screens/TaskDetailView.swift +219 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppModel.swift +320 -0
- package/examples/taskflow/generated/ios/TaskFlow/Sources/TaskFlow/Support/AppSupport.swift +41 -0
- package/examples/taskflow/generated/ios/TaskFlow/project.yml +26 -0
- package/examples/taskflow/generated/web/TaskFlow/README.md +19 -0
- package/examples/taskflow/generated/web/TaskFlow/index.html +12 -0
- package/examples/taskflow/generated/web/TaskFlow/package-lock.json +1908 -0
- package/examples/taskflow/generated/web/TaskFlow/package.json +24 -0
- package/examples/taskflow/generated/web/TaskFlow/src/App.tsx +58 -0
- package/examples/taskflow/generated/web/TaskFlow/src/AppShell.tsx +55 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Common.tsx +82 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Modals.tsx +191 -0
- package/examples/taskflow/generated/web/TaskFlow/src/components/Nav.tsx +41 -0
- package/examples/taskflow/generated/web/TaskFlow/src/generated/messages.ts +131 -0
- package/examples/taskflow/generated/web/TaskFlow/src/hooks.ts +25 -0
- package/examples/taskflow/generated/web/TaskFlow/src/i18n.ts +39 -0
- package/examples/taskflow/generated/web/TaskFlow/src/locales.en.json +111 -0
- package/examples/taskflow/generated/web/TaskFlow/src/main.tsx +13 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/HomeScreen.tsx +111 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/ProjectsScreen.tsx +82 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/SettingsScreens.tsx +132 -0
- package/examples/taskflow/generated/web/TaskFlow/src/screens/TaskDetail.tsx +105 -0
- package/examples/taskflow/generated/web/TaskFlow/src/store.ts +216 -0
- package/examples/taskflow/generated/web/TaskFlow/src/styles.css +617 -0
- package/examples/taskflow/generated/web/TaskFlow/src/types.ts +64 -0
- package/examples/taskflow/generated/web/TaskFlow/src/utils.ts +78 -0
- package/examples/taskflow/generated/web/TaskFlow/tsconfig.json +21 -0
- package/examples/taskflow/generated/web/TaskFlow/vite.config.ts +6 -0
- package/examples/taskflow/openuispec/README.md +49 -0
- package/examples/todo-orbit/AGENTS.md +44 -19
- package/examples/todo-orbit/CLAUDE.md +44 -19
- package/examples/todo-orbit/openuispec/README.md +2 -2
- package/package.json +1 -1
- package/schema/validate.ts +9 -4
- package/status/index.ts +16 -3
- /package/examples/taskflow/{contracts → openuispec/contracts}/README.md +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/action_trigger.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/collection.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/data_display.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/feedback.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/input_field.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/nav_container.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/surface.yaml +0 -0
- /package/examples/taskflow/{contracts → openuispec/contracts}/x_media_player.yaml +0 -0
- /package/examples/taskflow/{flows → openuispec/flows}/create_task.yaml +0 -0
- /package/examples/taskflow/{flows → openuispec/flows}/edit_task.yaml +0 -0
- /package/examples/taskflow/{locales → openuispec/locales}/en.json +0 -0
- /package/examples/taskflow/{openuispec.yaml → openuispec/openuispec.yaml} +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/android.yaml +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/ios.yaml +0 -0
- /package/examples/taskflow/{platform → openuispec/platform}/web.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/calendar.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/home.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/profile_edit.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/project_detail.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/projects.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/settings.yaml +0 -0
- /package/examples/taskflow/{screens → openuispec/screens}/task_detail.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/color.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/elevation.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/icons.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/layout.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/motion.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/spacing.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/themes.yaml +0 -0
- /package/examples/taskflow/{tokens → openuispec/tokens}/typography.yaml +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
import type { Preferences, Project, ProjectDraft, Task, TaskDraft, User } from "./types";
|
|
3
|
+
import { addDays, daysAgo, parseTags } from "./utils";
|
|
4
|
+
|
|
5
|
+
type AppState = {
|
|
6
|
+
user: User;
|
|
7
|
+
users: User[];
|
|
8
|
+
preferences: Preferences;
|
|
9
|
+
projects: Project[];
|
|
10
|
+
tasks: Task[];
|
|
11
|
+
searchQuery: string;
|
|
12
|
+
activeFilter: "all" | "today" | "upcoming" | "done";
|
|
13
|
+
selectedTaskId?: string;
|
|
14
|
+
setSearchQuery: (value: string) => void;
|
|
15
|
+
setActiveFilter: (value: "all" | "today" | "upcoming" | "done") => void;
|
|
16
|
+
setSelectedTaskId: (value?: string) => void;
|
|
17
|
+
setTheme: (value: Preferences["theme"]) => void;
|
|
18
|
+
updatePreferences: (patch: Partial<Preferences>) => void;
|
|
19
|
+
updateProfile: (patch: Pick<User, "name" | "email">) => void;
|
|
20
|
+
createTask: (draft: TaskDraft) => Task;
|
|
21
|
+
updateTask: (taskId: string, draft: TaskDraft) => void;
|
|
22
|
+
toggleTask: (taskId: string) => void;
|
|
23
|
+
deleteTask: (taskId: string) => void;
|
|
24
|
+
assignTask: (taskId: string, userId: string) => void;
|
|
25
|
+
createProject: (draft: ProjectDraft) => void;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const sampleUser: User = {
|
|
29
|
+
id: "user-1",
|
|
30
|
+
name: "Maya Hart",
|
|
31
|
+
firstName: "Maya",
|
|
32
|
+
email: "maya@taskflow.app"
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const teamUsers: User[] = [
|
|
36
|
+
sampleUser,
|
|
37
|
+
{ id: "user-2", name: "Luca Park", firstName: "Luca", email: "luca@taskflow.app" },
|
|
38
|
+
{ id: "user-3", name: "Noah Singh", firstName: "Noah", email: "noah@taskflow.app" }
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const sampleProjects: Project[] = [
|
|
42
|
+
{ id: "proj-1", name: "Product Launch", color: "#5B4FE8", icon: "rocket", taskCount: 3 },
|
|
43
|
+
{ id: "proj-2", name: "Ops Cleanup", color: "#E8634F", icon: "briefcase", taskCount: 2 },
|
|
44
|
+
{ id: "proj-3", name: "Brand Refresh", color: "#2D9D5E", icon: "star", taskCount: 1 }
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const sampleTasks: Task[] = [
|
|
48
|
+
{
|
|
49
|
+
id: "task-1",
|
|
50
|
+
title: "Ship onboarding copy review",
|
|
51
|
+
description: "Review the final onboarding text with product and legal before release.",
|
|
52
|
+
status: "in_progress",
|
|
53
|
+
priority: "high",
|
|
54
|
+
dueDate: addDays(0),
|
|
55
|
+
projectId: "proj-1",
|
|
56
|
+
tags: ["launch", "copy"],
|
|
57
|
+
createdAt: daysAgo(3),
|
|
58
|
+
updatedAt: daysAgo(0),
|
|
59
|
+
assignee: teamUsers[1],
|
|
60
|
+
attachment: {
|
|
61
|
+
source: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
|
62
|
+
mediaType: "video",
|
|
63
|
+
title: "Launch teaser draft"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "task-2",
|
|
68
|
+
title: "Audit due-date reminder logic",
|
|
69
|
+
description: "Check notification timing against the reminder preference spec.",
|
|
70
|
+
status: "todo",
|
|
71
|
+
priority: "urgent",
|
|
72
|
+
dueDate: addDays(2),
|
|
73
|
+
projectId: "proj-2",
|
|
74
|
+
tags: ["notifications", "qa"],
|
|
75
|
+
createdAt: daysAgo(2),
|
|
76
|
+
updatedAt: daysAgo(1)
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "task-3",
|
|
80
|
+
title: "Warm theme polish pass",
|
|
81
|
+
description: "Tune the warm theme tinting against the token ranges.",
|
|
82
|
+
status: "done",
|
|
83
|
+
priority: "medium",
|
|
84
|
+
dueDate: daysAgo(1),
|
|
85
|
+
projectId: "proj-3",
|
|
86
|
+
tags: ["design"],
|
|
87
|
+
createdAt: daysAgo(6),
|
|
88
|
+
updatedAt: daysAgo(1),
|
|
89
|
+
assignee: teamUsers[2]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "task-4",
|
|
93
|
+
title: "Prepare project import CSV",
|
|
94
|
+
description: "Gather migration rows for the first customer workspace.",
|
|
95
|
+
status: "todo",
|
|
96
|
+
priority: "low",
|
|
97
|
+
dueDate: addDays(4),
|
|
98
|
+
projectId: "proj-2",
|
|
99
|
+
tags: ["ops", "data"],
|
|
100
|
+
createdAt: daysAgo(1),
|
|
101
|
+
updatedAt: daysAgo(1),
|
|
102
|
+
assignee: sampleUser
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
export const useAppStore = create<AppState>((set, get) => ({
|
|
107
|
+
user: sampleUser,
|
|
108
|
+
users: teamUsers,
|
|
109
|
+
preferences: {
|
|
110
|
+
theme: "system",
|
|
111
|
+
defaultPriority: "medium",
|
|
112
|
+
notificationsEnabled: true,
|
|
113
|
+
remindersEnabled: true
|
|
114
|
+
},
|
|
115
|
+
projects: sampleProjects,
|
|
116
|
+
tasks: sampleTasks,
|
|
117
|
+
searchQuery: "",
|
|
118
|
+
activeFilter: "today",
|
|
119
|
+
selectedTaskId: sampleTasks[0]?.id,
|
|
120
|
+
setSearchQuery: (value) => set({ searchQuery: value }),
|
|
121
|
+
setActiveFilter: (value) => set({ activeFilter: value }),
|
|
122
|
+
setSelectedTaskId: (value) => set({ selectedTaskId: value }),
|
|
123
|
+
setTheme: (value) => set((state) => ({ preferences: { ...state.preferences, theme: value } })),
|
|
124
|
+
updatePreferences: (patch) => set((state) => ({ preferences: { ...state.preferences, ...patch } })),
|
|
125
|
+
updateProfile: (patch) =>
|
|
126
|
+
set((state) => ({
|
|
127
|
+
user: {
|
|
128
|
+
...state.user,
|
|
129
|
+
...patch,
|
|
130
|
+
firstName: patch.name ? patch.name.split(" ")[0] ?? patch.name : state.user.firstName
|
|
131
|
+
}
|
|
132
|
+
})),
|
|
133
|
+
createTask: (draft) => {
|
|
134
|
+
const created: Task = {
|
|
135
|
+
id: `task-${Date.now()}`,
|
|
136
|
+
title: draft.title,
|
|
137
|
+
description: draft.description || undefined,
|
|
138
|
+
status: "todo",
|
|
139
|
+
priority: draft.priority,
|
|
140
|
+
dueDate: draft.dueDate || undefined,
|
|
141
|
+
projectId: draft.projectId || undefined,
|
|
142
|
+
tags: parseTags(draft.tags),
|
|
143
|
+
createdAt: new Date().toISOString(),
|
|
144
|
+
updatedAt: new Date().toISOString(),
|
|
145
|
+
assignee: draft.assignToSelf ? get().user : undefined
|
|
146
|
+
};
|
|
147
|
+
set((state) => ({ tasks: [created, ...state.tasks], selectedTaskId: created.id }));
|
|
148
|
+
syncProjectCounts(set, get);
|
|
149
|
+
return created;
|
|
150
|
+
},
|
|
151
|
+
updateTask: (taskId, draft) => {
|
|
152
|
+
set((state) => ({
|
|
153
|
+
tasks: state.tasks.map((task) =>
|
|
154
|
+
task.id === taskId
|
|
155
|
+
? {
|
|
156
|
+
...task,
|
|
157
|
+
title: draft.title,
|
|
158
|
+
description: draft.description || undefined,
|
|
159
|
+
priority: draft.priority,
|
|
160
|
+
dueDate: draft.dueDate || undefined,
|
|
161
|
+
projectId: draft.projectId || undefined,
|
|
162
|
+
tags: parseTags(draft.tags),
|
|
163
|
+
assignee: draft.assignToSelf ? state.user : task.assignee,
|
|
164
|
+
updatedAt: new Date().toISOString()
|
|
165
|
+
}
|
|
166
|
+
: task
|
|
167
|
+
)
|
|
168
|
+
}));
|
|
169
|
+
syncProjectCounts(set, get);
|
|
170
|
+
},
|
|
171
|
+
toggleTask: (taskId) => {
|
|
172
|
+
set((state) => ({
|
|
173
|
+
tasks: state.tasks.map((task) =>
|
|
174
|
+
task.id === taskId
|
|
175
|
+
? { ...task, status: task.status === "done" ? "todo" : "done", updatedAt: new Date().toISOString() }
|
|
176
|
+
: task
|
|
177
|
+
)
|
|
178
|
+
}));
|
|
179
|
+
},
|
|
180
|
+
deleteTask: (taskId) => {
|
|
181
|
+
set((state) => ({
|
|
182
|
+
tasks: state.tasks.filter((task) => task.id !== taskId),
|
|
183
|
+
selectedTaskId:
|
|
184
|
+
state.selectedTaskId === taskId ? state.tasks.find((task) => task.id !== taskId)?.id : state.selectedTaskId
|
|
185
|
+
}));
|
|
186
|
+
syncProjectCounts(set, get);
|
|
187
|
+
},
|
|
188
|
+
assignTask: (taskId, userId) => {
|
|
189
|
+
set((state) => ({
|
|
190
|
+
tasks: state.tasks.map((task) =>
|
|
191
|
+
task.id === taskId ? { ...task, assignee: state.users.find((user) => user.id === userId) } : task
|
|
192
|
+
)
|
|
193
|
+
}));
|
|
194
|
+
},
|
|
195
|
+
createProject: (draft) => {
|
|
196
|
+
set((state) => ({
|
|
197
|
+
projects: [
|
|
198
|
+
...state.projects,
|
|
199
|
+
{ id: `proj-${Date.now()}`, name: draft.name, color: draft.color, icon: draft.icon, taskCount: 0 }
|
|
200
|
+
]
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
}));
|
|
204
|
+
|
|
205
|
+
function syncProjectCounts(
|
|
206
|
+
set: (partial: Partial<AppState> | ((state: AppState) => Partial<AppState>)) => void,
|
|
207
|
+
get: () => AppState
|
|
208
|
+
) {
|
|
209
|
+
const tasks = get().tasks;
|
|
210
|
+
set((state) => ({
|
|
211
|
+
projects: state.projects.map((project) => ({
|
|
212
|
+
...project,
|
|
213
|
+
taskCount: tasks.filter((task) => task.projectId === project.id).length
|
|
214
|
+
}))
|
|
215
|
+
}));
|
|
216
|
+
}
|