diff --git a/components/clicktime/.gitignore b/components/clicktime/.gitignore deleted file mode 100644 index ec761ccab7595..0000000000000 --- a/components/clicktime/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.js -*.mjs -dist \ No newline at end of file diff --git a/components/clicktime/actions/create-client/create-client.mjs b/components/clicktime/actions/create-client/create-client.mjs new file mode 100644 index 0000000000000..4829c8a826c2c --- /dev/null +++ b/components/clicktime/actions/create-client/create-client.mjs @@ -0,0 +1,88 @@ +import app from "../../clicktime.app.mjs"; + +export default { + key: "clicktime-create-client", + name: "Create Client", + description: "Create a Client on ClickTime [See the documentation](https://developer.clicktime.com/docs/api/#/Clients)", + version: "0.0.1", + type: "action", + props: { + app, + clientNumber: { + propDefinition: [ + app, + "clientNumber", + ], + optional: true, + }, + accountingPackageId: { + propDefinition: [ + app, + "accountingPackageId", + ], + optional: true, + }, + billingRate: { + propDefinition: [ + app, + "billingRate", + ], + description: "The billing rate for the client", + optional: true, + }, + isActive: { + propDefinition: [ + app, + "isActive", + ], + description: "Indicates whether the client is currently active", + optional: true, + }, + isEligibleTimeOffAllocation: { + propDefinition: [ + app, + "isEligibleTimeOffAllocation", + ], + description: "Determines if the client is eligible for time-off allocation", + optional: true, + }, + name: { + propDefinition: [ + app, + "name", + ], + description: "The name of the client", + }, + notes: { + propDefinition: [ + app, + "notes", + ], + description: "Additional information related to the client", + optional: true, + }, + shortName: { + propDefinition: [ + app, + "shortName", + ], + }, + }, + async run({ $ }) { + const response = await this.app.createClient({ + $, + data: { + AccountingPackageID: this.accountingPackageId, + BillingRate: this.billingRate, + ClientNumber: this.clientNumber, + IsActive: this.isActive, + IsEligibleTimeOffAllocation: this.isEligibleTimeOffAllocation, + Name: this.name, + Notes: this.notes, + ShortName: this.shortName, + }, + }); + $.export("$summary", `Successfully created Client with the ID: ${response.data.ID}`); + return response; + }, +}; diff --git a/components/clicktime/actions/create-job/create-job.mjs b/components/clicktime/actions/create-job/create-job.mjs new file mode 100644 index 0000000000000..547dd13e996c9 --- /dev/null +++ b/components/clicktime/actions/create-job/create-job.mjs @@ -0,0 +1,136 @@ +import app from "../../clicktime.app.mjs"; + +export default { + key: "clicktime-create-job", + name: "Create Job", + description: "Create a Job on Clicktime. [See the documentation](https://developer.clicktime.com/docs/api/#/operations/Jobs/CreateJob)", + version: "0.0.1", + type: "action", + props: { + app, + accountingPackageId: { + propDefinition: [ + app, + "accountingPackageId", + ], + optional: true, + }, + billingRate: { + propDefinition: [ + app, + "billingRate", + ], + description: "The billing rate for the job", + optional: true, + }, + isActive: { + propDefinition: [ + app, + "isActive", + ], + description: "Indicates whether the job is currently active", + optional: true, + }, + isEligibleTimeOffAllocation: { + propDefinition: [ + app, + "isEligibleTimeOffAllocation", + ], + description: "Determines if the job is eligible for time-off allocation", + optional: true, + }, + name: { + propDefinition: [ + app, + "name", + ], + description: "The name of the job", + }, + notes: { + propDefinition: [ + app, + "notes", + ], + description: "Additional information related to the job", + optional: true, + }, + clientId: { + propDefinition: [ + app, + "clientId", + ], + }, + includeInRm: { + propDefinition: [ + app, + "includeInRm", + ], + optional: true, + }, + isBillable: { + propDefinition: [ + app, + "isBillable", + ], + optional: true, + }, + jobNumber: { + propDefinition: [ + app, + "jobNumber", + ], + }, + startDate: { + propDefinition: [ + app, + "startDate", + ], + description: "The start date of the job, i.e.: `2020-01-01`", + optional: true, + }, + endDate: { + propDefinition: [ + app, + "endDate", + ], + optional: true, + }, + timeRequiresApproval: { + propDefinition: [ + app, + "timeRequiresApproval", + ], + optional: true, + }, + useCompanyBillingRate: { + propDefinition: [ + app, + "useCompanyBillingRate", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.app.createJob({ + $, + data: { + AccountingPackageID: this.accountingPackageId, + BillingRate: this.billingRate, + IsActive: this.isActive, + IsEligibleTimeOffAllocation: this.isEligibleTimeOffAllocation, + Name: this.name, + Notes: this.notes, + ClientID: this.clientId, + EndDate: this.endDate, + IncludeInRM: this.includeInRm, + IsBillable: this.isBillable, + JobNumber: this.jobNumber, + StartDate: this.startDate, + TimeRequiresApproval: this.timeRequiresApproval, + UseCompanyBillingRate: this.useCompanyBillingRate, + }, + }); + $.export("$summary", `Successfully created Job with ID: ${response.data.ID}`); + return response; + }, +}; diff --git a/components/clicktime/actions/create-user/create-user.mjs b/components/clicktime/actions/create-user/create-user.mjs new file mode 100644 index 0000000000000..6dc617df615ac --- /dev/null +++ b/components/clicktime/actions/create-user/create-user.mjs @@ -0,0 +1,95 @@ +import app from "../../clicktime.app.mjs"; + +export default { + key: "clicktime-create-user", + name: "Create User", + description: "Create an User on ClickTime. [See the documentation](https://developer.clicktime.com/docs/api/#/operations/Users/CreateManagedUser)", + version: "0.0.1", + type: "action", + props: { + app, + billingRate: { + propDefinition: [ + app, + "billingRate", + ], + description: "The billing rate for the user", + optional: true, + }, + isActive: { + propDefinition: [ + app, + "isActive", + ], + description: "Indicates whether the user is currently active", + optional: true, + }, + name: { + propDefinition: [ + app, + "name", + ], + description: "The name of the user", + }, + startDate: { + propDefinition: [ + app, + "startDate", + ], + description: "The start date of the user, i.e.: `2020-01-01`", + optional: true, + }, + costModel: { + propDefinition: [ + app, + "costModel", + ], + optional: true, + }, + costRate: { + propDefinition: [ + app, + "costRate", + ], + optional: true, + }, + email: { + propDefinition: [ + app, + "email", + ], + }, + employmentTypeId: { + propDefinition: [ + app, + "employmentTypeId", + ], + optional: true, + }, + role: { + propDefinition: [ + app, + "role", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.app.createUser({ + $, + data: { + BillingRate: this.billingRate, + IsActive: this.isActive, + Name: this.name, + StartDate: this.startDate, + CostModel: this.costModel, + CostRate: this.costRate, + Email: this.email, + EmploymentTypeID: this.employmentTypeId, + Role: this.role, + }, + }); + $.export("$summary", `Successfully created User with the ID: ${response.data.ID}`); + return response; + }, +}; diff --git a/components/clicktime/app/clicktime.app.ts b/components/clicktime/app/clicktime.app.ts deleted file mode 100644 index b0dbed95844eb..0000000000000 --- a/components/clicktime/app/clicktime.app.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineApp } from "@pipedream/types"; - -export default defineApp({ - type: "app", - app: "clicktime", - propDefinitions: {}, - methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); - }, - }, -}); \ No newline at end of file diff --git a/components/clicktime/clicktime.app.mjs b/components/clicktime/clicktime.app.mjs new file mode 100644 index 0000000000000..a03734d33cfcd --- /dev/null +++ b/components/clicktime/clicktime.app.mjs @@ -0,0 +1,201 @@ +import { axios } from "@pipedream/platform"; +import constants from "./common/constants.mjs"; + +export default { + type: "app", + app: "clicktime", + propDefinitions: { + accountingPackageId: { + type: "string", + label: "Accounting Package ID", + description: "Unique identifier for the accounting package", + }, + billingRate: { + type: "string", + label: "Billing Rate", + description: "The billing rate for the user, job or client", + }, + clientNumber: { + type: "string", + label: "Client Number", + description: "A unique identifier for the client in the system", + }, + isActive: { + type: "boolean", + label: "Is Active", + description: "Whether the user, job or client is currently active", + }, + isEligibleTimeOffAllocation: { + type: "boolean", + label: "Eligible for Time Off Allocation", + description: "Determines if the entity is eligible for time-off allocation", + }, + name: { + type: "string", + label: "Name", + description: "The name of the user, job or client", + }, + notes: { + type: "string", + label: "Notes", + description: "Additional information related to the user, job or client", + }, + shortName: { + type: "string", + label: "Short Name", + description: "A shorter version of the name for easier reference", + }, + clientId: { + type: "string", + label: "Client ID", + description: "Unique identifier of the client associated with a job", + async options({ page }) { + const limit = constants.DEFAULT_LIMIT; + const response = await this.getClients({ + params: { + limit, + offset: page * limit, + }, + }); + const clientIds = response.data; + return clientIds.map(({ + ID, Name, + }) => ({ + label: Name, + value: ID, + })); + }, + }, + endDate: { + type: "string", + label: "End Date", + description: "The end date of the job, i.e.: `2020-01-01`", + }, + includeInRm: { + type: "boolean", + label: "Include in RM", + description: "Specifies whether the job should be included in RM", + }, + isBillable: { + type: "boolean", + label: "Is Billable", + description: "Indicates whether the job is billable", + }, + jobNumber: { + type: "string", + label: "Job Number", + description: "Unique identifier assigned to a job for tracking purposes", + }, + startDate: { + type: "string", + label: "Start Date", + description: "Start date of the user or job, i.e.: `2020-01-01`", + }, + timeRequiresApproval: { + type: "boolean", + label: "Time Requires Approval", + description: "Indicates whether time entries for the job require approval", + }, + useCompanyBillingRate: { + type: "boolean", + label: "Use Company Billing Rate", + description: "Specifies whether the job uses the company-wide billing rate instead of a custom one", + }, + costModel: { + type: "string", + label: "Cost Model", + description: "Defines the cost model used for the user", + options: constants.COST_MODELS, + }, + costRate: { + type: "string", + label: "Cost Rate", + description: "The internal cost rate associated with the user", + }, + email: { + type: "string", + label: "Email", + description: "The email address associated with the user", + }, + employmentTypeId: { + type: "string", + label: "Employment Type ID", + description: "Unique identifier for the user's employment type", + async options({ page }) { + const limit = constants.DEFAULT_LIMIT; + const response = await this.getEmploymentTypes({ + params: { + limit, + offset: page * limit, + }, + }); + const employmentTypeIds = response.data; + return employmentTypeIds.map(({ + ID, Name, + }) => ({ + label: Name, + value: ID, + })); + }, + }, + role: { + type: "string", + label: "Role", + description: "The role assigned to the user", + }, + }, + methods: { + _baseUrl() { + return "https://api.clicktime.com/v2"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + path, + headers, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: this._baseUrl() + path, + headers: { + "Authorization": `Token ${this.$auth.api_token}`, + ...headers, + }, + }); + }, + async createClient(args = {}) { + return this._makeRequest({ + path: "/Clients", + method: "post", + ...args, + }); + }, + async createJob(args = {}) { + return this._makeRequest({ + path: "/Jobs", + method: "post", + ...args, + }); + }, + async createUser(args = {}) { + return this._makeRequest({ + path: "/Manage/Users", + method: "post", + ...args, + }); + }, + async getClients(args = {}) { + return this._makeRequest({ + path: "/Clients", + ...args, + }); + }, + async getEmploymentTypes(args = {}) { + return this._makeRequest({ + path: "/EmploymentTypes", + ...args, + }); + }, + }, +}; diff --git a/components/clicktime/common/constants.mjs b/components/clicktime/common/constants.mjs new file mode 100644 index 0000000000000..6d2c2b05b45ab --- /dev/null +++ b/components/clicktime/common/constants.mjs @@ -0,0 +1,7 @@ +export default { + COST_MODELS: [ + "Hourly", + "Salary", + ], + DEFAULT_LIMIT: 20, +}; diff --git a/components/clicktime/package.json b/components/clicktime/package.json index dd2501369f35b..230896b1a57a5 100644 --- a/components/clicktime/package.json +++ b/components/clicktime/package.json @@ -1,16 +1,18 @@ { "name": "@pipedream/clicktime", - "version": "0.0.2", + "version": "0.1.0", "description": "Pipedream ClickTime Components", - "main": "dist/app/clicktime.app.mjs", + "main": "clicktime.app.mjs", "keywords": [ "pipedream", "clicktime" ], - "files": ["dist"], "homepage": "https://pipedream.com/apps/clicktime", "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b67a545c0f714..a6819885c5274 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -796,8 +796,7 @@ importers: specifier: ^8.3.2 version: 8.3.2 - components/anchor_browser: - specifiers: {} + components/anchor_browser: {} components/annature: {} @@ -2400,7 +2399,11 @@ importers: specifier: ^1.6.0 version: 1.6.6 - components/clicktime: {} + components/clicktime: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/clickup: dependencies: @@ -3104,8 +3107,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/databricks_oauth: - specifiers: {} + components/databricks_oauth: {} components/datadog: dependencies: @@ -5564,8 +5566,7 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/griptape: - specifiers: {} + components/griptape: {} components/grist: dependencies: