Skip to content

Commit 7de53f3

Browse files
committed
clockify init
1 parent 84d6fdc commit 7de53f3

22 files changed

+1979
-6
lines changed

apps/sim/blocks/blocks/clockify.ts

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
import { ClockifyIcon } from '@/components/icons'
2+
import type { BlockConfig } from '@/blocks/types'
3+
import { AuthMode } from '@/blocks/types'
4+
5+
export const ClockifyBlock: BlockConfig = {
6+
type: 'clockify',
7+
name: 'Clockify',
8+
description: 'Access Clockify workspaces, users, projects, and member profiles',
9+
authMode: AuthMode.ApiKey,
10+
longDescription:
11+
'Integrate Clockify into your workflow. Retrieve workspace details, team members, projects, and member profiles for time tracking management.',
12+
category: 'tools',
13+
icon: ClockifyIcon,
14+
bgColor: '#03A9F4',
15+
subBlocks: [
16+
{
17+
id: 'operation',
18+
title: 'Operation',
19+
type: 'dropdown',
20+
options: [
21+
{ label: 'Get Current User', id: 'clockify_get_current_user' },
22+
{ label: 'Get Workspaces', id: 'clockify_get_workspaces' },
23+
{ label: 'Get Workspace Users', id: 'clockify_get_users' },
24+
{ label: 'Get Member Profile', id: 'clockify_get_member_profile' },
25+
{ label: 'Get Projects', id: 'clockify_get_projects' },
26+
],
27+
value: () => 'clockify_get_current_user',
28+
},
29+
{
30+
id: 'apiKey',
31+
title: 'API Key',
32+
type: 'short-input',
33+
placeholder: 'Enter your Clockify API key',
34+
password: true,
35+
required: true,
36+
},
37+
{
38+
id: 'workspaceId',
39+
title: 'Workspace ID',
40+
type: 'short-input',
41+
placeholder: 'Enter workspace ID',
42+
required: true,
43+
condition: {
44+
field: 'operation',
45+
value: ['clockify_get_current_user', 'clockify_get_workspaces'],
46+
not: true,
47+
},
48+
},
49+
{
50+
id: 'userId',
51+
title: 'User ID',
52+
type: 'short-input',
53+
placeholder: 'Enter user ID',
54+
required: true,
55+
condition: {
56+
field: 'operation',
57+
value: 'clockify_get_member_profile',
58+
},
59+
},
60+
],
61+
tools: {
62+
access: [
63+
'clockify_get_current_user',
64+
'clockify_get_workspaces',
65+
'clockify_get_users',
66+
'clockify_get_member_profile',
67+
'clockify_get_projects',
68+
],
69+
config: {
70+
tool: (params) => params.operation || 'clockify_get_current_user',
71+
params: (params) => {
72+
const baseParams: Record<string, unknown> = {
73+
apiKey: params.apiKey,
74+
}
75+
76+
switch (params.operation) {
77+
case 'clockify_get_current_user':
78+
case 'clockify_get_workspaces':
79+
return baseParams
80+
81+
case 'clockify_get_users':
82+
case 'clockify_get_projects':
83+
return {
84+
...baseParams,
85+
workspaceId: params.workspaceId,
86+
}
87+
88+
case 'clockify_get_member_profile':
89+
return {
90+
...baseParams,
91+
workspaceId: params.workspaceId,
92+
userId: params.userId,
93+
}
94+
95+
default:
96+
return baseParams
97+
}
98+
},
99+
},
100+
},
101+
inputs: {
102+
operation: { type: 'string', description: 'Operation to perform' },
103+
apiKey: { type: 'string', description: 'Clockify API key' },
104+
workspaceId: { type: 'string', description: 'Workspace ID' },
105+
userId: { type: 'string', description: 'User ID' },
106+
},
107+
outputs: {
108+
response: { type: 'json', description: 'API response data' },
109+
},
110+
}
111+
112+
export const ClockifyReportsBlock: BlockConfig = {
113+
type: 'clockify_reports',
114+
name: 'Clockify Reports',
115+
description: 'Generate Clockify time tracking reports',
116+
authMode: AuthMode.ApiKey,
117+
longDescription:
118+
'Generate summary, detailed, weekly, and attendance reports from Clockify. Filter by date range, users, and projects for comprehensive time tracking analysis.',
119+
category: 'tools',
120+
icon: ClockifyIcon,
121+
bgColor: '#03A9F4',
122+
subBlocks: [
123+
{
124+
id: 'operation',
125+
title: 'Report Type',
126+
type: 'dropdown',
127+
options: [
128+
{ label: 'Summary Report', id: 'clockify_report_summary' },
129+
{ label: 'Detailed Report', id: 'clockify_report_detailed' },
130+
{ label: 'Weekly Report', id: 'clockify_report_weekly' },
131+
{ label: 'Attendance Report', id: 'clockify_report_attendance' },
132+
],
133+
value: () => 'clockify_report_summary',
134+
},
135+
{
136+
id: 'apiKey',
137+
title: 'API Key',
138+
type: 'short-input',
139+
placeholder: 'Enter your Clockify API key',
140+
password: true,
141+
required: true,
142+
},
143+
{
144+
id: 'workspaceId',
145+
title: 'Workspace ID',
146+
type: 'short-input',
147+
placeholder: 'Enter workspace ID',
148+
required: true,
149+
},
150+
{
151+
id: 'dateRangeStart',
152+
title: 'Start Date',
153+
type: 'short-input',
154+
placeholder: 'ISO8601 (e.g., 2024-01-01T00:00:00Z)',
155+
required: true,
156+
},
157+
{
158+
id: 'dateRangeEnd',
159+
title: 'End Date',
160+
type: 'short-input',
161+
placeholder: 'ISO8601 (e.g., 2024-01-31T23:59:59Z)',
162+
required: true,
163+
},
164+
{
165+
id: 'userIds',
166+
title: 'User IDs',
167+
type: 'short-input',
168+
placeholder: 'Comma-separated user IDs (optional)',
169+
},
170+
{
171+
id: 'projectIds',
172+
title: 'Project IDs',
173+
type: 'short-input',
174+
placeholder: 'Comma-separated project IDs (optional)',
175+
},
176+
],
177+
tools: {
178+
access: [
179+
'clockify_report_summary',
180+
'clockify_report_detailed',
181+
'clockify_report_weekly',
182+
'clockify_report_attendance',
183+
],
184+
config: {
185+
tool: (params) => params.operation || 'clockify_report_summary',
186+
params: (params) => ({
187+
apiKey: params.apiKey,
188+
workspaceId: params.workspaceId,
189+
dateRangeStart: params.dateRangeStart,
190+
dateRangeEnd: params.dateRangeEnd,
191+
userIds: params.userIds || undefined,
192+
projectIds: params.projectIds || undefined,
193+
}),
194+
},
195+
},
196+
inputs: {
197+
operation: { type: 'string', description: 'Report type to generate' },
198+
apiKey: { type: 'string', description: 'Clockify API key' },
199+
workspaceId: { type: 'string', description: 'Workspace ID' },
200+
dateRangeStart: { type: 'string', description: 'Start date in ISO8601 format' },
201+
dateRangeEnd: { type: 'string', description: 'End date in ISO8601 format' },
202+
userIds: { type: 'string', description: 'Comma-separated user IDs to filter' },
203+
projectIds: { type: 'string', description: 'Comma-separated project IDs to filter' },
204+
},
205+
outputs: {
206+
response: { type: 'json', description: 'Report data' },
207+
},
208+
}
209+
210+
export const ClockifyTimeBlock: BlockConfig = {
211+
type: 'clockify_time',
212+
name: 'Clockify Time',
213+
description: 'Access Clockify time entries, timers, time off, and holidays',
214+
authMode: AuthMode.ApiKey,
215+
longDescription:
216+
'Retrieve time entries, in-progress timers, time off requests, and holidays from Clockify for detailed time tracking and absence management.',
217+
category: 'tools',
218+
icon: ClockifyIcon,
219+
bgColor: '#03A9F4',
220+
subBlocks: [
221+
{
222+
id: 'operation',
223+
title: 'Operation',
224+
type: 'dropdown',
225+
options: [
226+
{ label: 'Get Time Entries', id: 'clockify_get_time_entries' },
227+
{ label: 'Get Time Entry', id: 'clockify_get_time_entry' },
228+
{ label: 'In-Progress Timers', id: 'clockify_get_in_progress' },
229+
{ label: 'Time Off Requests', id: 'clockify_get_time_off' },
230+
{ label: 'Holidays', id: 'clockify_get_holidays' },
231+
],
232+
value: () => 'clockify_get_time_entries',
233+
},
234+
{
235+
id: 'apiKey',
236+
title: 'API Key',
237+
type: 'short-input',
238+
placeholder: 'Enter your Clockify API key',
239+
password: true,
240+
required: true,
241+
},
242+
{
243+
id: 'workspaceId',
244+
title: 'Workspace ID',
245+
type: 'short-input',
246+
placeholder: 'Enter workspace ID',
247+
required: true,
248+
},
249+
{
250+
id: 'userId',
251+
title: 'User ID',
252+
type: 'short-input',
253+
placeholder: 'Enter user ID',
254+
required: true,
255+
condition: {
256+
field: 'operation',
257+
value: 'clockify_get_time_entries',
258+
},
259+
},
260+
{
261+
id: 'timeEntryId',
262+
title: 'Time Entry ID',
263+
type: 'short-input',
264+
placeholder: 'Enter time entry ID',
265+
required: true,
266+
condition: {
267+
field: 'operation',
268+
value: 'clockify_get_time_entry',
269+
},
270+
},
271+
{
272+
id: 'start',
273+
title: 'Start Date',
274+
type: 'short-input',
275+
placeholder: 'ISO8601 (e.g., 2024-01-01T00:00:00Z)',
276+
condition: {
277+
field: 'operation',
278+
value: ['clockify_get_time_entries', 'clockify_get_time_off', 'clockify_get_holidays'],
279+
},
280+
},
281+
{
282+
id: 'end',
283+
title: 'End Date',
284+
type: 'short-input',
285+
placeholder: 'ISO8601 (e.g., 2024-01-31T23:59:59Z)',
286+
condition: {
287+
field: 'operation',
288+
value: ['clockify_get_time_entries', 'clockify_get_time_off', 'clockify_get_holidays'],
289+
},
290+
},
291+
],
292+
tools: {
293+
access: [
294+
'clockify_get_time_entries',
295+
'clockify_get_time_entry',
296+
'clockify_get_in_progress',
297+
'clockify_get_time_off',
298+
'clockify_get_holidays',
299+
],
300+
config: {
301+
tool: (params) => params.operation || 'clockify_get_time_entries',
302+
params: (params) => {
303+
const baseParams: Record<string, unknown> = {
304+
apiKey: params.apiKey,
305+
workspaceId: params.workspaceId,
306+
}
307+
308+
switch (params.operation) {
309+
case 'clockify_get_time_entries':
310+
return {
311+
...baseParams,
312+
userId: params.userId,
313+
start: params.start || undefined,
314+
end: params.end || undefined,
315+
}
316+
317+
case 'clockify_get_time_entry':
318+
return {
319+
...baseParams,
320+
timeEntryId: params.timeEntryId,
321+
}
322+
323+
case 'clockify_get_in_progress':
324+
return baseParams
325+
326+
case 'clockify_get_time_off':
327+
return {
328+
...baseParams,
329+
start: params.start || undefined,
330+
end: params.end || undefined,
331+
}
332+
333+
case 'clockify_get_holidays':
334+
return {
335+
...baseParams,
336+
start: params.start || undefined,
337+
end: params.end || undefined,
338+
}
339+
340+
default:
341+
return baseParams
342+
}
343+
},
344+
},
345+
},
346+
inputs: {
347+
operation: { type: 'string', description: 'Operation to perform' },
348+
apiKey: { type: 'string', description: 'Clockify API key' },
349+
workspaceId: { type: 'string', description: 'Workspace ID' },
350+
userId: { type: 'string', description: 'User ID' },
351+
timeEntryId: { type: 'string', description: 'Time entry ID' },
352+
start: { type: 'string', description: 'Start date in ISO8601 format' },
353+
end: { type: 'string', description: 'End date in ISO8601 format' },
354+
},
355+
outputs: {
356+
response: { type: 'json', description: 'API response data' },
357+
},
358+
}

apps/sim/blocks/registry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger'
2121
import { CirclebackBlock } from '@/blocks/blocks/circleback'
2222
import { ClayBlock } from '@/blocks/blocks/clay'
2323
import { ClerkBlock } from '@/blocks/blocks/clerk'
24+
import { ClockifyBlock, ClockifyReportsBlock, ClockifyTimeBlock } from '@/blocks/blocks/clockify'
2425
import { CloudflareBlock } from '@/blocks/blocks/cloudflare'
2526
import { ConditionBlock } from '@/blocks/blocks/condition'
2627
import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence'
@@ -223,6 +224,9 @@ export const registry: Record<string, BlockConfig> = {
223224
cloudflare: CloudflareBlock,
224225
clay: ClayBlock,
225226
clerk: ClerkBlock,
227+
clockify: ClockifyBlock,
228+
clockify_reports: ClockifyReportsBlock,
229+
clockify_time: ClockifyTimeBlock,
226230
condition: ConditionBlock,
227231
confluence: ConfluenceBlock,
228232
confluence_v2: ConfluenceV2Block,

apps/sim/components/icons.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,17 @@ export function ClayIcon(props: SVGProps<SVGSVGElement>) {
23162316
)
23172317
}
23182318

2319+
export function ClockifyIcon(props: SVGProps<SVGSVGElement>) {
2320+
return (
2321+
<svg {...props} viewBox='0 0 64 64' fill='none' xmlns='http://www.w3.org/2000/svg'>
2322+
<circle cx='32' cy='32' r='30' fill='#03A9F4' />
2323+
<circle cx='32' cy='32' r='14' stroke='white' strokeWidth='4' fill='none' />
2324+
<line x1='32' y1='22' x2='32' y2='32' stroke='white' strokeWidth='4' strokeLinecap='round' />
2325+
<line x1='32' y1='32' x2='40' y2='32' stroke='white' strokeWidth='4' strokeLinecap='round' />
2326+
</svg>
2327+
)
2328+
}
2329+
23192330
export function ClerkIcon(props: SVGProps<SVGSVGElement>) {
23202331
return (
23212332
<svg {...props} viewBox='0 0 128 128' fill='none' xmlns='http://www.w3.org/2000/svg'>

0 commit comments

Comments
 (0)