From 55fbfd7dbb7522a137a6b2259481da895be3fd08 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Fri, 24 Jan 2025 12:07:07 -0500 Subject: [PATCH 1/8] charthop init --- .../create-employee/create-employee.mjs | 57 +++++ .../record-compensation-change.mjs | 50 ++++ .../update-employee-details.mjs | 37 +++ components/charthop/charthop.app.mjs | 230 +++++++++++++++++- components/charthop/package.json | 2 +- .../new-compensation-change-instant.mjs | 121 +++++++++ .../new-employee-instant.mjs | 119 +++++++++ .../new-org-change-instant.mjs | 106 ++++++++ 8 files changed, 719 insertions(+), 3 deletions(-) create mode 100644 components/charthop/actions/create-employee/create-employee.mjs create mode 100644 components/charthop/actions/record-compensation-change/record-compensation-change.mjs create mode 100644 components/charthop/actions/update-employee-details/update-employee-details.mjs create mode 100644 components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs create mode 100644 components/charthop/sources/new-employee-instant/new-employee-instant.mjs create mode 100644 components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs diff --git a/components/charthop/actions/create-employee/create-employee.mjs b/components/charthop/actions/create-employee/create-employee.mjs new file mode 100644 index 0000000000000..4ad7ca7385660 --- /dev/null +++ b/components/charthop/actions/create-employee/create-employee.mjs @@ -0,0 +1,57 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "charthop-create-employee", + name: "Create Employee", + description: "Adds a new employee to the system. [See the documentation](https://docs.charthop.com)", + version: "0.0.{{ts}}", + type: "action", + props: { + charthop: { + type: "app", + app: "charthop", + }, + addEmployeeName: { + propDefinition: [ + charthop, + "addEmployeeName", + ], + }, + addEmployeeEmail: { + propDefinition: [ + charthop, + "addEmployeeEmail", + ], + }, + addEmployeeRole: { + propDefinition: [ + charthop, + "addEmployeeRole", + ], + }, + addEmployeeStartDate: { + propDefinition: [ + charthop, + "addEmployeeStartDate", + ], + }, + addEmployeeDepartment: { + propDefinition: [ + charthop, + "addEmployeeDepartment", + ], + }, + addEmployeeCustomFields: { + propDefinition: [ + charthop, + "addEmployeeCustomFields", + ], + }, + }, + async run({ $ }) { + const employee = await this.charthop.addEmployee(); + $.export("$summary", `Created employee ${this.addEmployeeName}`); + return employee; + }, +}; diff --git a/components/charthop/actions/record-compensation-change/record-compensation-change.mjs b/components/charthop/actions/record-compensation-change/record-compensation-change.mjs new file mode 100644 index 0000000000000..ec33d49bd735d --- /dev/null +++ b/components/charthop/actions/record-compensation-change/record-compensation-change.mjs @@ -0,0 +1,50 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "charthop-record-compensation-change", + name: "Record Compensation Change", + description: "Logs or modifies an employee's compensation records, such as salary increases, bonuses, or equity grants. [See the documentation]()", + version: "0.0.{{ts}}", + type: "action", + props: { + charthop, + employeeId: { + propDefinition: [ + charthop, + "modifyCompensationEmployeeId", + ], + }, + compensationDetails: { + propDefinition: [ + charthop, + "modifyCompensationDetails", + ], + }, + effectiveDate: { + propDefinition: [ + charthop, + "modifyCompensationEffectiveDate", + ], + optional: true, + }, + reason: { + propDefinition: [ + charthop, + "modifyCompensationReason", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.charthop.modifyCompensation(); + const summaryParts = [ + `Compensation for employee ID ${this.employeeId} has been updated`, + ]; + if (this.reason) { + summaryParts.push(`for reason: ${this.reason}`); + } + $.export("$summary", summaryParts.join(" ") + "."); + return response; + }, +}; diff --git a/components/charthop/actions/update-employee-details/update-employee-details.mjs b/components/charthop/actions/update-employee-details/update-employee-details.mjs new file mode 100644 index 0000000000000..7bd767f39a8c1 --- /dev/null +++ b/components/charthop/actions/update-employee-details/update-employee-details.mjs @@ -0,0 +1,37 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "charthop-update-employee-details", + name: "Update Employee Details", + description: "Updates an existing employee's profile, including department, role, or compensation. [See the documentation](https://docs.charthop.com)", + version: "0.0.{{ts}}", + type: "action", + props: { + charthop, + updateEmployeeId: { + propDefinition: [ + charthop, + "updateEmployeeId", + ], + }, + updateFields: { + propDefinition: [ + charthop, + "updateFields", + ], + }, + updateMetadata: { + propDefinition: [ + charthop, + "updateMetadata", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.charthop.updateEmployeeProfile(); + $.export("$summary", `Successfully updated employee with ID ${this.updateEmployeeId}`); + return response; + }, +}; diff --git a/components/charthop/charthop.app.mjs b/components/charthop/charthop.app.mjs index 746957318d73f..44169ab363608 100644 --- a/components/charthop/charthop.app.mjs +++ b/components/charthop/charthop.app.mjs @@ -1,11 +1,237 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "charthop", - propDefinitions: {}, + version: "0.0.{{ts}}", + propDefinitions: { + // Event Filters for New Employee Added + newEmployeeDepartmentFilter: { + type: "string", + label: "Department Filter", + description: "Optional department filter for new employee events.", + optional: true, + }, + newEmployeeRoleFilter: { + type: "string", + label: "Role Filter", + description: "Optional role filter for new employee events.", + optional: true, + }, + // Event Filters for Compensation Details Updated + compensationDepartmentFilter: { + type: "string", + label: "Department Filter", + description: "Optional department filter for compensation update events.", + optional: true, + }, + compensationEmployeeIdFilter: { + type: "string", + label: "Employee ID Filter", + description: "Optional employee ID filter for compensation update events.", + optional: true, + }, + // Event Filters for Organizational Structure Changes + orgStructureTeamFilter: { + type: "string", + label: "Team Filter", + description: "Optional team filter for organizational structure change events.", + optional: true, + }, + orgStructureDivisionFilter: { + type: "string", + label: "Division Filter", + description: "Optional division filter for organizational structure change events.", + optional: true, + }, + + // Action: Add New Employee + addEmployeeName: { + type: "string", + label: "Employee Name", + description: "Name of the new employee.", + }, + addEmployeeEmail: { + type: "string", + label: "Employee Email", + description: "Email address of the new employee.", + }, + addEmployeeRole: { + type: "string", + label: "Employee Role", + description: "Role of the new employee.", + }, + addEmployeeStartDate: { + type: "string", + label: "Start Date", + description: "Optional start date for the new employee.", + optional: true, + }, + addEmployeeDepartment: { + type: "string", + label: "Department", + description: "Optional department for the new employee.", + optional: true, + }, + addEmployeeCustomFields: { + type: "string[]", + label: "Custom Fields", + description: "Optional custom fields for the new employee. Provide as JSON strings.", + optional: true, + }, + + // Action: Update Employee Profile + updateEmployeeId: { + type: "string", + label: "Employee ID", + description: "ID of the employee to update.", + }, + updateFields: { + type: "string[]", + label: "Fields to Update", + description: "Fields to update in the employee profile. Provide as JSON strings.", + }, + updateMetadata: { + type: "string", + label: "Metadata", + description: "Optional metadata for the employee update. Provide as a JSON string.", + optional: true, + }, + + // Action: Modify Compensation Records + modifyCompensationEmployeeId: { + type: "string", + label: "Employee ID", + description: "ID of the employee for compensation update.", + }, + modifyCompensationDetails: { + type: "string", + label: "Compensation Details", + description: "Details of the compensation update. Provide as a JSON string.", + }, + modifyCompensationEffectiveDate: { + type: "string", + label: "Effective Date", + description: "Optional effective date for the compensation update.", + optional: true, + }, + modifyCompensationReason: { + type: "string", + label: "Reason for Change", + description: "Optional reason for the compensation update.", + optional: true, + }, + }, methods: { - // this.$auth contains connected account data + // Existing method authKeys() { console.log(Object.keys(this.$auth)); }, + + _baseUrl() { + return "https://api.charthop.com"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, method = "GET", path = "/", headers, ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + method, + url: `${this._baseUrl()}${path}`, + headers: { + ...headers, + "Authorization": `Bearer ${this.$auth.api_token}`, + "Content-Type": "application/json", + }, + }); + }, + // Event: Emit New Employee Added Event + async emitNewEmployeeAddedEvent(opts = {}) { + const data = {}; + if (this.newEmployeeDepartmentFilter) data.department = this.newEmployeeDepartmentFilter; + if (this.newEmployeeRoleFilter) data.role = this.newEmployeeRoleFilter; + return this._makeRequest({ + method: "POST", + path: "/events/new-employee-added", + data, + }); + }, + // Event: Emit Compensation Updated Event + async emitCompensationUpdatedEvent(opts = {}) { + const data = {}; + if (this.compensationDepartmentFilter) data.department = this.compensationDepartmentFilter; + if (this.compensationEmployeeIdFilter) data.employee_id = this.compensationEmployeeIdFilter; + return this._makeRequest({ + method: "POST", + path: "/events/compensation-updated", + data, + }); + }, + // Event: Emit Organizational Structure Changed Event + async emitOrgStructureChangedEvent(opts = {}) { + const data = {}; + if (this.orgStructureTeamFilter) data.team = this.orgStructureTeamFilter; + if (this.orgStructureDivisionFilter) data.division = this.orgStructureDivisionFilter; + return this._makeRequest({ + method: "POST", + path: "/events/org-structure-changed", + data, + }); + }, + + // Action: Add New Employee + async addEmployee(opts = {}) { + const data = { + name: this.addEmployeeName, + email: this.addEmployeeEmail, + role: this.addEmployeeRole, + }; + if (this.addEmployeeStartDate) data.start_date = this.addEmployeeStartDate; + if (this.addEmployeeDepartment) data.department = this.addEmployeeDepartment; + if (this.addEmployeeCustomFields) { + data.custom_fields = this.addEmployeeCustomFields.map((field) => JSON.parse(field)); + } + return this._makeRequest({ + method: "POST", + path: "/employees", + data, + }); + }, + + // Action: Update Employee Profile + async updateEmployeeProfile(opts = {}) { + const data = {}; + if (this.updateFields) { + data.fields_to_update = this.updateFields.map((field) => JSON.parse(field)); + } + if (this.updateMetadata) { + data.metadata = JSON.parse(this.updateMetadata); + } + return this._makeRequest({ + method: "PUT", + path: `/employees/${this.updateEmployeeId}`, + data, + }); + }, + + // Action: Modify Compensation Records + async modifyCompensation(opts = {}) { + const data = {}; + if (this.modifyCompensationDetails) { + data.compensation_details = JSON.parse(this.modifyCompensationDetails); + } + if (this.modifyCompensationEffectiveDate) { + data.effective_date = this.modifyCompensationEffectiveDate; + } + if (this.modifyCompensationReason) { + data.reason = this.modifyCompensationReason; + } + return this._makeRequest({ + method: "PUT", + path: `/employees/${this.modifyCompensationEmployeeId}/compensation`, + data, + }); + }, }, }; diff --git a/components/charthop/package.json b/components/charthop/package.json index f4cef0f7edc4e..24879cd5541dd 100644 --- a/components/charthop/package.json +++ b/components/charthop/package.json @@ -12,4 +12,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs b/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs new file mode 100644 index 0000000000000..4561411e3739c --- /dev/null +++ b/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs @@ -0,0 +1,121 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; +import crypto from "crypto"; + +export default { + key: "charthop-new-compensation-change-instant", + name: "New Compensation Change (Instant)", + description: "Emit new event when an employee's compensation details are updated. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + charthop: { + type: "app", + app: "charthop", + }, + db: "$.service.db", + http: { + type: "$.interface.http", + customResponse: true, + }, + compensationDepartmentFilter: { + propDefinition: [ + "charthop", + "compensationDepartmentFilter", + ], + optional: true, + }, + compensationEmployeeIdFilter: { + propDefinition: [ + "charthop", + "compensationEmployeeIdFilter", + ], + optional: true, + }, + }, + hooks: { + async deploy() { + const params = { + limit: 50, + sort: "desc", + }; + if (this.compensationDepartmentFilter) { + params.department = this.compensationDepartmentFilter; + } + if (this.compensationEmployeeIdFilter) { + params.employee_id = this.compensationEmployeeIdFilter; + } + const events = await this.charthop._makeRequest({ + method: "GET", + path: "/compensation-updates", + params, + }); + + const sortedEvents = events.sort((a, b) => new Date(a.updated_at) - new Date(b.updated_at)); + for (const event of sortedEvents) { + this.$emit(event, { + id: event.id || event.updated_at, + summary: `Compensation updated for employee ID ${event.employee_id}`, + ts: Date.parse(event.updated_at) || Date.now(), + }); + } + }, + async activate() { + const webhookData = { + event: "compensation_updated", + callback_url: this.http.endpoint, + filters: {}, + }; + if (this.compensationDepartmentFilter) { + webhookData.filters.department = this.compensationDepartmentFilter; + } + if (this.compensationEmployeeIdFilter) { + webhookData.filters.employee_id = this.compensationEmployeeIdFilter; + } + const response = await this.charthop._makeRequest({ + method: "POST", + path: "/webhooks", + data: webhookData, + }); + await this.db.set("webhookId", response.id); + }, + async deactivate() { + const webhookId = await this.db.get("webhookId"); + if (webhookId) { + await this.charthop._makeRequest({ + method: "DELETE", + path: `/webhooks/${webhookId}`, + }); + await this.db.delete("webhookId"); + } + }, + }, + async run(event) { + const signature = event.headers["x-charthop-signature"]; + const secretKey = this.charthop.$auth.secret_key; + const computedSignature = crypto + .createHmac("sha256", secretKey) + .update(event.rawBody) + .digest("base64"); + if (computedSignature !== signature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + const data = event.body; + this.$emit(data, { + id: data.id || data.updated_at, + summary: `Compensation updated for employee ID ${data.employee_id}`, + ts: data.updated_at + ? Date.parse(data.updated_at) + : Date.now(), + }); + this.http.respond({ + status: 200, + body: "OK", + }); + }, +}; diff --git a/components/charthop/sources/new-employee-instant/new-employee-instant.mjs b/components/charthop/sources/new-employee-instant/new-employee-instant.mjs new file mode 100644 index 0000000000000..49a043b2899a2 --- /dev/null +++ b/components/charthop/sources/new-employee-instant/new-employee-instant.mjs @@ -0,0 +1,119 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; +import crypto from "crypto"; + +export default { + key: "charthop-new-employee-instant", + name: "New Employee Added", + description: "Emit new event when a new employee is added to the organization. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + charthop, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + newEmployeeDepartmentFilter: { + propDefinition: [ + charthop, + "newEmployeeDepartmentFilter", + ], + }, + newEmployeeRoleFilter: { + propDefinition: [ + charthop, + "newEmployeeRoleFilter", + ], + }, + }, + hooks: { + async activate() { + const webhookUrl = this.http.endpoint; + const data = { + webhook_url: webhookUrl, + }; + if (this.newEmployeeDepartmentFilter) { + data.department = this.newEmployeeDepartmentFilter; + } + if (this.newEmployeeRoleFilter) { + data.role = this.newEmployeeRoleFilter; + } + const response = await this.charthop.emitNewEmployeeAddedEvent(data); + if (response.id) { + await this.db.set("webhookId", response.id); + } + }, + async deactivate() { + const webhookId = await this.db.get("webhookId"); + if (webhookId) { + await this.charthop._makeRequest({ + method: "DELETE", + path: `/webhooks/${webhookId}`, + }); + await this.db.set("webhookId", null); + } + }, + async deploy() { + const filters = {}; + if (this.newEmployeeDepartmentFilter) { + filters.department = this.newEmployeeDepartmentFilter; + } + if (this.newEmployeeRoleFilter) { + filters.role = this.newEmployeeRoleFilter; + } + const events = await this.charthop._makeRequest({ + method: "GET", + path: "/events/new_employee_added", + params: { + limit: 50, + ...filters, + }, + }); + for (const event of events.reverse()) { + this.$emit(event, { + id: event.id || event.created_at, + summary: `New employee added: ${event.name}`, + ts: Date.parse(event.created_at) || Date.now(), + }); + } + }, + }, + async run(event) { + const receivedSignature = event.headers["x-charthop-signature"]; + const secret = this.charthop.$auth.api_token; + const computedSignature = crypto + .createHmac("sha256", secret) + .update(event.body) + .digest("hex"); + if (computedSignature !== receivedSignature) { + await this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + const data = JSON.parse(event.body); + if ( + this.newEmployeeDepartmentFilter && + data.department !== this.newEmployeeDepartmentFilter + ) { + return; + } + if ( + this.newEmployeeRoleFilter && + data.role !== this.newEmployeeRoleFilter + ) { + return; + } + + this.$emit(data, { + id: data.id || data.created_at, + summary: `New employee added: ${data.name}`, + ts: Date.parse(data.created_at) || Date.now(), + }); + }, +}; diff --git a/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs b/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs new file mode 100644 index 0000000000000..06f56297810d9 --- /dev/null +++ b/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs @@ -0,0 +1,106 @@ +import charthop from "../../charthop.app.mjs"; +import { axios } from "@pipedream/platform"; +import crypto from "crypto"; + +export default { + key: "charthop-new-org-change-instant", + name: "New Organizational Structure Change (Instant)", + description: "Emit new events when there are changes to the organizational structure, such as team reassignments or role updates. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + charthop: { + type: "app", + app: "charthop", + }, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + orgStructureTeamFilter: { + propDefinition: [ + "charthop", + "orgStructureTeamFilter", + ], + optional: true, + }, + orgStructureDivisionFilter: { + propDefinition: [ + "charthop", + "orgStructureDivisionFilter", + ], + optional: true, + }, + }, + hooks: { + async deploy() { + const params = {}; + if (this.orgStructureTeamFilter) params.team = this.orgStructureTeamFilter; + if (this.orgStructureDivisionFilter) params.division = this.orgStructureDivisionFilter; + const recentEvents = await this.charthop.emitOrgStructureChangedEvent({ + data: params, + paginate: true, + max: 50, + }); + const events = recentEvents.events || []; + for (const event of events.slice(-50)) { + this.$emit(event, { + id: event.id || event.ts.toString(), + summary: `Organizational structure change in ${event.team || "unknown team"}`, + ts: event.ts + ? Date.parse(event.ts) + : Date.now(), + }); + } + }, + async activate() { + const webhookUrl = this.http.endpoint; + const webhookResponse = await this.charthop.createWebhook({ + event: "org_structure_changed", + url: webhookUrl, + team: this.orgStructureTeamFilter, + division: this.orgStructureDivisionFilter, + }); + await this.db.set("webhookId", webhookResponse.id); + }, + async deactivate() { + const webhookId = await this.db.get("webhookId"); + if (webhookId) { + await this.charthop.deleteWebhook(webhookId); + await this.db.delete("webhookId"); + } + }, + }, + async run(event) { + const secret = this.charthop.$auth.webhook_secret; + const signature = event.headers["x-charthop-signature"]; + const rawBody = await this.http.rawBody; + + const computedSignature = crypto + .createHmac("sha256", secret) + .update(rawBody) + .digest("base64"); + + if (computedSignature !== signature) { + this.http.respond({ + status: 401, + body: "Unauthorized", + }); + return; + } + + const eventData = event.body; + const id = eventData.id || eventData.ts.toString(); + const summary = `Organizational structure change: ${eventData.description || "No description"}`; + const ts = eventData.ts + ? Date.parse(eventData.ts) + : Date.now(); + this.$emit(eventData, { + id, + summary, + ts, + }); + }, +}; From 44485d11dd5c5597f6121b281ddd98506ec80e23 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Fri, 24 Jan 2025 15:51:29 -0500 Subject: [PATCH 2/8] wip --- .../create-employee/create-employee.mjs | 67 +++-- .../record-compensation-change.mjs | 1 - .../update-employee-details.mjs | 79 +++++- components/charthop/charthop.app.mjs | 250 ++++++++++++------ components/charthop/package.json | 5 +- components/charthop/sources/common/base.mjs | 0 .../new-compensation-change-instant.mjs | 6 +- .../new-employee-instant.mjs | 1 - .../new-org-change-instant.mjs | 6 +- 9 files changed, 292 insertions(+), 123 deletions(-) create mode 100644 components/charthop/sources/common/base.mjs diff --git a/components/charthop/actions/create-employee/create-employee.mjs b/components/charthop/actions/create-employee/create-employee.mjs index 4ad7ca7385660..8a0a14afbe678 100644 --- a/components/charthop/actions/create-employee/create-employee.mjs +++ b/components/charthop/actions/create-employee/create-employee.mjs @@ -1,57 +1,84 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "charthop-create-employee", name: "Create Employee", - description: "Adds a new employee to the system. [See the documentation](https://docs.charthop.com)", + description: "Adds a new employee to the system. [See the documentation](https://api.charthop.com/swagger#/user/createUser)", version: "0.0.{{ts}}", type: "action", props: { - charthop: { - type: "app", - app: "charthop", + charthop, + orgId: { + propDefinition: [ + charthop, + "orgId", + ], + }, + firstName: { + propDefinition: [ + charthop, + "firstName", + ], }, - addEmployeeName: { + middleName: { propDefinition: [ charthop, - "addEmployeeName", + "middleName", ], }, - addEmployeeEmail: { + lastName: { propDefinition: [ charthop, - "addEmployeeEmail", + "lastName", ], }, - addEmployeeRole: { + preferredFirstName: { propDefinition: [ charthop, - "addEmployeeRole", + "preferredFirstName", ], }, - addEmployeeStartDate: { + preferredLastName: { propDefinition: [ charthop, - "addEmployeeStartDate", + "preferredLastName", ], }, - addEmployeeDepartment: { + email: { propDefinition: [ charthop, - "addEmployeeDepartment", + "email", ], }, - addEmployeeCustomFields: { + status: { propDefinition: [ charthop, - "addEmployeeCustomFields", + "status", ], }, }, async run({ $ }) { - const employee = await this.charthop.addEmployee(); - $.export("$summary", `Created employee ${this.addEmployeeName}`); - return employee; + const response = await this.charthop.createUser({ + $, + data: { + orgs: [ + { + orgId: this.orgId, + access: "MEMBER", + roleId: await this.charthop.getEmployeeRoleId($), + }, + ], + name: { + first: this.firstName, + middle: this.middleName, + last: this.lastName, + pref: this.preferredFirstName, + prefLast: this.preferredLastName, + }, + email: this.email, + }, + }); + $.export("$summary", `Successfully created employee with ID: ${response.id}`); + return response; }, }; diff --git a/components/charthop/actions/record-compensation-change/record-compensation-change.mjs b/components/charthop/actions/record-compensation-change/record-compensation-change.mjs index ec33d49bd735d..c2e39b5ff3dbe 100644 --- a/components/charthop/actions/record-compensation-change/record-compensation-change.mjs +++ b/components/charthop/actions/record-compensation-change/record-compensation-change.mjs @@ -1,5 +1,4 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "charthop-record-compensation-change", diff --git a/components/charthop/actions/update-employee-details/update-employee-details.mjs b/components/charthop/actions/update-employee-details/update-employee-details.mjs index 7bd767f39a8c1..8d134eac77d2c 100644 --- a/components/charthop/actions/update-employee-details/update-employee-details.mjs +++ b/components/charthop/actions/update-employee-details/update-employee-details.mjs @@ -1,37 +1,96 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "charthop-update-employee-details", name: "Update Employee Details", - description: "Updates an existing employee's profile, including department, role, or compensation. [See the documentation](https://docs.charthop.com)", + description: "Updates an existing employee's details. [See the documentation](https://api.charthop.com/swagger#/user/updateUser)", version: "0.0.{{ts}}", type: "action", props: { charthop, - updateEmployeeId: { + orgId: { propDefinition: [ charthop, - "updateEmployeeId", + "orgId", ], }, - updateFields: { + employeeId: { propDefinition: [ charthop, - "updateFields", + "employeeId", + (c) => ({ + orgId: c.orgId, + }), ], }, - updateMetadata: { + firstName: { propDefinition: [ charthop, - "updateMetadata", + "firstName", ], optional: true, }, + middleName: { + propDefinition: [ + charthop, + "middleName", + ], + }, + lastName: { + propDefinition: [ + charthop, + "lastName", + ], + optional: true, + }, + preferredFirstName: { + propDefinition: [ + charthop, + "preferredFirstName", + ], + }, + preferredLastName: { + propDefinition: [ + charthop, + "preferredLastName", + ], + }, + email: { + propDefinition: [ + charthop, + "email", + ], + optional: true, + }, + status: { + propDefinition: [ + charthop, + "status", + ], + }, }, async run({ $ }) { - const response = await this.charthop.updateEmployeeProfile(); - $.export("$summary", `Successfully updated employee with ID ${this.updateEmployeeId}`); + const { + name, email, + } = await this.charthop.getUser({ + $, + userId: this.employeeId, + }); + const response = await this.charthop.updateUser({ + $, + userId: this.employeeId, + data: { + name: { + first: this.firstName || name.first, + middle: this.middleName || name.middle, + last: this.lastName || name.last, + pref: this.preferredFirstName || name.pref, + prefLast: this.preferredLastName || name.prefLast, + }, + email: this.email || email, + }, + }); + $.export("$summary", `Successfully updated employee with ID ${this.employeeId}`); return response; }, }; diff --git a/components/charthop/charthop.app.mjs b/components/charthop/charthop.app.mjs index 44169ab363608..6683dfa6ddef6 100644 --- a/components/charthop/charthop.app.mjs +++ b/components/charthop/charthop.app.mjs @@ -3,8 +3,120 @@ import { axios } from "@pipedream/platform"; export default { type: "app", app: "charthop", - version: "0.0.{{ts}}", propDefinitions: { + orgId: { + type: "string", + label: "Organization ID", + description: "The identifier of an organization", + async options({ prevContext }) { + const params = prevContext?.from + ? { + from: prevContext.from, + } + : {}; + const { data } = await this.listOrgs({ + params, + }); + const options = data.map(({ + id: value, name: label, + }) => ({ + value, + label, + })); + return { + options, + context: { + from: options[options.length - 1].id, + }, + }; + }, + }, + employeeId: { + type: "string", + label: "Employee ID", + description: "The identifier of an employee", + async options({ + orgId, prevContext, + }) { + const params = prevContext?.from + ? { + from: prevContext.from, + } + : {}; + const { data } = await this.listUsers({ + params: { + ...params, + orgId, + }, + }); + const employees = []; + const employeeRoleId = await this.getEmployeeRoleId({ + orgId, + }); + for (const user of data) { + if (user.orgs.find((u) => u.orgId === orgId && u.roleId === employeeRoleId)) { + employees.push(user); + } + } + const options = employees.map(({ + id: value, name, + }) => ({ + value, + label: (`${name.first} ${name.last}`).trim(), + })); + return { + options, + context: { + from: data[data.length - 1].id, + }, + }; + }, + }, + firstName: { + type: "string", + label: "First Name", + description: "First name of the employee", + }, + middleName: { + type: "string", + label: "Middle Name", + description: "Middle name of the employee", + optional: true, + }, + lastName: { + type: "string", + label: "Last Name", + description: "Last name of the employee", + }, + preferredFirstName: { + type: "string", + label: "Preferred First Name", + description: "The preferred first name of the employee", + optional: true, + }, + preferredLastName: { + type: "string", + label: "Preferred Last Name", + description: "The preferred last name of the employee", + optional: true, + }, + email: { + type: "string", + label: "Email", + description: "Email address of the employee", + }, + status: { + type: "string", + label: "Status", + description: "The status of the emaployee", + options: [ + "SUPERUSER", + "NORMAL", + "INACTIVE", + "UNINSTALLED", + ], + optional: true, + }, // Event Filters for New Employee Added newEmployeeDepartmentFilter: { type: "string", @@ -45,41 +157,6 @@ export default { optional: true, }, - // Action: Add New Employee - addEmployeeName: { - type: "string", - label: "Employee Name", - description: "Name of the new employee.", - }, - addEmployeeEmail: { - type: "string", - label: "Employee Email", - description: "Email address of the new employee.", - }, - addEmployeeRole: { - type: "string", - label: "Employee Role", - description: "Role of the new employee.", - }, - addEmployeeStartDate: { - type: "string", - label: "Start Date", - description: "Optional start date for the new employee.", - optional: true, - }, - addEmployeeDepartment: { - type: "string", - label: "Department", - description: "Optional department for the new employee.", - optional: true, - }, - addEmployeeCustomFields: { - type: "string[]", - label: "Custom Fields", - description: "Optional custom fields for the new employee. Provide as JSON strings.", - optional: true, - }, - // Action: Update Employee Profile updateEmployeeId: { type: "string", @@ -123,29 +200,53 @@ export default { }, }, methods: { - // Existing method - authKeys() { - console.log(Object.keys(this.$auth)); - }, - _baseUrl() { - return "https://api.charthop.com"; + return "https://api.charthop.com/v1"; }, - async _makeRequest(opts = {}) { - const { - $ = this, method = "GET", path = "/", headers, ...otherOpts - } = opts; + _makeRequest({ + $ = this, + path, + ...otherOpts + }) { return axios($, { ...otherOpts, - method, url: `${this._baseUrl()}${path}`, headers: { - ...headers, "Authorization": `Bearer ${this.$auth.api_token}`, "Content-Type": "application/json", }, }); }, + listOrgs(opts = {}) { + return this._makeRequest({ + path: "/org", + ...opts, + }); + }, + listRoles({ + orgId, ...opts + }) { + return this._makeRequest({ + path: `/org/${orgId}/role`, + ...opts, + }); + }, + listUsers(opts = {}) { + return this._makeRequest({ + path: "/user", + ...opts, + }); + }, + async getEmployeeRoleId({ + orgId, ...opts + }) { + const { data } = await this.listRoles({ + orgId, + ...opts, + }); + const employeeRole = data.filter(({ label }) => label === "Employee"); + return employeeRole.id; + }, // Event: Emit New Employee Added Event async emitNewEmployeeAddedEvent(opts = {}) { const data = {}; @@ -154,7 +255,7 @@ export default { return this._makeRequest({ method: "POST", path: "/events/new-employee-added", - data, + ...opts, }); }, // Event: Emit Compensation Updated Event @@ -165,7 +266,7 @@ export default { return this._makeRequest({ method: "POST", path: "/events/compensation-updated", - data, + ...opts, }); }, // Event: Emit Organizational Structure Changed Event @@ -176,42 +277,31 @@ export default { return this._makeRequest({ method: "POST", path: "/events/org-structure-changed", - data, + ...opts, }); }, - - // Action: Add New Employee - async addEmployee(opts = {}) { - const data = { - name: this.addEmployeeName, - email: this.addEmployeeEmail, - role: this.addEmployeeRole, - }; - if (this.addEmployeeStartDate) data.start_date = this.addEmployeeStartDate; - if (this.addEmployeeDepartment) data.department = this.addEmployeeDepartment; - if (this.addEmployeeCustomFields) { - data.custom_fields = this.addEmployeeCustomFields.map((field) => JSON.parse(field)); - } + getUser({ + userId, ...opts + }) { + return this._makeRequest({ + path: `/user/${userId}`, + ...opts, + }); + }, + createUser(opts = {}) { return this._makeRequest({ method: "POST", - path: "/employees", - data, + path: "/user", + ...opts, }); }, - - // Action: Update Employee Profile - async updateEmployeeProfile(opts = {}) { - const data = {}; - if (this.updateFields) { - data.fields_to_update = this.updateFields.map((field) => JSON.parse(field)); - } - if (this.updateMetadata) { - data.metadata = JSON.parse(this.updateMetadata); - } + updateUser({ + userId, ...opts + }) { return this._makeRequest({ - method: "PUT", - path: `/employees/${this.updateEmployeeId}`, - data, + method: "PATCH", + path: `/user/${userId}`, + ...opts, }); }, @@ -230,7 +320,7 @@ export default { return this._makeRequest({ method: "PUT", path: `/employees/${this.modifyCompensationEmployeeId}/compensation`, - data, + ...opts, }); }, }, diff --git a/components/charthop/package.json b/components/charthop/package.json index 24879cd5541dd..5c52feeacd438 100644 --- a/components/charthop/package.json +++ b/components/charthop/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/charthop", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream ChartHop Components", "main": "charthop.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/components/charthop/sources/common/base.mjs b/components/charthop/sources/common/base.mjs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs b/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs index 4561411e3739c..6770c08ffeb10 100644 --- a/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs +++ b/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs @@ -1,5 +1,4 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; import crypto from "crypto"; export default { @@ -10,10 +9,7 @@ export default { type: "source", dedupe: "unique", props: { - charthop: { - type: "app", - app: "charthop", - }, + charthop, db: "$.service.db", http: { type: "$.interface.http", diff --git a/components/charthop/sources/new-employee-instant/new-employee-instant.mjs b/components/charthop/sources/new-employee-instant/new-employee-instant.mjs index 49a043b2899a2..04f756a9614ad 100644 --- a/components/charthop/sources/new-employee-instant/new-employee-instant.mjs +++ b/components/charthop/sources/new-employee-instant/new-employee-instant.mjs @@ -1,5 +1,4 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; import crypto from "crypto"; export default { diff --git a/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs b/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs index 06f56297810d9..840b48a366070 100644 --- a/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs +++ b/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs @@ -1,5 +1,4 @@ import charthop from "../../charthop.app.mjs"; -import { axios } from "@pipedream/platform"; import crypto from "crypto"; export default { @@ -10,10 +9,7 @@ export default { type: "source", dedupe: "unique", props: { - charthop: { - type: "app", - app: "charthop", - }, + charthop, http: { type: "$.interface.http", customResponse: true, From 0891f82fe711305fa3ae02d0fe8304d33f9e4331 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Fri, 24 Jan 2025 15:54:07 -0500 Subject: [PATCH 3/8] pnpm-lock.yaml --- pnpm-lock.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3183cb0fdb21a..b2a316ce9c65f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1713,7 +1713,11 @@ importers: specifier: ^3.0.3 version: 3.0.3 - components/charthop: {} + components/charthop: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/chartmogul: dependencies: @@ -9279,8 +9283,7 @@ importers: specifier: 3.0.1 version: 3.0.1 - components/seen: - specifiers: {} + components/seen: {} components/segment: dependencies: From 385452b7528ee717297361b044d535a388d7b7cf Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 11 Mar 2025 10:47:37 -0400 Subject: [PATCH 4/8] wip --- .../create-employee/create-employee.mjs | 79 ++---- .../update-employee-details.mjs | 104 ++++---- components/charthop/charthop.app.mjs | 228 ++---------------- components/charthop/common/utils.mjs | 17 ++ 4 files changed, 106 insertions(+), 322 deletions(-) create mode 100644 components/charthop/common/utils.mjs diff --git a/components/charthop/actions/create-employee/create-employee.mjs b/components/charthop/actions/create-employee/create-employee.mjs index 8a0a14afbe678..cecf98acb3cb5 100644 --- a/components/charthop/actions/create-employee/create-employee.mjs +++ b/components/charthop/actions/create-employee/create-employee.mjs @@ -1,10 +1,11 @@ import charthop from "../../charthop.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; export default { key: "charthop-create-employee", name: "Create Employee", - description: "Adds a new employee to the system. [See the documentation](https://api.charthop.com/swagger#/user/createUser)", - version: "0.0.{{ts}}", + description: "Adds a new employee to the system. [See the documentation](https://api.charthop.com/swagger#/person/createPerson)", + version: "0.0.1", type: "action", props: { charthop, @@ -14,70 +15,32 @@ export default { "orgId", ], }, - firstName: { - propDefinition: [ - charthop, - "firstName", - ], - }, - middleName: { - propDefinition: [ - charthop, - "middleName", - ], - }, - lastName: { - propDefinition: [ - charthop, - "lastName", - ], - }, - preferredFirstName: { - propDefinition: [ - charthop, - "preferredFirstName", - ], - }, - preferredLastName: { - propDefinition: [ - charthop, - "preferredLastName", - ], - }, - email: { - propDefinition: [ - charthop, - "email", - ], + name: { + type: "string", + label: "Name", + description: "Name of the employee", }, - status: { - propDefinition: [ - charthop, - "status", - ], + additionalProperties: { + type: "object", + label: "Additional Properties", + description: "Additional properties to add to the employee", + optional: true, }, }, async run({ $ }) { - const response = await this.charthop.createUser({ + const additionalProperties = this.additionalProperties + ? parseObject(this.additionalProperties) + : {}; + + const response = await this.charthop.createPerson({ $, + orgId: this.orgId, data: { - orgs: [ - { - orgId: this.orgId, - access: "MEMBER", - roleId: await this.charthop.getEmployeeRoleId($), - }, - ], - name: { - first: this.firstName, - middle: this.middleName, - last: this.lastName, - pref: this.preferredFirstName, - prefLast: this.preferredLastName, - }, - email: this.email, + name: this.name, + ...additionalProperties, }, }); + $.export("$summary", `Successfully created employee with ID: ${response.id}`); return response; }, diff --git a/components/charthop/actions/update-employee-details/update-employee-details.mjs b/components/charthop/actions/update-employee-details/update-employee-details.mjs index 8d134eac77d2c..a39b5c3e13f42 100644 --- a/components/charthop/actions/update-employee-details/update-employee-details.mjs +++ b/components/charthop/actions/update-employee-details/update-employee-details.mjs @@ -4,7 +4,7 @@ export default { key: "charthop-update-employee-details", name: "Update Employee Details", description: "Updates an existing employee's details. [See the documentation](https://api.charthop.com/swagger#/user/updateUser)", - version: "0.0.{{ts}}", + version: "0.0.1", type: "action", props: { charthop, @@ -22,75 +22,55 @@ export default { orgId: c.orgId, }), ], - }, - firstName: { - propDefinition: [ - charthop, - "firstName", - ], - optional: true, - }, - middleName: { - propDefinition: [ - charthop, - "middleName", - ], - }, - lastName: { - propDefinition: [ - charthop, - "lastName", - ], - optional: true, - }, - preferredFirstName: { - propDefinition: [ - charthop, - "preferredFirstName", - ], - }, - preferredLastName: { - propDefinition: [ - charthop, - "preferredLastName", - ], - }, - email: { - propDefinition: [ - charthop, - "email", - ], - optional: true, - }, - status: { - propDefinition: [ - charthop, - "status", - ], + reloadProps: true, }, }, + async additionalProps() { + const props = {}; + if (!this.employeeId || !this.orgId) { + return props; + } + + const employee = await this.charthop.getPerson({ + orgId: this.orgId, + personId: this.employeeId, + }); + + for (const [ + key, + value, + ] of Object.entries(employee)) { + if (key === "id") { + continue; + } + props[key] = { + type: "string", + label: `${key}`, + default: key === "name" + ? (`${value?.first} ${value?.last}`).trim() + : `${value}`, + }; + } + + return props; + }, async run({ $ }) { const { - name, email, - } = await this.charthop.getUser({ - $, - userId: this.employeeId, - }); - const response = await this.charthop.updateUser({ + charthop, + orgId, + employeeId, + ...fields + } = this; + + const response = await charthop.updatePerson({ $, - userId: this.employeeId, + orgId, + personId: employeeId, data: { - name: { - first: this.firstName || name.first, - middle: this.middleName || name.middle, - last: this.lastName || name.last, - pref: this.preferredFirstName || name.pref, - prefLast: this.preferredLastName || name.prefLast, - }, - email: this.email || email, + ...fields, }, }); - $.export("$summary", `Successfully updated employee with ID ${this.employeeId}`); + $.export("$summary", `Successfully updated employee with ID ${employeeId}`); return response; }, }; diff --git a/components/charthop/charthop.app.mjs b/components/charthop/charthop.app.mjs index 6683dfa6ddef6..6290b6d3a82b7 100644 --- a/components/charthop/charthop.app.mjs +++ b/components/charthop/charthop.app.mjs @@ -17,12 +17,12 @@ export default { const { data } = await this.listOrgs({ params, }); - const options = data.map(({ + const options = data?.map(({ id: value, name: label, }) => ({ value, label, - })); + })) || []; return { options, context: { @@ -38,32 +38,24 @@ export default { async options({ orgId, prevContext, }) { - const params = prevContext?.from - ? { - from: prevContext.from, - } - : {}; - const { data } = await this.listUsers({ + const params = { + includeAll: true, + }; + if (prevContext?.from) { + params.from = prevContext.from; + } + const { data } = await this.listPersons({ + orgId, params: { ...params, - orgId, }, }); - const employees = []; - const employeeRoleId = await this.getEmployeeRoleId({ - orgId, - }); - for (const user of data) { - if (user.orgs.find((u) => u.orgId === orgId && u.roleId === employeeRoleId)) { - employees.push(user); - } - } - const options = employees.map(({ + const options = data?.map(({ id: value, name, }) => ({ value, - label: (`${name.first} ${name.last}`).trim(), - })); + label: (`${name?.first} ${name?.last}`).trim(), + })) || []; return { options, context: { @@ -72,108 +64,6 @@ export default { }; }, }, - firstName: { - type: "string", - label: "First Name", - description: "First name of the employee", - }, - middleName: { - type: "string", - label: "Middle Name", - description: "Middle name of the employee", - optional: true, - }, - lastName: { - type: "string", - label: "Last Name", - description: "Last name of the employee", - }, - preferredFirstName: { - type: "string", - label: "Preferred First Name", - description: "The preferred first name of the employee", - optional: true, - }, - preferredLastName: { - type: "string", - label: "Preferred Last Name", - description: "The preferred last name of the employee", - optional: true, - }, - email: { - type: "string", - label: "Email", - description: "Email address of the employee", - }, - status: { - type: "string", - label: "Status", - description: "The status of the emaployee", - options: [ - "SUPERUSER", - "NORMAL", - "INACTIVE", - "UNINSTALLED", - ], - optional: true, - }, - // Event Filters for New Employee Added - newEmployeeDepartmentFilter: { - type: "string", - label: "Department Filter", - description: "Optional department filter for new employee events.", - optional: true, - }, - newEmployeeRoleFilter: { - type: "string", - label: "Role Filter", - description: "Optional role filter for new employee events.", - optional: true, - }, - // Event Filters for Compensation Details Updated - compensationDepartmentFilter: { - type: "string", - label: "Department Filter", - description: "Optional department filter for compensation update events.", - optional: true, - }, - compensationEmployeeIdFilter: { - type: "string", - label: "Employee ID Filter", - description: "Optional employee ID filter for compensation update events.", - optional: true, - }, - // Event Filters for Organizational Structure Changes - orgStructureTeamFilter: { - type: "string", - label: "Team Filter", - description: "Optional team filter for organizational structure change events.", - optional: true, - }, - orgStructureDivisionFilter: { - type: "string", - label: "Division Filter", - description: "Optional division filter for organizational structure change events.", - optional: true, - }, - - // Action: Update Employee Profile - updateEmployeeId: { - type: "string", - label: "Employee ID", - description: "ID of the employee to update.", - }, - updateFields: { - type: "string[]", - label: "Fields to Update", - description: "Fields to update in the employee profile. Provide as JSON strings.", - }, - updateMetadata: { - type: "string", - label: "Metadata", - description: "Optional metadata for the employee update. Provide as a JSON string.", - optional: true, - }, // Action: Modify Compensation Records modifyCompensationEmployeeId: { @@ -201,7 +91,7 @@ export default { }, methods: { _baseUrl() { - return "https://api.charthop.com/v1"; + return "https://api.charthop.com"; }, _makeRequest({ $ = this, @@ -219,107 +109,41 @@ export default { }, listOrgs(opts = {}) { return this._makeRequest({ - path: "/org", + path: "/v1/org", ...opts, }); }, - listRoles({ + listPersons({ orgId, ...opts }) { return this._makeRequest({ - path: `/org/${orgId}/role`, - ...opts, - }); - }, - listUsers(opts = {}) { - return this._makeRequest({ - path: "/user", + path: `/v2/org/${orgId}/person`, ...opts, }); }, - async getEmployeeRoleId({ - orgId, ...opts + getPerson({ + orgId, personId, ...opts }) { - const { data } = await this.listRoles({ - orgId, - ...opts, - }); - const employeeRole = data.filter(({ label }) => label === "Employee"); - return employeeRole.id; - }, - // Event: Emit New Employee Added Event - async emitNewEmployeeAddedEvent(opts = {}) { - const data = {}; - if (this.newEmployeeDepartmentFilter) data.department = this.newEmployeeDepartmentFilter; - if (this.newEmployeeRoleFilter) data.role = this.newEmployeeRoleFilter; return this._makeRequest({ - method: "POST", - path: "/events/new-employee-added", + path: `/v2/org/${orgId}/person/${personId}`, ...opts, }); }, - // Event: Emit Compensation Updated Event - async emitCompensationUpdatedEvent(opts = {}) { - const data = {}; - if (this.compensationDepartmentFilter) data.department = this.compensationDepartmentFilter; - if (this.compensationEmployeeIdFilter) data.employee_id = this.compensationEmployeeIdFilter; - return this._makeRequest({ - method: "POST", - path: "/events/compensation-updated", - ...opts, - }); - }, - // Event: Emit Organizational Structure Changed Event - async emitOrgStructureChangedEvent(opts = {}) { - const data = {}; - if (this.orgStructureTeamFilter) data.team = this.orgStructureTeamFilter; - if (this.orgStructureDivisionFilter) data.division = this.orgStructureDivisionFilter; - return this._makeRequest({ - method: "POST", - path: "/events/org-structure-changed", - ...opts, - }); - }, - getUser({ - userId, ...opts + createPerson({ + orgId, ...opts }) { - return this._makeRequest({ - path: `/user/${userId}`, - ...opts, - }); - }, - createUser(opts = {}) { return this._makeRequest({ method: "POST", - path: "/user", + path: `/v2/org/${orgId}/person`, ...opts, }); }, - updateUser({ - userId, ...opts + updatePerson({ + orgId, personId, ...opts }) { return this._makeRequest({ method: "PATCH", - path: `/user/${userId}`, - ...opts, - }); - }, - - // Action: Modify Compensation Records - async modifyCompensation(opts = {}) { - const data = {}; - if (this.modifyCompensationDetails) { - data.compensation_details = JSON.parse(this.modifyCompensationDetails); - } - if (this.modifyCompensationEffectiveDate) { - data.effective_date = this.modifyCompensationEffectiveDate; - } - if (this.modifyCompensationReason) { - data.reason = this.modifyCompensationReason; - } - return this._makeRequest({ - method: "PUT", - path: `/employees/${this.modifyCompensationEmployeeId}/compensation`, + path: `/v2/org/${orgId}/person/${personId}`, ...opts, }); }, diff --git a/components/charthop/common/utils.mjs b/components/charthop/common/utils.mjs new file mode 100644 index 0000000000000..6489741fadd51 --- /dev/null +++ b/components/charthop/common/utils.mjs @@ -0,0 +1,17 @@ +function parseObject(obj) { + if (!obj) { + return undefined; + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch { + return obj; + } + } + return obj; +} + +export { + parseObject, +}; From f010ed1bc705d73e12e658d4e724c086c81374c4 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 11 Mar 2025 16:33:33 -0400 Subject: [PATCH 5/8] new components --- .../record-compensation-change.mjs | 49 -------- .../search-organization.mjs | 36 ++++++ .../update-employee-details.mjs | 9 +- components/charthop/charthop.app.mjs | 107 ++++++++++++---- components/charthop/sources/common/base.mjs | 93 ++++++++++++++ .../new-compensation-change-instant.mjs | 117 ----------------- .../new-employee-created.mjs | 28 +++++ .../new-employee-instant.mjs | 118 ------------------ .../new-group-created/new-group-created.mjs | 38 ++++++ .../new-job-created/new-job-created.mjs | 20 +++ .../new-org-change-instant.mjs | 102 --------------- 11 files changed, 308 insertions(+), 409 deletions(-) delete mode 100644 components/charthop/actions/record-compensation-change/record-compensation-change.mjs create mode 100644 components/charthop/actions/search-organization/search-organization.mjs delete mode 100644 components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs create mode 100644 components/charthop/sources/new-employee-created/new-employee-created.mjs delete mode 100644 components/charthop/sources/new-employee-instant/new-employee-instant.mjs create mode 100644 components/charthop/sources/new-group-created/new-group-created.mjs create mode 100644 components/charthop/sources/new-job-created/new-job-created.mjs delete mode 100644 components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs diff --git a/components/charthop/actions/record-compensation-change/record-compensation-change.mjs b/components/charthop/actions/record-compensation-change/record-compensation-change.mjs deleted file mode 100644 index c2e39b5ff3dbe..0000000000000 --- a/components/charthop/actions/record-compensation-change/record-compensation-change.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import charthop from "../../charthop.app.mjs"; - -export default { - key: "charthop-record-compensation-change", - name: "Record Compensation Change", - description: "Logs or modifies an employee's compensation records, such as salary increases, bonuses, or equity grants. [See the documentation]()", - version: "0.0.{{ts}}", - type: "action", - props: { - charthop, - employeeId: { - propDefinition: [ - charthop, - "modifyCompensationEmployeeId", - ], - }, - compensationDetails: { - propDefinition: [ - charthop, - "modifyCompensationDetails", - ], - }, - effectiveDate: { - propDefinition: [ - charthop, - "modifyCompensationEffectiveDate", - ], - optional: true, - }, - reason: { - propDefinition: [ - charthop, - "modifyCompensationReason", - ], - optional: true, - }, - }, - async run({ $ }) { - const response = await this.charthop.modifyCompensation(); - const summaryParts = [ - `Compensation for employee ID ${this.employeeId} has been updated`, - ]; - if (this.reason) { - summaryParts.push(`for reason: ${this.reason}`); - } - $.export("$summary", summaryParts.join(" ") + "."); - return response; - }, -}; diff --git a/components/charthop/actions/search-organization/search-organization.mjs b/components/charthop/actions/search-organization/search-organization.mjs new file mode 100644 index 0000000000000..e5758c381121f --- /dev/null +++ b/components/charthop/actions/search-organization/search-organization.mjs @@ -0,0 +1,36 @@ +import charthop from "../../charthop.app.mjs"; + +export default { + key: "charthop-search-organization", + name: "Search Organization", + description: "Return people, job, group, and field data for a particular org that match a provided search string. [See the documentation](https://api.charthop.com/swagger#/search/searchOrgData)", + version: "0.0.1", + type: "action", + props: { + charthop, + orgId: { + propDefinition: [ + charthop, + "orgId", + ], + }, + q: { + type: "string", + label: "Query", + description: "The search query", + }, + }, + async run({ $ }) { + const response = await this.charthop.searchOrganization({ + $, + orgId: this.orgId, + params: { + q: this.q, + includeFormer: true, + }, + }); + + $.export("$summary", "Successfully completed search query"); + return response; + }, +}; diff --git a/components/charthop/actions/update-employee-details/update-employee-details.mjs b/components/charthop/actions/update-employee-details/update-employee-details.mjs index a39b5c3e13f42..356e17917b530 100644 --- a/components/charthop/actions/update-employee-details/update-employee-details.mjs +++ b/components/charthop/actions/update-employee-details/update-employee-details.mjs @@ -62,7 +62,7 @@ export default { ...fields } = this; - const response = await charthop.updatePerson({ + await charthop.updatePerson({ $, orgId, personId: employeeId, @@ -70,6 +70,13 @@ export default { ...fields, }, }); + + const response = await charthop.getPerson({ + $, + orgId, + personId: employeeId, + }); + $.export("$summary", `Successfully updated employee with ID ${employeeId}`); return response; }, diff --git a/components/charthop/charthop.app.mjs b/components/charthop/charthop.app.mjs index 6290b6d3a82b7..18c4d6ba8f9ea 100644 --- a/components/charthop/charthop.app.mjs +++ b/components/charthop/charthop.app.mjs @@ -64,29 +64,38 @@ export default { }; }, }, - - // Action: Modify Compensation Records - modifyCompensationEmployeeId: { - type: "string", - label: "Employee ID", - description: "ID of the employee for compensation update.", - }, - modifyCompensationDetails: { - type: "string", - label: "Compensation Details", - description: "Details of the compensation update. Provide as a JSON string.", - }, - modifyCompensationEffectiveDate: { - type: "string", - label: "Effective Date", - description: "Optional effective date for the compensation update.", - optional: true, - }, - modifyCompensationReason: { + groupTypeId: { type: "string", - label: "Reason for Change", - description: "Optional reason for the compensation update.", - optional: true, + label: "Group Type ID", + description: "The identifier of a group type", + async options({ + orgId, prevContext, + }) { + const params = { + includeAll: true, + }; + if (prevContext?.from) { + params.from = prevContext.from; + } + const { data } = await this.listGroupTypes({ + orgId, + params: { + ...params, + }, + }); + const options = data?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + return { + options, + context: { + from: data[data.length - 1].id, + }, + }; + }, }, }, methods: { @@ -121,6 +130,30 @@ export default { ...opts, }); }, + listJobs({ + orgId, ...opts + }) { + return this._makeRequest({ + path: `/v2/org/${orgId}/job`, + ...opts, + }); + }, + listGroupTypes({ + orgId, ...opts + }) { + return this._makeRequest({ + path: `/v1/org/${orgId}/group-type`, + ...opts, + }); + }, + listGroups({ + orgId, type, ...opts + }) { + return this._makeRequest({ + path: `/v2/org/${orgId}/group/${type}`, + ...opts, + }); + }, getPerson({ orgId, personId, ...opts }) { @@ -147,5 +180,35 @@ export default { ...opts, }); }, + searchOrganization({ + orgId, ...opts + }) { + return this._makeRequest({ + path: `/v1/org/${orgId}/search`, + ...opts, + }); + }, + async *paginate({ + resourceFn, + args, + max, + }) { + let count = 0; + do { + const { + data, next, + } = await resourceFn(args); + for (const item of data) { + yield item; + if (max && ++count >= max) { + return; + } + args.params = { + ...args.params, + from: next, + }; + } + } while (args.params?.next); + }, }, }; diff --git a/components/charthop/sources/common/base.mjs b/components/charthop/sources/common/base.mjs index e69de29bb2d1d..5969897db2045 100644 --- a/components/charthop/sources/common/base.mjs +++ b/components/charthop/sources/common/base.mjs @@ -0,0 +1,93 @@ +import charthop from "../../charthop.app.mjs"; +import { + ConfigurationError, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, +} from "@pipedream/platform"; + +export default { + props: { + charthop, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + orgId: { + propDefinition: [ + charthop, + "orgId", + ], + }, + }, + methods: { + _getLastId() { + return this.db.get("lastId"); + }, + _setLastId(lastId) { + this.db.set("lastId", lastId); + }, + generateMeta(item) { + return { + id: item.id, + summary: this.getSummary(item), + ts: Date.now(), + }; + }, + emitEvents(items) { + items.forEach((item) => { + const meta = this.generateMeta(item); + this.$emit(item, meta); + }); + }, + getArgs() { + return { + orgId: this.orgId, + }; + }, + async getResults() { + const lastId = this._getLastId(); + const resourceFn = this.getResourceFn(); + const args = this.getArgs(); + + if (lastId) { + args.params = { + ...args.params, + from: lastId, + }; + } + + const items = this.charthop.paginate({ + resourceFn, + args, + }); + + const results = []; + for await (const item of items) { + results.push(item); + } + + if (results.length) { + this._setLastId(results[results.length - 1].id); + } + + return results; + }, + getResourceFn() { + throw new ConfigurationError("getResourceFn is not implemented"); + }, + getSummary() { + throw new ConfigurationError("getSummary is not implemented"); + }, + }, + hooks: { + async deploy() { + const results = await this.getResults(); + this.emitEvents(results.slice(-25)); + }, + }, + async run() { + const results = await this.getResults(); + this.emitEvents(results); + }, +}; diff --git a/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs b/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs deleted file mode 100644 index 6770c08ffeb10..0000000000000 --- a/components/charthop/sources/new-compensation-change-instant/new-compensation-change-instant.mjs +++ /dev/null @@ -1,117 +0,0 @@ -import charthop from "../../charthop.app.mjs"; -import crypto from "crypto"; - -export default { - key: "charthop-new-compensation-change-instant", - name: "New Compensation Change (Instant)", - description: "Emit new event when an employee's compensation details are updated. [See the documentation]()", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - charthop, - db: "$.service.db", - http: { - type: "$.interface.http", - customResponse: true, - }, - compensationDepartmentFilter: { - propDefinition: [ - "charthop", - "compensationDepartmentFilter", - ], - optional: true, - }, - compensationEmployeeIdFilter: { - propDefinition: [ - "charthop", - "compensationEmployeeIdFilter", - ], - optional: true, - }, - }, - hooks: { - async deploy() { - const params = { - limit: 50, - sort: "desc", - }; - if (this.compensationDepartmentFilter) { - params.department = this.compensationDepartmentFilter; - } - if (this.compensationEmployeeIdFilter) { - params.employee_id = this.compensationEmployeeIdFilter; - } - const events = await this.charthop._makeRequest({ - method: "GET", - path: "/compensation-updates", - params, - }); - - const sortedEvents = events.sort((a, b) => new Date(a.updated_at) - new Date(b.updated_at)); - for (const event of sortedEvents) { - this.$emit(event, { - id: event.id || event.updated_at, - summary: `Compensation updated for employee ID ${event.employee_id}`, - ts: Date.parse(event.updated_at) || Date.now(), - }); - } - }, - async activate() { - const webhookData = { - event: "compensation_updated", - callback_url: this.http.endpoint, - filters: {}, - }; - if (this.compensationDepartmentFilter) { - webhookData.filters.department = this.compensationDepartmentFilter; - } - if (this.compensationEmployeeIdFilter) { - webhookData.filters.employee_id = this.compensationEmployeeIdFilter; - } - const response = await this.charthop._makeRequest({ - method: "POST", - path: "/webhooks", - data: webhookData, - }); - await this.db.set("webhookId", response.id); - }, - async deactivate() { - const webhookId = await this.db.get("webhookId"); - if (webhookId) { - await this.charthop._makeRequest({ - method: "DELETE", - path: `/webhooks/${webhookId}`, - }); - await this.db.delete("webhookId"); - } - }, - }, - async run(event) { - const signature = event.headers["x-charthop-signature"]; - const secretKey = this.charthop.$auth.secret_key; - const computedSignature = crypto - .createHmac("sha256", secretKey) - .update(event.rawBody) - .digest("base64"); - if (computedSignature !== signature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - const data = event.body; - this.$emit(data, { - id: data.id || data.updated_at, - summary: `Compensation updated for employee ID ${data.employee_id}`, - ts: data.updated_at - ? Date.parse(data.updated_at) - : Date.now(), - }); - this.http.respond({ - status: 200, - body: "OK", - }); - }, -}; diff --git a/components/charthop/sources/new-employee-created/new-employee-created.mjs b/components/charthop/sources/new-employee-created/new-employee-created.mjs new file mode 100644 index 0000000000000..95a5ec6ddf9dc --- /dev/null +++ b/components/charthop/sources/new-employee-created/new-employee-created.mjs @@ -0,0 +1,28 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "charthop-new-employee-created", + name: "New Employee Created", + description: "Emit new event when a new employee is added to the organization. [See the documentation](https://api.charthop.com/swagger#/person/findPersons)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.charthop.listPersons; + }, + getArgs() { + return { + orgId: this.orgId, + params: { + includeAll: true, + }, + }; + }, + getSummary(item) { + return `New Employee: ${item.id}`; + }, + }, +}; diff --git a/components/charthop/sources/new-employee-instant/new-employee-instant.mjs b/components/charthop/sources/new-employee-instant/new-employee-instant.mjs deleted file mode 100644 index 04f756a9614ad..0000000000000 --- a/components/charthop/sources/new-employee-instant/new-employee-instant.mjs +++ /dev/null @@ -1,118 +0,0 @@ -import charthop from "../../charthop.app.mjs"; -import crypto from "crypto"; - -export default { - key: "charthop-new-employee-instant", - name: "New Employee Added", - description: "Emit new event when a new employee is added to the organization. [See the documentation]()", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - charthop, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", - newEmployeeDepartmentFilter: { - propDefinition: [ - charthop, - "newEmployeeDepartmentFilter", - ], - }, - newEmployeeRoleFilter: { - propDefinition: [ - charthop, - "newEmployeeRoleFilter", - ], - }, - }, - hooks: { - async activate() { - const webhookUrl = this.http.endpoint; - const data = { - webhook_url: webhookUrl, - }; - if (this.newEmployeeDepartmentFilter) { - data.department = this.newEmployeeDepartmentFilter; - } - if (this.newEmployeeRoleFilter) { - data.role = this.newEmployeeRoleFilter; - } - const response = await this.charthop.emitNewEmployeeAddedEvent(data); - if (response.id) { - await this.db.set("webhookId", response.id); - } - }, - async deactivate() { - const webhookId = await this.db.get("webhookId"); - if (webhookId) { - await this.charthop._makeRequest({ - method: "DELETE", - path: `/webhooks/${webhookId}`, - }); - await this.db.set("webhookId", null); - } - }, - async deploy() { - const filters = {}; - if (this.newEmployeeDepartmentFilter) { - filters.department = this.newEmployeeDepartmentFilter; - } - if (this.newEmployeeRoleFilter) { - filters.role = this.newEmployeeRoleFilter; - } - const events = await this.charthop._makeRequest({ - method: "GET", - path: "/events/new_employee_added", - params: { - limit: 50, - ...filters, - }, - }); - for (const event of events.reverse()) { - this.$emit(event, { - id: event.id || event.created_at, - summary: `New employee added: ${event.name}`, - ts: Date.parse(event.created_at) || Date.now(), - }); - } - }, - }, - async run(event) { - const receivedSignature = event.headers["x-charthop-signature"]; - const secret = this.charthop.$auth.api_token; - const computedSignature = crypto - .createHmac("sha256", secret) - .update(event.body) - .digest("hex"); - if (computedSignature !== receivedSignature) { - await this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - - const data = JSON.parse(event.body); - if ( - this.newEmployeeDepartmentFilter && - data.department !== this.newEmployeeDepartmentFilter - ) { - return; - } - if ( - this.newEmployeeRoleFilter && - data.role !== this.newEmployeeRoleFilter - ) { - return; - } - - this.$emit(data, { - id: data.id || data.created_at, - summary: `New employee added: ${data.name}`, - ts: Date.parse(data.created_at) || Date.now(), - }); - }, -}; diff --git a/components/charthop/sources/new-group-created/new-group-created.mjs b/components/charthop/sources/new-group-created/new-group-created.mjs new file mode 100644 index 0000000000000..9b14193648c64 --- /dev/null +++ b/components/charthop/sources/new-group-created/new-group-created.mjs @@ -0,0 +1,38 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "charthop-new-group-created", + name: "New Group Created", + description: "Emit new event when a new group is added to the organization. [See the documentation](https://api.charthop.com/swagger#/group/findGroups)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + ...common.props, + groupTypeId: { + propDefinition: [ + common.props.charthop, + "groupTypeId", + (c) => ({ + orgId: c.orgId, + }), + ], + }, + }, + methods: { + ...common.methods, + getResourceFn() { + return this.charthop.listJobs; + }, + getArgs() { + return { + orgId: this.orgId, + type: this.groupTypeId, + }; + }, + getSummary(item) { + return `New Group: ${item.id}`; + }, + }, +}; diff --git a/components/charthop/sources/new-job-created/new-job-created.mjs b/components/charthop/sources/new-job-created/new-job-created.mjs new file mode 100644 index 0000000000000..d99bc1e3e8c89 --- /dev/null +++ b/components/charthop/sources/new-job-created/new-job-created.mjs @@ -0,0 +1,20 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "charthop-new-job-created", + name: "New Job Created", + description: "Emit new event when a new job is added to the organization. [See the documentation](https://api.charthop.com/swagger#/job/findJobs)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.charthop.listJobs; + }, + getSummary(item) { + return `New Job: ${item.id}`; + }, + }, +}; diff --git a/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs b/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs deleted file mode 100644 index 840b48a366070..0000000000000 --- a/components/charthop/sources/new-org-change-instant/new-org-change-instant.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import charthop from "../../charthop.app.mjs"; -import crypto from "crypto"; - -export default { - key: "charthop-new-org-change-instant", - name: "New Organizational Structure Change (Instant)", - description: "Emit new events when there are changes to the organizational structure, such as team reassignments or role updates. [See the documentation]()", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - charthop, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", - orgStructureTeamFilter: { - propDefinition: [ - "charthop", - "orgStructureTeamFilter", - ], - optional: true, - }, - orgStructureDivisionFilter: { - propDefinition: [ - "charthop", - "orgStructureDivisionFilter", - ], - optional: true, - }, - }, - hooks: { - async deploy() { - const params = {}; - if (this.orgStructureTeamFilter) params.team = this.orgStructureTeamFilter; - if (this.orgStructureDivisionFilter) params.division = this.orgStructureDivisionFilter; - const recentEvents = await this.charthop.emitOrgStructureChangedEvent({ - data: params, - paginate: true, - max: 50, - }); - const events = recentEvents.events || []; - for (const event of events.slice(-50)) { - this.$emit(event, { - id: event.id || event.ts.toString(), - summary: `Organizational structure change in ${event.team || "unknown team"}`, - ts: event.ts - ? Date.parse(event.ts) - : Date.now(), - }); - } - }, - async activate() { - const webhookUrl = this.http.endpoint; - const webhookResponse = await this.charthop.createWebhook({ - event: "org_structure_changed", - url: webhookUrl, - team: this.orgStructureTeamFilter, - division: this.orgStructureDivisionFilter, - }); - await this.db.set("webhookId", webhookResponse.id); - }, - async deactivate() { - const webhookId = await this.db.get("webhookId"); - if (webhookId) { - await this.charthop.deleteWebhook(webhookId); - await this.db.delete("webhookId"); - } - }, - }, - async run(event) { - const secret = this.charthop.$auth.webhook_secret; - const signature = event.headers["x-charthop-signature"]; - const rawBody = await this.http.rawBody; - - const computedSignature = crypto - .createHmac("sha256", secret) - .update(rawBody) - .digest("base64"); - - if (computedSignature !== signature) { - this.http.respond({ - status: 401, - body: "Unauthorized", - }); - return; - } - - const eventData = event.body; - const id = eventData.id || eventData.ts.toString(); - const summary = `Organizational structure change: ${eventData.description || "No description"}`; - const ts = eventData.ts - ? Date.parse(eventData.ts) - : Date.now(); - this.$emit(eventData, { - id, - summary, - ts, - }); - }, -}; From 52f29e7a2c573ac4ae3c9b38b6d62232774ec4f9 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 11 Mar 2025 16:35:27 -0400 Subject: [PATCH 6/8] pnpm-lock.yaml --- pnpm-lock.yaml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2a316ce9c65f..7897d0b82a193 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14106,12 +14106,12 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@definitelytyped/header-parser@0.2.16': - resolution: {integrity: sha512-UFsgPft5bhZn07UNGz/9ck4AhdKgLFEOmi2DNr7gXcGL89zbe3u5oVafKUT8j1HOtSBjT8ZEQsXHKlbq+wwF/Q==} + '@definitelytyped/header-parser@0.2.17': + resolution: {integrity: sha512-U0juKFkTOcbkSfO83WSzMEJHYDwoBFiq0tf/JszulL3+7UoSiqunpGmxXS54bm3eGqy7GWjV8AqPQHdeoEaWBQ==} engines: {node: '>=18.18.0'} - '@definitelytyped/typescript-versions@0.1.6': - resolution: {integrity: sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==} + '@definitelytyped/typescript-versions@0.1.7': + resolution: {integrity: sha512-sBzBi1SBn79OkSr8V0H+FzR7QumHk23syPyRxod/VRBrSkgN9rCliIe+nqLoWRAKN8EeKbp00ketnJNLZhucdA==} engines: {node: '>=18.18.0'} '@definitelytyped/utils@0.1.8': @@ -22148,6 +22148,7 @@ packages: lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. lodash.has@4.5.2: resolution: {integrity: sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==} @@ -29558,13 +29559,13 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@definitelytyped/header-parser@0.2.16': + '@definitelytyped/header-parser@0.2.17': dependencies: - '@definitelytyped/typescript-versions': 0.1.6 + '@definitelytyped/typescript-versions': 0.1.7 '@definitelytyped/utils': 0.1.8 semver: 7.6.3 - '@definitelytyped/typescript-versions@0.1.6': {} + '@definitelytyped/typescript-versions@0.1.7': {} '@definitelytyped/utils@0.1.8': dependencies: @@ -36079,7 +36080,7 @@ snapshots: dts-critic@3.3.11(typescript@5.7.2): dependencies: - '@definitelytyped/header-parser': 0.2.16 + '@definitelytyped/header-parser': 0.2.17 command-exists: 1.2.9 rimraf: 3.0.2 semver: 6.3.1 @@ -36089,8 +36090,8 @@ snapshots: dtslint@4.2.1(typescript@5.7.2): dependencies: - '@definitelytyped/header-parser': 0.2.16 - '@definitelytyped/typescript-versions': 0.1.6 + '@definitelytyped/header-parser': 0.2.17 + '@definitelytyped/typescript-versions': 0.1.7 '@definitelytyped/utils': 0.1.8 dts-critic: 3.3.11(typescript@5.7.2) fs-extra: 6.0.1 From 91c529e95f3141875c82d99d544e98f91b7ce6fc Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 11 Mar 2025 16:58:37 -0400 Subject: [PATCH 7/8] fixes --- components/charthop/charthop.app.mjs | 2 +- components/charthop/sources/new-job-created/new-job-created.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/charthop/charthop.app.mjs b/components/charthop/charthop.app.mjs index 18c4d6ba8f9ea..7d3993b5f2343 100644 --- a/components/charthop/charthop.app.mjs +++ b/components/charthop/charthop.app.mjs @@ -208,7 +208,7 @@ export default { from: next, }; } - } while (args.params?.next); + } while (args.params?.from); }, }, }; diff --git a/components/charthop/sources/new-job-created/new-job-created.mjs b/components/charthop/sources/new-job-created/new-job-created.mjs index d99bc1e3e8c89..9c571a28d3811 100644 --- a/components/charthop/sources/new-job-created/new-job-created.mjs +++ b/components/charthop/sources/new-job-created/new-job-created.mjs @@ -11,7 +11,7 @@ export default { methods: { ...common.methods, getResourceFn() { - return this.charthop.listJobs; + return this.charthop.listGroups; }, getSummary(item) { return `New Job: ${item.id}`; From 528a1c6335df8a27ff73b28749618d035ffed3d0 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Tue, 11 Mar 2025 17:07:07 -0400 Subject: [PATCH 8/8] fix method names --- .../charthop/sources/new-group-created/new-group-created.mjs | 2 +- components/charthop/sources/new-job-created/new-job-created.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/charthop/sources/new-group-created/new-group-created.mjs b/components/charthop/sources/new-group-created/new-group-created.mjs index 9b14193648c64..3efac1ee46655 100644 --- a/components/charthop/sources/new-group-created/new-group-created.mjs +++ b/components/charthop/sources/new-group-created/new-group-created.mjs @@ -23,7 +23,7 @@ export default { methods: { ...common.methods, getResourceFn() { - return this.charthop.listJobs; + return this.charthop.listGroups; }, getArgs() { return { diff --git a/components/charthop/sources/new-job-created/new-job-created.mjs b/components/charthop/sources/new-job-created/new-job-created.mjs index 9c571a28d3811..d99bc1e3e8c89 100644 --- a/components/charthop/sources/new-job-created/new-job-created.mjs +++ b/components/charthop/sources/new-job-created/new-job-created.mjs @@ -11,7 +11,7 @@ export default { methods: { ...common.methods, getResourceFn() { - return this.charthop.listGroups; + return this.charthop.listJobs; }, getSummary(item) { return `New Job: ${item.id}`;