From 085ed562072c94f21d8c333ad0ee956ea12d220b Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 2 Apr 2025 17:13:42 -0300 Subject: [PATCH 1/8] lucca init --- .../approve-leave-request.mjs | 42 ++++ .../update-user-info/update-user-info.mjs | 210 ++++++++++++++++++ components/lucca/lucca.app.mjs | 145 +++++++++++- components/lucca/package.json | 2 +- .../new-expense-report/new-expense-report.mjs | 69 ++++++ .../new-leave-request/new-leave-request.mjs | 104 +++++++++ .../lucca/sources/new-user/new-user.mjs | 64 ++++++ 7 files changed, 630 insertions(+), 6 deletions(-) create mode 100644 components/lucca/actions/approve-leave-request/approve-leave-request.mjs create mode 100644 components/lucca/actions/update-user-info/update-user-info.mjs create mode 100644 components/lucca/sources/new-expense-report/new-expense-report.mjs create mode 100644 components/lucca/sources/new-leave-request/new-leave-request.mjs create mode 100644 components/lucca/sources/new-user/new-user.mjs diff --git a/components/lucca/actions/approve-leave-request/approve-leave-request.mjs b/components/lucca/actions/approve-leave-request/approve-leave-request.mjs new file mode 100644 index 0000000000000..d5dccb0345686 --- /dev/null +++ b/components/lucca/actions/approve-leave-request/approve-leave-request.mjs @@ -0,0 +1,42 @@ +import lucca from "../../lucca.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "lucca-approve-leave-request", + name: "Approve Leave Request", + description: "Approve a pending leave request. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/approve-or-deny-a-leave-request)", + version: "0.0.{{ts}}", + type: "action", + props: { + lucca, + leaveRequestId: { + propDefinition: [ + lucca, + "leaveRequestId", + ], + }, + approved: { + type: "boolean", + label: "Approved", + description: "Whether the leave request should be approved. Defaults to `true`.", + optional: true, + default: true, + }, + comment: { + type: "string", + label: "Comment", + description: "Optional comment about the approval decision.", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.lucca.approveLeaveRequest({ + leaveRequestId: this.leaveRequestId, + approved: this.approved ?? true, + comment: this.comment || "", + }); + + $.export("$summary", `Leave request ${this.leaveRequestId} was successfully processed.`); + return response; + }, +}; diff --git a/components/lucca/actions/update-user-info/update-user-info.mjs b/components/lucca/actions/update-user-info/update-user-info.mjs new file mode 100644 index 0000000000000..f68028d9e33c2 --- /dev/null +++ b/components/lucca/actions/update-user-info/update-user-info.mjs @@ -0,0 +1,210 @@ +import lucca from "../../lucca.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "lucca-update-user-info", + name: "Update User Info", + description: "Update profile or HR information for an existing user. [See the documentation](https://developers.lucca.fr/api-reference/legacy/directory/update-a-user-by-id)", + version: "0.0.{{ts}}", + type: "action", + props: { + lucca, + userId: { + propDefinition: [ + lucca, + "userId", + ], + }, + firstname: { + type: "string", + label: "First Name", + description: "The user's first name", + optional: true, + }, + lastname: { + type: "string", + label: "Last Name", + description: "The user's last name", + optional: true, + }, + mail: { + type: "string", + label: "Email", + description: "The user's email", + optional: true, + }, + login: { + type: "string", + label: "Login", + description: "The user's login", + optional: true, + }, + legalentityid: { + type: "integer", + label: "Legal Entity ID", + description: "The ID of the legal entity", + optional: true, + }, + cspid: { + type: "integer", + label: "CSP ID", + description: "The ID of the CSP", + optional: true, + }, + calendarid: { + type: "integer", + label: "Calendar ID", + description: "The ID of the calendar", + optional: true, + }, + employeenumber: { + type: "string", + label: "Employee Number", + description: "The employee number", + optional: true, + }, + birthdate: { + type: "string", + label: "Birth Date", + description: "The birth date of the user. Format: 'YYYY-MM-DD'.", + optional: true, + }, + userworkcycles: { + type: "string[]", + label: "User Work Cycles", + description: "An array of user work cycles in JSON format", + optional: true, + }, + departmentid: { + type: "integer", + label: "Department ID", + description: "The ID of the department", + optional: true, + }, + managerid: { + type: "integer", + label: "Manager ID", + description: "The ID of the manager", + optional: true, + }, + roleprincipalid: { + type: "integer", + label: "Role Principal ID", + description: "The ID of the role principal", + optional: true, + }, + habilitedroles: { + type: "string[]", + label: "Habilited Roles", + description: "An array of habilited roles in JSON format", + optional: true, + }, + cultureid: { + type: "integer", + label: "Culture ID", + description: "The ID of the culture", + optional: true, + }, + address: { + type: "string", + label: "Address", + description: "The address of the user", + optional: true, + }, + bankname: { + type: "string", + label: "Bank Name", + description: "The name of the bank", + optional: true, + }, + directline: { + type: "string", + label: "Direct Line", + description: "The direct line of the user", + optional: true, + }, + jobtitle: { + type: "string", + label: "Job Title", + description: "The job title of the user", + optional: true, + }, + gender: { + type: "string", + label: "Gender", + description: "The gender of the user", + optional: true, + }, + nationality: { + type: "string", + label: "Nationality", + description: "The nationality of the user", + optional: true, + }, + personalemail: { + type: "string", + label: "Personal Email", + description: "The personal email of the user", + optional: true, + }, + personalmobile: { + type: "string", + label: "Personal Mobile", + description: "The personal mobile of the user", + optional: true, + }, + professionalmobile: { + type: "string", + label: "Professional Mobile", + description: "The professional mobile of the user", + optional: true, + }, + quote: { + type: "string", + label: "Quote", + description: "The quote of the user", + optional: true, + }, + }, + async run({ $ }) { + const data = { + firstName: this.firstname, + lastName: this.lastname, + mail: this.mail, + login: this.login, + legalEntityId: this.legalentityid, + cspId: this.cspid, + calendarId: this.calendarid, + employeeNumber: this.employeenumber, + birthDate: this.birthdate, + userWorkCycles: this.userworkcycles + ? this.userworkcycles.map(JSON.parse) + : [], + departmentId: this.departmentid, + managerId: this.managerid, + rolePrincipalId: this.roleprincipalid, + habilitedRoles: this.habilitedroles + ? this.habilitedroles.map(JSON.parse) + : [], + cultureId: this.cultureid, + address: this.address, + bankName: this.bankname, + directLine: this.directline, + jobTitle: this.jobtitle, + gender: this.gender, + nationality: this.nationality, + personalEmail: this.personalemail, + personalMobile: this.personalmobile, + professionalMobile: this.professionalmobile, + quote: this.quote, + }; + + const response = await this.lucca.updateUserProfile({ + userId: this.userId, + ...data, + }); + + $.export("$summary", `Successfully updated user with ID: ${this.userId}`); + return response; + }, +}; diff --git a/components/lucca/lucca.app.mjs b/components/lucca/lucca.app.mjs index 6c2a44bc7dc69..5c2f40518614b 100644 --- a/components/lucca/lucca.app.mjs +++ b/components/lucca/lucca.app.mjs @@ -1,11 +1,146 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "lucca", - propDefinitions: {}, + propDefinitions: { + leaveType: { + type: "string", + label: "Leave Type", + description: "Filter by leave type", + optional: true, + async options() { + const leaveTypes = await this.listLeaveTypes(); + return leaveTypes.map((type) => ({ + label: type.name, + value: type.id, + })); + }, + }, + userId: { + type: "string", + label: "User ID", + description: "The ID of the user", + async options() { + const users = await this.listUsers(); + return users.map((user) => ({ + label: user.displayName, + value: user.id, + })); + }, + }, + leaveRequestId: { + type: "string", + label: "Leave Request ID", + description: "The ID of the leave request to approve", + async options() { + const leaveRequests = await this.listLeaveRequests(); + return leaveRequests.map((request) => ({ + label: `${request.id} - ${request.status}`, + value: request.id, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `https://${this.$auth.account}.ilucca.net/api/v3`; + }, + 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.oauth_access_token}`, + }, + }); + }, + async listLeaveTypes(opts = {}) { + return this._makeRequest({ + path: "/leaveperiods/leavetypes", + ...opts, + }); + }, + async listUsers(opts = {}) { + const response = await this._makeRequest({ + path: "/users", + ...opts, + }); + return response.items; + }, + async listLeaveRequests(opts = {}) { + const response = await this._makeRequest({ + path: "/leaveRequests", + ...opts, + }); + return response.items; + }, + async approveLeaveRequest({ + leaveRequestId, approved = true, comment = "", + }) { + return this._makeRequest({ + method: "POST", + path: `/leaveRequests/${leaveRequestId}/approvals`, + data: { + approved, + comment, + }, + }); + }, + async updateUserProfile({ + userId, firstname, lastname, mail, login, legalentityid, cspid, calendarid, + employeenumber, birthdate, userworkcycles, departmentid, managerid, + roleprincipalid, habilitedroles, cultureid, address, bankname, + directline, jobtitle, gender, nationality, personalemail, personalmobile, + professionalmobile, quote, + }) { + return this._makeRequest({ + method: "PUT", + path: `/users/${userId}`, + data: { + firstName: firstname, + lastName: lastname, + mail, + login, + legalEntityId: legalentityid, + cspId: cspid, + calendarId: calendarid, + employeeNumber: employeenumber, + birthDate: birthdate, + userWorkCycles: userworkcycles + ? userworkcycles.map(JSON.parse) + : [], + departmentId: departmentid, + managerId: managerid, + rolePrincipalId: roleprincipalid, + habilitedRoles: habilitedroles + ? habilitedroles.map(JSON.parse) + : [], + cultureId: cultureid, + address, + bankName: bankname, + directLine: directline, + jobTitle: jobtitle, + gender, + nationality, + personalEmail: personalemail, + personalMobile: personalmobile, + professionalMobile: professionalmobile, + quote, + }, + }); + }, + async listExpenseClaims(opts = {}) { + return this._makeRequest({ + path: "/expenseClaims", + ...opts, + }); }, }, -}; \ No newline at end of file + version: "0.0.{{ts}}", +}; diff --git a/components/lucca/package.json b/components/lucca/package.json index e53759b922e86..7b2c467cc7d1f 100644 --- a/components/lucca/package.json +++ b/components/lucca/package.json @@ -12,4 +12,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/components/lucca/sources/new-expense-report/new-expense-report.mjs b/components/lucca/sources/new-expense-report/new-expense-report.mjs new file mode 100644 index 0000000000000..a0e82135d4ee1 --- /dev/null +++ b/components/lucca/sources/new-expense-report/new-expense-report.mjs @@ -0,0 +1,69 @@ +import { axios } from "@pipedream/platform"; +import lucca from "../../lucca.app.mjs"; + +export default { + key: "lucca-new-expense-report", + name: "New Expense Report Created", + description: "Emit new event when a new expense report is created by an employee. Useful for automating approval or finance workflows. [See the documentation](https://developers.lucca.fr/api-reference/legacy/cleemy-expenses/expenseclaims/list-expenseclaims)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + lucca, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: 3600, // polling interval of 1 hour + }, + }, + }, + hooks: { + async deploy() { + // Fetching and emitting the latest 50 expense claims on deploy + const expenseClaims = await this.lucca.listExpenseClaims({ + params: { + orderBy: "createdOn,desc", + paging: "0,50", + }, + }); + + for (const expenseClaim of expenseClaims.slice(0, 50)) { + this.$emit(expenseClaim, { + id: expenseClaim.id, + summary: `New expense report: ${expenseClaim.name}`, + ts: Date.parse(expenseClaim.createdOn), + }); + } + }, + }, + methods: { + _getLastTimestamp() { + return this.db.get("lastTimestamp"); + }, + _setLastTimestamp(ts) { + this.db.set("lastTimestamp", ts); + }, + }, + async run() { + const lastTimestamp = this._getLastTimestamp() || 0; + const expenseClaims = await this.lucca.listExpenseClaims({ + params: { + declaredOn: `since,${new Date(lastTimestamp).toISOString()}`, + orderBy: "createdOn,asc", + }, + }); + + for (const expenseClaim of expenseClaims) { + const timestamp = Date.parse(expenseClaim.createdOn); + if (timestamp > lastTimestamp) { + this.$emit(expenseClaim, { + id: expenseClaim.id, + summary: `New expense report: ${expenseClaim.name}`, + ts: timestamp, + }); + this._setLastTimestamp(timestamp); + } + } + }, +}; diff --git a/components/lucca/sources/new-leave-request/new-leave-request.mjs b/components/lucca/sources/new-leave-request/new-leave-request.mjs new file mode 100644 index 0000000000000..c6c7327091177 --- /dev/null +++ b/components/lucca/sources/new-leave-request/new-leave-request.mjs @@ -0,0 +1,104 @@ +import { + axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, +} from "@pipedream/platform"; +import lucca from "../../lucca.app.mjs"; + +export default { + key: "lucca-new-leave-request", + name: "New Leave Request", + description: "Emit new event when a new leave request is submitted by an employee. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/list-leave-requests)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + lucca, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + leaveType: { + propDefinition: [ + lucca, + "leaveType", + ], + }, + userId: { + propDefinition: [ + lucca, + "userId", + ], + }, + }, + methods: { + _getLastChecked() { + return this.db.get("lastChecked") || null; + }, + _setLastChecked(timestamp) { + this.db.set("lastChecked", timestamp); + }, + async fetchLeaveRequests(params = {}) { + return this.lucca.listLeaveRequests({ + params, + }); + }, + emitEvent(leaveRequest) { + this.$emit(leaveRequest, { + id: leaveRequest.id, + summary: `New Leave Request by ${leaveRequest.leavePeriod.ownerId}`, + ts: new Date(leaveRequest.creationDate).getTime(), + }); + }, + }, + hooks: { + async deploy() { + const params = { + orderBy: "creationDate desc", + ...(this.leaveType && { + leaveTypeId: this.leaveType, + }), + ...(this.userId && { + userId: this.userId, + }), + }; + const leaveRequests = await this.fetchLeaveRequests(params); + + leaveRequests.slice(0, 50).forEach((leaveRequest) => { + this.emitEvent(leaveRequest); + }); + + if (leaveRequests.length > 0) { + const lastChecked = new Date(leaveRequests[0].creationDate); + this._setLastChecked(lastChecked.toISOString()); + } + }, + }, + async run() { + const lastChecked = this._getLastChecked(); + const params = { + orderBy: "creationDate asc", + ...(this.leaveType && { + leaveTypeId: this.leaveType, + }), + ...(this.userId && { + userId: this.userId, + }), + ...(lastChecked && { + filter: `creationDate gt ${lastChecked}`, + }), + }; + + const leaveRequests = await this.fetchLeaveRequests(params); + + leaveRequests.forEach((leaveRequest) => { + this.emitEvent(leaveRequest); + }); + + if (leaveRequests.length > 0) { + const lastProcessedDate = new Date(leaveRequests[leaveRequests.length - 1].creationDate); + this._setLastChecked(lastProcessedDate.toISOString()); + } + }, +}; diff --git a/components/lucca/sources/new-user/new-user.mjs b/components/lucca/sources/new-user/new-user.mjs new file mode 100644 index 0000000000000..4da24d36e9258 --- /dev/null +++ b/components/lucca/sources/new-user/new-user.mjs @@ -0,0 +1,64 @@ +import { axios } from "@pipedream/platform"; +import lucca from "../../lucca.app.mjs"; + +export default { + key: "lucca-new-user", + name: "New User Created", + description: "Emit new event when a new user (employee) is created in Lucca. [See the documentation](https://developers.lucca.fr/api-reference/legacy/directory/list-users)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + lucca, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: 3600, + }, + }, + }, + methods: { + _getLastUserId() { + return this.db.get("lastUserId") || 0; + }, + _setLastUserId(id) { + this.db.set("lastUserId", id); + }, + }, + hooks: { + async deploy() { + const users = await this.lucca.listUsers(); + users.sort((a, b) => b.id - a.id); + users.slice(0, 50).forEach((user) => { + this.$emit(user, { + id: user.id, + summary: `New User: ${user.displayName}`, + ts: new Date(user.modifiedOn).getTime(), + }); + }); + if (users.length) { + this._setLastUserId(users[0].id); + } + }, + }, + async run() { + let lastUserId = this._getLastUserId(); + const users = await this.lucca.listUsers(); + + users + .filter((user) => user.id > lastUserId) + .forEach((user) => { + this.$emit(user, { + id: user.id, + summary: `New User: ${user.displayName}`, + ts: new Date(user.modifiedOn).getTime(), + }); + }); + + if (users.length) { + const newLastUserId = Math.max(...users.map((user) => user.id)); + this._setLastUserId(newLastUserId); + } + }, +}; From 0b8558e1cac7c844886931c87522d966c3f66e5e Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 3 Apr 2025 16:35:45 -0300 Subject: [PATCH 2/8] [Components] lucca #16101 Sources - New Leave Request - New User - New Expense Report Actions - Approve Leave Request - Update User Info --- .../approve-leave-request.mjs | 17 +- .../update-user-info/update-user-info.mjs | 92 +++------ components/lucca/common/constants.mjs | 1 + components/lucca/lucca.app.mjs | 160 +++++++--------- components/lucca/package.json | 5 +- components/lucca/sources/common/base.mjs | 63 ++++++ .../new-expense-report/new-expense-report.mjs | 69 ++----- .../sources/new-expense-report/test-event.mjs | 181 ++++++++++++++++++ .../new-leave-request/new-leave-request.mjs | 104 ++-------- .../sources/new-leave-request/test-event.mjs | 50 +++++ .../lucca/sources/new-user/new-user.mjs | 64 ++----- .../lucca/sources/new-user/test-event.mjs | 67 +++++++ 12 files changed, 509 insertions(+), 364 deletions(-) create mode 100644 components/lucca/common/constants.mjs create mode 100644 components/lucca/sources/common/base.mjs create mode 100644 components/lucca/sources/new-expense-report/test-event.mjs create mode 100644 components/lucca/sources/new-leave-request/test-event.mjs create mode 100644 components/lucca/sources/new-user/test-event.mjs diff --git a/components/lucca/actions/approve-leave-request/approve-leave-request.mjs b/components/lucca/actions/approve-leave-request/approve-leave-request.mjs index d5dccb0345686..1c0efc3ac2288 100644 --- a/components/lucca/actions/approve-leave-request/approve-leave-request.mjs +++ b/components/lucca/actions/approve-leave-request/approve-leave-request.mjs @@ -1,11 +1,10 @@ import lucca from "../../lucca.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "lucca-approve-leave-request", - name: "Approve Leave Request", - description: "Approve a pending leave request. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/approve-or-deny-a-leave-request)", - version: "0.0.{{ts}}", + name: "Approve Or Deny Leave Request", + description: "Approve or Deny a pending leave request. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/approve-or-deny-a-leave-request)", + version: "0.0.1", type: "action", props: { lucca, @@ -18,9 +17,8 @@ export default { approved: { type: "boolean", label: "Approved", - description: "Whether the leave request should be approved. Defaults to `true`.", + description: "Whether the leave request should be approved.", optional: true, - default: true, }, comment: { type: "string", @@ -31,9 +29,12 @@ export default { }, async run({ $ }) { const response = await this.lucca.approveLeaveRequest({ + $, leaveRequestId: this.leaveRequestId, - approved: this.approved ?? true, - comment: this.comment || "", + data: { + approved: this.approved, + comment: this.comment, + }, }); $.export("$summary", `Leave request ${this.leaveRequestId} was successfully processed.`); diff --git a/components/lucca/actions/update-user-info/update-user-info.mjs b/components/lucca/actions/update-user-info/update-user-info.mjs index f68028d9e33c2..24a8866a45ca7 100644 --- a/components/lucca/actions/update-user-info/update-user-info.mjs +++ b/components/lucca/actions/update-user-info/update-user-info.mjs @@ -1,11 +1,10 @@ import lucca from "../../lucca.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "lucca-update-user-info", name: "Update User Info", description: "Update profile or HR information for an existing user. [See the documentation](https://developers.lucca.fr/api-reference/legacy/directory/update-a-user-by-id)", - version: "0.0.{{ts}}", + version: "0.0.1", type: "action", props: { lucca, @@ -15,13 +14,13 @@ export default { "userId", ], }, - firstname: { + firstName: { type: "string", label: "First Name", description: "The user's first name", optional: true, }, - lastname: { + lastName: { type: "string", label: "Last Name", description: "The user's last name", @@ -39,67 +38,55 @@ export default { description: "The user's login", optional: true, }, - legalentityid: { + legalEntityId: { type: "integer", label: "Legal Entity ID", description: "The ID of the legal entity", optional: true, }, - cspid: { + cspId: { type: "integer", label: "CSP ID", description: "The ID of the CSP", optional: true, }, - calendarid: { + calendarId: { type: "integer", label: "Calendar ID", description: "The ID of the calendar", optional: true, }, - employeenumber: { + employeeNumber: { type: "string", label: "Employee Number", description: "The employee number", optional: true, }, - birthdate: { + birthDate: { type: "string", label: "Birth Date", description: "The birth date of the user. Format: 'YYYY-MM-DD'.", optional: true, }, - userworkcycles: { - type: "string[]", - label: "User Work Cycles", - description: "An array of user work cycles in JSON format", - optional: true, - }, - departmentid: { + departmentId: { type: "integer", label: "Department ID", description: "The ID of the department", optional: true, }, - managerid: { + managerId: { type: "integer", label: "Manager ID", description: "The ID of the manager", optional: true, }, - roleprincipalid: { + rolePrincipalId: { type: "integer", label: "Role Principal ID", description: "The ID of the role principal", optional: true, }, - habilitedroles: { - type: "string[]", - label: "Habilited Roles", - description: "An array of habilited roles in JSON format", - optional: true, - }, - cultureid: { + cultureId: { type: "integer", label: "Culture ID", description: "The ID of the culture", @@ -111,19 +98,19 @@ export default { description: "The address of the user", optional: true, }, - bankname: { + bankName: { type: "string", label: "Bank Name", description: "The name of the bank", optional: true, }, - directline: { + directLine: { type: "string", label: "Direct Line", description: "The direct line of the user", optional: true, }, - jobtitle: { + jobTitle: { type: "string", label: "Job Title", description: "The job title of the user", @@ -141,19 +128,19 @@ export default { description: "The nationality of the user", optional: true, }, - personalemail: { + personalEmail: { type: "string", label: "Personal Email", description: "The personal email of the user", optional: true, }, - personalmobile: { + personalMobile: { type: "string", label: "Personal Mobile", description: "The personal mobile of the user", optional: true, }, - professionalmobile: { + professionalMobile: { type: "string", label: "Professional Mobile", description: "The professional mobile of the user", @@ -167,41 +154,16 @@ export default { }, }, async run({ $ }) { - const data = { - firstName: this.firstname, - lastName: this.lastname, - mail: this.mail, - login: this.login, - legalEntityId: this.legalentityid, - cspId: this.cspid, - calendarId: this.calendarid, - employeeNumber: this.employeenumber, - birthDate: this.birthdate, - userWorkCycles: this.userworkcycles - ? this.userworkcycles.map(JSON.parse) - : [], - departmentId: this.departmentid, - managerId: this.managerid, - rolePrincipalId: this.roleprincipalid, - habilitedRoles: this.habilitedroles - ? this.habilitedroles.map(JSON.parse) - : [], - cultureId: this.cultureid, - address: this.address, - bankName: this.bankname, - directLine: this.directline, - jobTitle: this.jobtitle, - gender: this.gender, - nationality: this.nationality, - personalEmail: this.personalemail, - personalMobile: this.personalmobile, - professionalMobile: this.professionalmobile, - quote: this.quote, - }; + const { + lucca, + userId, + ...data + } = this; - const response = await this.lucca.updateUserProfile({ - userId: this.userId, - ...data, + const response = await lucca.updateUserProfile({ + $, + userId, + data, }); $.export("$summary", `Successfully updated user with ID: ${this.userId}`); diff --git a/components/lucca/common/constants.mjs b/components/lucca/common/constants.mjs new file mode 100644 index 0000000000000..ea830c15a04cb --- /dev/null +++ b/components/lucca/common/constants.mjs @@ -0,0 +1 @@ +export const LIMIT = 100; diff --git a/components/lucca/lucca.app.mjs b/components/lucca/lucca.app.mjs index 5c2f40518614b..ea4b98dabbcb8 100644 --- a/components/lucca/lucca.app.mjs +++ b/components/lucca/lucca.app.mjs @@ -1,31 +1,26 @@ import { axios } from "@pipedream/platform"; +import { LIMIT } from "./common/constants.mjs"; export default { type: "app", app: "lucca", propDefinitions: { - leaveType: { - type: "string", - label: "Leave Type", - description: "Filter by leave type", - optional: true, - async options() { - const leaveTypes = await this.listLeaveTypes(); - return leaveTypes.map((type) => ({ - label: type.name, - value: type.id, - })); - }, - }, userId: { type: "string", label: "User ID", description: "The ID of the user", - async options() { - const users = await this.listUsers(); - return users.map((user) => ({ - label: user.displayName, - value: user.id, + async options({ page }) { + const { data: { items } } = await this.listUsers({ + params: { + paging: `${LIMIT * page},${LIMIT}`, + }, + }); + + return items.map(({ + id: value, name: label, + }) => ({ + label, + value, })); }, }, @@ -33,114 +28,107 @@ export default { type: "string", label: "Leave Request ID", description: "The ID of the leave request to approve", - async options() { - const leaveRequests = await this.listLeaveRequests(); - return leaveRequests.map((request) => ({ - label: `${request.id} - ${request.status}`, - value: request.id, + async options({ page }) { + const { data: { items } } = await this.listLeaveRequests({ + params: { + paging: `${LIMIT * page},${LIMIT}`, + status: 0, + }, + }); + return items.map(({ + id: value, name: label, + }) => ({ + label, + value, })); }, }, }, methods: { _baseUrl() { - return `https://${this.$auth.account}.ilucca.net/api/v3`; + return `${this.$auth.api_url}/api/v3`; }, - async _makeRequest(opts = {}) { - const { - $ = this, method = "GET", path = "/", headers, ...otherOpts - } = opts; + _headers() { + return { + "authorization": `lucca application=${this.$auth.api_key}`, + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { return axios($, { - ...otherOpts, - method, url: this._baseUrl() + path, - headers: { - ...headers, - "Authorization": `Bearer ${this.$auth.oauth_access_token}`, - }, + headers: this._headers(), + ...opts, }); }, - async listLeaveTypes(opts = {}) { + listLeaveTypes(opts = {}) { return this._makeRequest({ path: "/leaveperiods/leavetypes", ...opts, }); }, - async listUsers(opts = {}) { - const response = await this._makeRequest({ + listUsers(opts = {}) { + return this._makeRequest({ path: "/users", ...opts, }); - return response.items; }, - async listLeaveRequests(opts = {}) { - const response = await this._makeRequest({ + listLeaveRequests(opts = {}) { + return this._makeRequest({ path: "/leaveRequests", ...opts, }); - return response.items; }, - async approveLeaveRequest({ - leaveRequestId, approved = true, comment = "", + approveLeaveRequest({ + leaveRequestId, ...opts }) { return this._makeRequest({ method: "POST", path: `/leaveRequests/${leaveRequestId}/approvals`, - data: { - approved, - comment, - }, + ...opts, }); }, - async updateUserProfile({ - userId, firstname, lastname, mail, login, legalentityid, cspid, calendarid, - employeenumber, birthdate, userworkcycles, departmentid, managerid, - roleprincipalid, habilitedroles, cultureid, address, bankname, - directline, jobtitle, gender, nationality, personalemail, personalmobile, - professionalmobile, quote, + updateUserProfile({ + userId, ...opts }) { return this._makeRequest({ method: "PUT", path: `/users/${userId}`, - data: { - firstName: firstname, - lastName: lastname, - mail, - login, - legalEntityId: legalentityid, - cspId: cspid, - calendarId: calendarid, - employeeNumber: employeenumber, - birthDate: birthdate, - userWorkCycles: userworkcycles - ? userworkcycles.map(JSON.parse) - : [], - departmentId: departmentid, - managerId: managerid, - rolePrincipalId: roleprincipalid, - habilitedRoles: habilitedroles - ? habilitedroles.map(JSON.parse) - : [], - cultureId: cultureid, - address, - bankName: bankname, - directLine: directline, - jobTitle: jobtitle, - gender, - nationality, - personalEmail: personalemail, - personalMobile: personalmobile, - professionalMobile: professionalmobile, - quote, - }, + ...opts, }); }, - async listExpenseClaims(opts = {}) { + listExpenseClaims(opts = {}) { return this._makeRequest({ path: "/expenseClaims", ...opts, }); }, + async *paginate({ + fn, params = {}, maxResults = null, ...opts + }) { + let hasMore = false; + let count = 0; + let page = 0; + + do { + params.paging = `${LIMIT * page},${LIMIT}`; + page++; + const { data: { items } } = await fn({ + params, + ...opts, + }); + for (const d of items) { + yield d; + + if (maxResults && ++count === maxResults) { + return count; + } + } + + hasMore = items.length; + + } while (hasMore); + }, }, - version: "0.0.{{ts}}", }; diff --git a/components/lucca/package.json b/components/lucca/package.json index 7b2c467cc7d1f..bb3de410413ef 100644 --- a/components/lucca/package.json +++ b/components/lucca/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/lucca", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Lucca Components", "main": "lucca.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/lucca/sources/common/base.mjs b/components/lucca/sources/common/base.mjs new file mode 100644 index 0000000000000..7bea268e8ec73 --- /dev/null +++ b/components/lucca/sources/common/base.mjs @@ -0,0 +1,63 @@ +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; +import app from "../../lucca.app.mjs"; + +export default { + props: { + app, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + methods: { + _getLastId() { + return this.db.get("lastId") || 0; + }, + _setLastId(lastId) { + this.db.set("lastId", lastId); + }, + async emitEvent(maxResults = false) { + const lastId = this._getLastId(); + + const response = this.app.paginate({ + fn: this.getFunction(), + maxResults, + params: { + orderBy: "id,desc", + }, + }); + + let responseArray = []; + for await (const item of response) { + if (item.id <= lastId) break; + responseArray.push(item); + } + + if (responseArray.length) { + if (maxResults && (responseArray.length > maxResults)) { + responseArray.length = maxResults; + } + this._setLastId(responseArray[0].id); + } + + for (const item of responseArray.reverse()) { + this.$emit(item, { + id: item.id, + summary: this.getSummary(item), + ts: Date.parse(item.created || new Date()), + }); + } + }, + }, + hooks: { + async deploy() { + await this.emitEvent(25); + }, + }, + async run() { + await this.emitEvent(); + }, +}; diff --git a/components/lucca/sources/new-expense-report/new-expense-report.mjs b/components/lucca/sources/new-expense-report/new-expense-report.mjs index a0e82135d4ee1..dac90c6ceee9c 100644 --- a/components/lucca/sources/new-expense-report/new-expense-report.mjs +++ b/components/lucca/sources/new-expense-report/new-expense-report.mjs @@ -1,69 +1,22 @@ -import { axios } from "@pipedream/platform"; -import lucca from "../../lucca.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "lucca-new-expense-report", name: "New Expense Report Created", - description: "Emit new event when a new expense report is created by an employee. Useful for automating approval or finance workflows. [See the documentation](https://developers.lucca.fr/api-reference/legacy/cleemy-expenses/expenseclaims/list-expenseclaims)", - version: "0.0.{{ts}}", + description: "Emit new event when a new expense report is created by an employee. Useful for automating approval or finance workflows.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - lucca, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: 3600, // polling interval of 1 hour - }, - }, - }, - hooks: { - async deploy() { - // Fetching and emitting the latest 50 expense claims on deploy - const expenseClaims = await this.lucca.listExpenseClaims({ - params: { - orderBy: "createdOn,desc", - paging: "0,50", - }, - }); - - for (const expenseClaim of expenseClaims.slice(0, 50)) { - this.$emit(expenseClaim, { - id: expenseClaim.id, - summary: `New expense report: ${expenseClaim.name}`, - ts: Date.parse(expenseClaim.createdOn), - }); - } - }, - }, methods: { - _getLastTimestamp() { - return this.db.get("lastTimestamp"); + ...common.methods, + getFunction() { + return this.app.listExpenseClaims; }, - _setLastTimestamp(ts) { - this.db.set("lastTimestamp", ts); + getSummary(item) { + return `New expense report: ${item.name}`; }, }, - async run() { - const lastTimestamp = this._getLastTimestamp() || 0; - const expenseClaims = await this.lucca.listExpenseClaims({ - params: { - declaredOn: `since,${new Date(lastTimestamp).toISOString()}`, - orderBy: "createdOn,asc", - }, - }); - - for (const expenseClaim of expenseClaims) { - const timestamp = Date.parse(expenseClaim.createdOn); - if (timestamp > lastTimestamp) { - this.$emit(expenseClaim, { - id: expenseClaim.id, - summary: `New expense report: ${expenseClaim.name}`, - ts: timestamp, - }); - this._setLastTimestamp(timestamp); - } - } - }, + sampleEmit, }; diff --git a/components/lucca/sources/new-expense-report/test-event.mjs b/components/lucca/sources/new-expense-report/test-event.mjs new file mode 100644 index 0000000000000..a7192b6f6dbe6 --- /dev/null +++ b/components/lucca/sources/new-expense-report/test-event.mjs @@ -0,0 +1,181 @@ +export default { + "id": 1, + "expenseClaimId": 1, + "lineNumber": 1, + "isControlled": true, + "purchasedOn": "2023-11-07T05:31:56Z", + "createdOn": "2023-11-07T05:31:56Z", + "modifiedOn": "2023-11-07T05:31:56Z", + "originalTransaction": { + "grossAmount": 123, + "currencyId": "", + "isExpenseAbroad": true, + "currency": { + "id": "", + "name": "", + "url": "" + } + }, + "processedAmounts": { + "grossAmount": 123, + "currencyId": "", + "currency": { + "id": "", + "name": "", + "url": "" + }, + "netAmount": 123, + "vatBases": [ + { + "countryVatRateId": 2, + "countryVatRate": { + "id": 2, + "name": "", + "url": "" + }, + "vatAmount": 123, + "amountExcludingVat": 123 + } + ] + }, + "expenseNatureId": 1, + "mileage": { + "distance": 123, + "power": 123, + "waypoints": [ + "" + ] + }, + "quantity": 1, + "effectiveQuantity": 2, + "attendees": { + "internal": [ + { + "id": 123, + "name": "", + "url": "", + "displayName": "", + "modifiedOn": "", + "lastName": "", + "firstName": "", + "login": "", + "mail": "", + "dtContractStart": "", + "dtContractEnd": "", + "birthDate": "", + "employeeNumber": "", + "calendar": { + "id": 123, + "url": "", + "name": "" + }, + "culture": { + "id": 123, + "name": "", + "url": "" + }, + "picture": { + "id": "", + "url": "", + "name": "" + }, + "applicationData": { + "profile_figgo": { + "id": 123, + "name": "", + "url": "" + }, + "profile_utime": { + "id": 123, + "name": "", + "url": "" + } + }, + "legalEntity": { + "id": 123, + "name": "", + "url": "" + }, + "department": { + "id": 123, + "name": "", + "url": "" + }, + "manager": { + "id": 123, + "name": "", + "url": "" + }, + "rolePrincipal": { + "id": 123, + "name": "", + "url": "" + }, + "habilitedRoles": [ + { + "id": 123, + "name": "", + "url": "" + } + ], + "userWorkCycles": [ + { + "Id": 123, + "OwnerID": 123, + "WorkCycleID": 123, + "StartsOn": "", + "EndsOn": "" + } + ] + } + ], + "external": [ + { + "id": 2, + "displayName": "" + } + ] + }, + "axisSections": [ + { + "id": 2, + "code": "", + "name": "", + "multilingualName": "", + "description": "", + "ownerId": 2, + "startOn": "2023-11-07T05:31:56Z", + "endOn": "2023-11-07T05:31:56Z", + "active": true, + "axisId": 123, + "parentAxisSections": [ + {} + ], + "childrenAxisSections": [ + {} + ] + } + ], + "customFields": {}, + "merchant": "", + "comment": "", + "expenseReceipts": [ + { + "id": "" + } + ], + "authorizedActions": { + "isCancellable": true, + "isEditable": true + }, + "sourceId": { + "id": "" + }, + "source": { + "id": 123, + "name": "", + "code": "" + }, + "ownerId": 123, + "paymentMethodId": 0 +} \ No newline at end of file diff --git a/components/lucca/sources/new-leave-request/new-leave-request.mjs b/components/lucca/sources/new-leave-request/new-leave-request.mjs index c6c7327091177..638efb1bcd8c0 100644 --- a/components/lucca/sources/new-leave-request/new-leave-request.mjs +++ b/components/lucca/sources/new-leave-request/new-leave-request.mjs @@ -1,104 +1,22 @@ -import { - axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform"; -import lucca from "../../lucca.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "lucca-new-leave-request", name: "New Leave Request", - description: "Emit new event when a new leave request is submitted by an employee. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/list-leave-requests)", - version: "0.0.{{ts}}", + description: "Emit new event when a new leave request is submitted by an employee.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - lucca, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - leaveType: { - propDefinition: [ - lucca, - "leaveType", - ], - }, - userId: { - propDefinition: [ - lucca, - "userId", - ], - }, - }, methods: { - _getLastChecked() { - return this.db.get("lastChecked") || null; - }, - _setLastChecked(timestamp) { - this.db.set("lastChecked", timestamp); - }, - async fetchLeaveRequests(params = {}) { - return this.lucca.listLeaveRequests({ - params, - }); - }, - emitEvent(leaveRequest) { - this.$emit(leaveRequest, { - id: leaveRequest.id, - summary: `New Leave Request by ${leaveRequest.leavePeriod.ownerId}`, - ts: new Date(leaveRequest.creationDate).getTime(), - }); + ...common.methods, + getFunction() { + return this.app.listLeaveRequests; }, - }, - hooks: { - async deploy() { - const params = { - orderBy: "creationDate desc", - ...(this.leaveType && { - leaveTypeId: this.leaveType, - }), - ...(this.userId && { - userId: this.userId, - }), - }; - const leaveRequests = await this.fetchLeaveRequests(params); - - leaveRequests.slice(0, 50).forEach((leaveRequest) => { - this.emitEvent(leaveRequest); - }); - - if (leaveRequests.length > 0) { - const lastChecked = new Date(leaveRequests[0].creationDate); - this._setLastChecked(lastChecked.toISOString()); - } + getSummary(item) { + return `New Leave Request with ID: ${item.id}`; }, }, - async run() { - const lastChecked = this._getLastChecked(); - const params = { - orderBy: "creationDate asc", - ...(this.leaveType && { - leaveTypeId: this.leaveType, - }), - ...(this.userId && { - userId: this.userId, - }), - ...(lastChecked && { - filter: `creationDate gt ${lastChecked}`, - }), - }; - - const leaveRequests = await this.fetchLeaveRequests(params); - - leaveRequests.forEach((leaveRequest) => { - this.emitEvent(leaveRequest); - }); - - if (leaveRequests.length > 0) { - const lastProcessedDate = new Date(leaveRequests[leaveRequests.length - 1].creationDate); - this._setLastChecked(lastProcessedDate.toISOString()); - } - }, + sampleEmit, }; diff --git a/components/lucca/sources/new-leave-request/test-event.mjs b/components/lucca/sources/new-leave-request/test-event.mjs new file mode 100644 index 0000000000000..e746765c331c2 --- /dev/null +++ b/components/lucca/sources/new-leave-request/test-event.mjs @@ -0,0 +1,50 @@ +export default { + "id": 123, + "leavePeriodId": 123, + "leavePeriod": { + "id": 123, + "ownerId": 123, + "isConfirmed": true, + "confirmationDate": null, + "attachmentId": null, + "leaves": [ + {} + ], + "logs": [ + { + "id": 123, + "date": "2023-11-07T05:31:56Z", + "comment": "", + "status": 0 + } + ] + }, + "status": 0, + "creationDate": "2023-11-07T05:31:56Z", + "nextApproverId": null, + "cancellationUserId": null, + "cancellationDate": null, + "isActive": true, + "approvals": [ + { + "id": 123, + "date": "2023-11-07T05:31:56Z", + "approverId": 123, + "substitutedApproverId": null, + "approved": true, + "comment": "" + } + ], + "cancellationRequests": [ + { + "id": 123, + "authorId": 123, + "comment": "", + "rank": 0, + "approved": true, + "creationDate": "2023-11-07T05:31:56Z", + "nextApproverId": null, + "isActive": true + } + ] +} \ No newline at end of file diff --git a/components/lucca/sources/new-user/new-user.mjs b/components/lucca/sources/new-user/new-user.mjs index 4da24d36e9258..46f47c3b4ec1a 100644 --- a/components/lucca/sources/new-user/new-user.mjs +++ b/components/lucca/sources/new-user/new-user.mjs @@ -1,64 +1,22 @@ -import { axios } from "@pipedream/platform"; -import lucca from "../../lucca.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "lucca-new-user", name: "New User Created", - description: "Emit new event when a new user (employee) is created in Lucca. [See the documentation](https://developers.lucca.fr/api-reference/legacy/directory/list-users)", - version: "0.0.{{ts}}", + description: "Emit new event when a new user (employee) is created in Lucca.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - lucca, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: 3600, - }, - }, - }, methods: { - _getLastUserId() { - return this.db.get("lastUserId") || 0; + ...common.methods, + getFunction() { + return this.app.listUsers; }, - _setLastUserId(id) { - this.db.set("lastUserId", id); - }, - }, - hooks: { - async deploy() { - const users = await this.lucca.listUsers(); - users.sort((a, b) => b.id - a.id); - users.slice(0, 50).forEach((user) => { - this.$emit(user, { - id: user.id, - summary: `New User: ${user.displayName}`, - ts: new Date(user.modifiedOn).getTime(), - }); - }); - if (users.length) { - this._setLastUserId(users[0].id); - } + getSummary(item) { + return `New User: ${item.name}`; }, }, - async run() { - let lastUserId = this._getLastUserId(); - const users = await this.lucca.listUsers(); - - users - .filter((user) => user.id > lastUserId) - .forEach((user) => { - this.$emit(user, { - id: user.id, - summary: `New User: ${user.displayName}`, - ts: new Date(user.modifiedOn).getTime(), - }); - }); - - if (users.length) { - const newLastUserId = Math.max(...users.map((user) => user.id)); - this._setLastUserId(newLastUserId); - } - }, + sampleEmit, }; diff --git a/components/lucca/sources/new-user/test-event.mjs b/components/lucca/sources/new-user/test-event.mjs new file mode 100644 index 0000000000000..77d3985c43fb9 --- /dev/null +++ b/components/lucca/sources/new-user/test-event.mjs @@ -0,0 +1,67 @@ +export default { + "id": 123, + "name": "", + "url": "", + "displayName": "", + "modifiedOn": "", + "lastName": "", + "firstName": "", + "login": "", + "mail": "", + "dtContractStart": "", + "dtContractEnd": null, + "birthDate": "", + "employeeNumber": "", + "calendar": { + "id": 123, + "url": "", + "name": "" + }, + "culture": { + "id": 123, + "name": "", + "url": "" + }, + "picture": { + "id": "", + "href": "", + "name": "" + }, + "applicationData": {}, + "legalEntity": { + "id": 123, + "name": "", + "url": "" + }, + "department": { + "id": 123, + "name": "", + "url": "" + }, + "manager": { + "id": 123, + "name": "", + "url": "" + }, + "rolePrincipal": { + "id": 123, + "name": "", + "url": "" + }, + "habilitedRoles": [ + { + "id": 123, + "name": "", + "url": "" + } + ], + "userWorkCycles": [ + { + "Id": 123, + "OwnerID": 123, + "WorkCycleID": 123, + "StartsOn": "", + "EndsOn": "" + } + ] +} \ No newline at end of file From d5350dff4c8381330df2ce5b4d93bcd075dbddeb Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 3 Apr 2025 16:37:19 -0300 Subject: [PATCH 3/8] pnpm update --- pnpm-lock.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c0245be37368..e208ad9085588 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1401,8 +1401,7 @@ importers: components/better_uptime: {} - components/bettercontact: - specifiers: {} + components/bettercontact: {} components/bettervoice: dependencies: @@ -1930,8 +1929,7 @@ importers: specifier: ^4.2.0 version: 4.2.0 - components/bytebot: - specifiers: {} + components/bytebot: {} components/byteforms: dependencies: @@ -7478,7 +7476,11 @@ importers: specifier: ^1.6.0 version: 1.6.6 - components/lucca: {} + components/lucca: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/lucid: dependencies: @@ -8611,8 +8613,7 @@ importers: specifier: ^1.3.0 version: 1.6.6 - components/notiff: - specifiers: {} + components/notiff: {} components/notion: dependencies: @@ -12782,8 +12783,7 @@ importers: specifier: ^1.6.0 version: 1.6.6 - components/teltel: - specifiers: {} + components/teltel: {} components/temi: dependencies: From d6cd96b4054b09523754aa39d56595a175db7205 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Apr 2025 10:10:52 -0300 Subject: [PATCH 4/8] some adjusts --- .../update-user-info/update-user-info.mjs | 14 +++--- components/lucca/lucca.app.mjs | 50 +++++++++++++++++++ .../new-expense-report/new-expense-report.mjs | 2 +- .../new-leave-request/new-leave-request.mjs | 2 +- .../lucca/sources/new-user/new-user.mjs | 2 +- 5 files changed, 61 insertions(+), 9 deletions(-) diff --git a/components/lucca/actions/update-user-info/update-user-info.mjs b/components/lucca/actions/update-user-info/update-user-info.mjs index 24a8866a45ca7..71d5e014b3869 100644 --- a/components/lucca/actions/update-user-info/update-user-info.mjs +++ b/components/lucca/actions/update-user-info/update-user-info.mjs @@ -39,9 +39,10 @@ export default { optional: true, }, legalEntityId: { - type: "integer", - label: "Legal Entity ID", - description: "The ID of the legal entity", + propDefinition: [ + lucca, + "legalEntityId", + ], optional: true, }, cspId: { @@ -69,9 +70,10 @@ export default { optional: true, }, departmentId: { - type: "integer", - label: "Department ID", - description: "The ID of the department", + propDefinition: [ + lucca, + "departmentId", + ], optional: true, }, managerId: { diff --git a/components/lucca/lucca.app.mjs b/components/lucca/lucca.app.mjs index ea4b98dabbcb8..782696770a293 100644 --- a/components/lucca/lucca.app.mjs +++ b/components/lucca/lucca.app.mjs @@ -43,6 +43,44 @@ export default { })); }, }, + legalEntityId: { + type: "integer", + label: "Legal Entity ID", + description: "The ID of the legal entity", + async options({ page }) { + const { data: { items } } = await this.listEstablishments({ + params: { + paging: `${LIMIT * page},${LIMIT}`, + status: 0, + }, + }); + return items.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + departmentId: { + type: "integer", + label: "Department ID", + description: "The ID of the department", + async options({ page }) { + const { data: { items } } = await this.listDepartments({ + params: { + paging: `${LIMIT * page},${LIMIT}`, + status: 0, + }, + }); + return items.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, }, methods: { _baseUrl() { @@ -80,6 +118,18 @@ export default { ...opts, }); }, + listEstablishments(opts = {}) { + return this._makeRequest({ + path: "/establishments", + ...opts, + }); + }, + listDepartments(opts = {}) { + return this._makeRequest({ + path: "/departments", + ...opts, + }); + }, approveLeaveRequest({ leaveRequestId, ...opts }) { diff --git a/components/lucca/sources/new-expense-report/new-expense-report.mjs b/components/lucca/sources/new-expense-report/new-expense-report.mjs index dac90c6ceee9c..b22658d7c0f3d 100644 --- a/components/lucca/sources/new-expense-report/new-expense-report.mjs +++ b/components/lucca/sources/new-expense-report/new-expense-report.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "lucca-new-expense-report", name: "New Expense Report Created", - description: "Emit new event when a new expense report is created by an employee. Useful for automating approval or finance workflows.", + description: "Emit new event when a new expense report is created by an employee. Useful for automating approval or finance workflows. [See the documentation](https://developers.lucca.fr/api-reference/legacy/cleemy-expenses/expenseclaims/list-expenseclaims)", version: "0.0.1", type: "source", dedupe: "unique", diff --git a/components/lucca/sources/new-leave-request/new-leave-request.mjs b/components/lucca/sources/new-leave-request/new-leave-request.mjs index 638efb1bcd8c0..442cee30dba28 100644 --- a/components/lucca/sources/new-leave-request/new-leave-request.mjs +++ b/components/lucca/sources/new-leave-request/new-leave-request.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "lucca-new-leave-request", name: "New Leave Request", - description: "Emit new event when a new leave request is submitted by an employee.", + description: "Emit new event when a new leave request is submitted by an employee. [See the documentation](https://developers.lucca.fr/api-reference/legacy/timmi-absences/leave-requests/list-leave-requests)", version: "0.0.1", type: "source", dedupe: "unique", diff --git a/components/lucca/sources/new-user/new-user.mjs b/components/lucca/sources/new-user/new-user.mjs index 46f47c3b4ec1a..c675713696111 100644 --- a/components/lucca/sources/new-user/new-user.mjs +++ b/components/lucca/sources/new-user/new-user.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "lucca-new-user", name: "New User Created", - description: "Emit new event when a new user (employee) is created in Lucca.", + description: "Emit new event when a new user (employee) is created in Lucca. [See the documentation](https://developers.lucca.fr/api-reference/legacy/directory/list-users)", version: "0.0.1", type: "source", dedupe: "unique", From 111bcfc6e45dd7ab8552db57a2b7b55322639edd Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Apr 2025 10:12:32 -0300 Subject: [PATCH 5/8] pnpm update --- pnpm-lock.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e208ad9085588..e9c269b708b65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16455,8 +16455,8 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@definitelytyped/header-parser@0.2.18': - resolution: {integrity: sha512-3JWGzhieGOx+zhy+qaPDoiby2TPA1PZGpEJHt0VwR1aK0R9dER5BoBvnT5zSafg9kHQTw4aBRFbt3o41FNkaLw==} + '@definitelytyped/header-parser@0.2.19': + resolution: {integrity: sha512-zu+RxQpUCgorYUQZoyyrRIn9CljL1CeM4qak3NDeMO1r7tjAkodfpAGnVzx/6JR2OUk0tAgwmZxNMSwd9LVgxw==} engines: {node: '>=18.18.0'} '@definitelytyped/typescript-versions@0.1.8': @@ -32198,7 +32198,7 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@definitelytyped/header-parser@0.2.18': + '@definitelytyped/header-parser@0.2.19': dependencies: '@definitelytyped/typescript-versions': 0.1.8 '@definitelytyped/utils': 0.1.8 @@ -38838,7 +38838,7 @@ snapshots: dts-critic@3.3.11(typescript@5.7.2): dependencies: - '@definitelytyped/header-parser': 0.2.18 + '@definitelytyped/header-parser': 0.2.19 command-exists: 1.2.9 rimraf: 3.0.2 semver: 6.3.1 @@ -38848,7 +38848,7 @@ snapshots: dtslint@4.2.1(typescript@5.7.2): dependencies: - '@definitelytyped/header-parser': 0.2.18 + '@definitelytyped/header-parser': 0.2.19 '@definitelytyped/typescript-versions': 0.1.8 '@definitelytyped/utils': 0.1.8 dts-critic: 3.3.11(typescript@5.7.2) From 323a89cc2ca12e400737862ad1c3036d91a6791c Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Apr 2025 16:24:11 -0300 Subject: [PATCH 6/8] pnpm update --- pnpm-lock.yaml | 223 ++++++++----------------------------------------- 1 file changed, 36 insertions(+), 187 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6b2d340e74c2..e0f157ed550b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -379,8 +379,7 @@ importers: specifier: ^20.0.0 version: 20.0.0 - components/adyntel: - specifiers: {} + components/adyntel: {} components/aerisweather: dependencies: @@ -3557,7 +3556,7 @@ importers: components/docparser: dependencies: '@pipedream/platform': - specifier: ^3.0.0 + specifier: ^3.0.3 version: 3.0.3 components/docraptor: {} @@ -5771,8 +5770,7 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/hamsa: - specifiers: {} + components/hamsa: {} components/handwrytten: {} @@ -14902,8 +14900,8 @@ importers: docs-v2: dependencies: '@docsearch/react': - specifier: ^3.6.1 - version: 3.8.0(@algolia/client-search@5.17.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + specifier: ^3.8.1 + version: 3.9.0(@algolia/client-search@5.17.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) '@vercel/analytics': specifier: ^1.3.1 version: 1.4.1(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(vue@2.7.16) @@ -15198,126 +15196,74 @@ packages: resolution: {integrity: sha512-C+jj5XBTCNs7AFwufOkPLhuqn9bdgSDcqLB6b/Ppi9Fujwt613vWmA1hxeG76RX49vzHZIDJLq6N/v0o2SY1sA==} engines: {node: '>=18'} - '@algolia/autocomplete-core@1.17.7': - resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} + '@algolia/autocomplete-core@1.17.9': + resolution: {integrity: sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==} - '@algolia/autocomplete-plugin-algolia-insights@1.17.7': - resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==} + '@algolia/autocomplete-plugin-algolia-insights@1.17.9': + resolution: {integrity: sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==} peerDependencies: search-insights: '>= 1 < 3' - '@algolia/autocomplete-preset-algolia@1.17.7': - resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==} + '@algolia/autocomplete-preset-algolia@1.17.9': + resolution: {integrity: sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/autocomplete-shared@1.17.7': - resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==} + '@algolia/autocomplete-shared@1.17.9': + resolution: {integrity: sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.15.0': - resolution: {integrity: sha512-FaEM40iuiv1mAipYyiptP4EyxkJ8qHfowCpEeusdHUC4C7spATJYArD2rX3AxkVeREkDIgYEOuXcwKUbDCr7Nw==} - engines: {node: '>= 14.0.0'} - '@algolia/client-abtesting@5.17.1': resolution: {integrity: sha512-Os/xkQbDp5A5RdGYq1yS3fF69GoBJH5FIfrkVh+fXxCSe714i1Xdl9XoXhS4xG76DGKm6EFMlUqP024qjps8cg==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.15.0': - resolution: {integrity: sha512-lho0gTFsQDIdCwyUKTtMuf9nCLwq9jOGlLGIeQGKDxXF7HbiAysFIu5QW/iQr1LzMgDyM9NH7K98KY+BiIFriQ==} - engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.17.1': resolution: {integrity: sha512-WKpGC+cUhmdm3wndIlTh8RJXoVabUH+4HrvZHC4hXtvCYojEXYeep8RZstatwSZ7Ocg6Y2u67bLw90NEINuYEw==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.15.0': - resolution: {integrity: sha512-IofrVh213VLsDkPoSKMeM9Dshrv28jhDlBDLRcVJQvlL8pzue7PEB1EZ4UoJFYS3NSn7JOcJ/V+olRQzXlJj1w==} - engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.17.1': resolution: {integrity: sha512-5rb5+yPIie6912riAypTSyzbE23a7UM1UpESvD8GEPI4CcWQvA9DBlkRNx9qbq/nJ5pvv8VjZjUxJj7rFkzEAA==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.15.0': - resolution: {integrity: sha512-bDDEQGfFidDi0UQUCbxXOCdphbVAgbVmxvaV75cypBTQkJ+ABx/Npw7LkFGw1FsoVrttlrrQbwjvUB6mLVKs/w==} - engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.17.1': resolution: {integrity: sha512-nb/tfwBMn209TzFv1DDTprBKt/wl5btHVKoAww9fdEVdoKK02R2KAqxe5tuXLdEzAsS+LevRyOM/YjXuLmPtjQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.15.0': - resolution: {integrity: sha512-LfaZqLUWxdYFq44QrasCDED5bSYOswpQjSiIL7Q5fYlefAAUO95PzBPKCfUhSwhb4rKxigHfDkd81AvEicIEoA==} - engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.17.1': resolution: {integrity: sha512-JuNlZe1SdW9KbV0gcgdsiVkFfXt0mmPassdS3cBSGvZGbPB9JsHthD719k5Y6YOY4dGvw1JmC1i9CwCQHAS8hg==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.15.0': - resolution: {integrity: sha512-wu8GVluiZ5+il8WIRsGKu8VxMK9dAlr225h878GGtpTL6VBvwyJvAyLdZsfFIpY0iN++jiNb31q2C1PlPL+n/A==} - engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.17.1': resolution: {integrity: sha512-RBIFIv1QE3IlAikJKWTOpd6pwE4d2dY6t02iXH7r/SLXWn0HzJtsAPPeFg/OKkFvWAXt0H7In2/Mp7a1/Dy2pw==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.15.0': - resolution: {integrity: sha512-Z32gEMrRRpEta5UqVQA612sLdoqY3AovvUPClDfMxYrbdDAebmGDVPtSogUba1FZ4pP5dx20D3OV3reogLKsRA==} - engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.17.1': resolution: {integrity: sha512-bd5JBUOP71kPsxwDcvOxqtqXXVo/706NFifZ/O5Rx5GB8ZNVAhg4l7aGoT6jBvEfgmrp2fqPbkdIZ6JnuOpGcw==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.15.0': - resolution: {integrity: sha512-MkqkAxBQxtQ5if/EX2IPqFA7LothghVyvPoRNA/meS2AW2qkHwcxjuiBxv4H6mnAVEPfJlhu9rkdVz9LgCBgJg==} - engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.17.1': resolution: {integrity: sha512-T18tvePi1rjRYcIKhd82oRukrPWHxG/Iy1qFGaxCplgRm9Im5z96qnYOq75MSKGOUHkFxaBKJOLmtn8xDR+Mcw==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.15.0': - resolution: {integrity: sha512-QPrFnnGLMMdRa8t/4bs7XilPYnoUXDY8PMQJ1sf9ZFwhUysYYhQNX34/enoO0LBjpoOY6rLpha39YQEFbzgKyQ==} - engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.17.1': resolution: {integrity: sha512-gDtow+AUywTehRP8S1tWKx2IvhcJOxldAoqBxzN3asuQobF7er5n72auBeL++HY4ImEuzMi7PDOA/Iuwxs2IcA==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.15.0': - resolution: {integrity: sha512-5eupMwSqMLDObgSMF0XG958zR6GJP3f7jHDQ3/WlzCM9/YIJiWIUoJFGsko9GYsA5xbLDHE/PhWtq4chcCdaGQ==} - engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.17.1': resolution: {integrity: sha512-2992tTHkRe18qmf5SP57N78kN1D3e5t4PO1rt10sJncWtXBZWiNOK6K/UcvWsFbNSGAogFcIcvIMAl5mNp6RWA==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.15.0': - resolution: {integrity: sha512-Po/GNib6QKruC3XE+WKP1HwVSfCDaZcXu48kD+gwmtDlqHWKc7Bq9lrS0sNZ456rfCKhXksOmMfUs4wRM/Y96w==} - engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.17.1': resolution: {integrity: sha512-XpKgBfyczVesKgr7DOShNyPPu5kqlboimRRPjdqAw5grSyHhCmb8yoTIKy0TCqBABZeXRPMYT13SMruUVRXvHA==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.15.0': - resolution: {integrity: sha512-rOZ+c0P7ajmccAvpeeNrUmEKoliYFL8aOR5qGW5pFq3oj3Iept7Y5mEtEsOBYsRt6qLnaXn4zUKf+N8nvJpcIw==} - engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.17.1': resolution: {integrity: sha512-EhUomH+DZP5vb6DnEjT0GvXaXBSwzZnuU6hPGNU1EYKRXDouRjII/bIWpVjt7ycMgL2D2oQruqDh6rAWUhQwRw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.15.0': - resolution: {integrity: sha512-b1jTpbFf9LnQHEJP5ddDJKE2sAlhYd7EVSOWgzo/27n/SfCoHfqD0VWntnWYD83PnOKvfe8auZ2+xCb0TXotrQ==} - engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.17.1': resolution: {integrity: sha512-PSnENJtl4/wBWXlGyOODbLYm6lSiFqrtww7UpQRCJdsHXlJKF8XAP6AME8NxvbE0Qo/RJUxK0mvyEh9sQcx6bg==} engines: {node: '>= 14.0.0'} @@ -16487,15 +16433,15 @@ packages: resolution: {integrity: sha512-4JINx4Rttha29f50PBsJo48xZXx/He5yaIWJRwVarhYAN947+S84YciHl+AIhQNRPAFkg8+5qFngEGtKxQDWXA==} engines: {node: '>=18.18.0'} - '@docsearch/css@3.8.0': - resolution: {integrity: sha512-pieeipSOW4sQ0+bE5UFC51AOZp9NGxg89wAlZ1BAQFaiRAGK1IKUaPQ0UGZeNctJXyqZ1UvBtOQh2HH+U5GtmA==} + '@docsearch/css@3.9.0': + resolution: {integrity: sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==} - '@docsearch/react@3.8.0': - resolution: {integrity: sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==} + '@docsearch/react@3.9.0': + resolution: {integrity: sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ==} peerDependencies: - '@types/react': '>= 16.8.0 < 19.0.0' - react: '>= 16.8.0 < 19.0.0' - react-dom: '>= 16.8.0 < 19.0.0' + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' search-insights: '>= 1 < 3' peerDependenciesMeta: '@types/react': @@ -20238,10 +20184,6 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - algoliasearch@5.15.0: - resolution: {integrity: sha512-Yf3Swz1s63hjvBVZ/9f2P1Uu48GjmjCN+Esxb6MAONMGtZB1fRX8/S1AhUTtsuTlcGovbYLxpHgc7wEzstDZBw==} - engines: {node: '>= 14.0.0'} - algoliasearch@5.17.1: resolution: {integrity: sha512-3CcbT5yTWJDIcBe9ZHgsPi184SkT1kyZi3GWlQU5EFgvq1V73X2sqHRkPCQMe0RA/uvZbB+1sFeAk73eWygeLg==} engines: {node: '>= 14.0.0'} @@ -29126,40 +29068,33 @@ snapshots: transitivePeerDependencies: - supports-color - '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)': + '@algolia/autocomplete-preset-algolia@1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)': dependencies: - '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0) + '@algolia/autocomplete-shared': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1) '@algolia/client-search': 5.17.1 - algoliasearch: 5.15.0 + algoliasearch: 5.17.1 - '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)': + '@algolia/autocomplete-shared@1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)': dependencies: '@algolia/client-search': 5.17.1 - algoliasearch: 5.15.0 - - '@algolia/client-abtesting@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 + algoliasearch: 5.17.1 '@algolia/client-abtesting@5.17.1': dependencies: @@ -29168,13 +29103,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/client-analytics@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/client-analytics@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29182,17 +29110,8 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/client-common@5.15.0': {} - '@algolia/client-common@5.17.1': {} - '@algolia/client-insights@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/client-insights@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29200,13 +29119,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/client-personalization@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/client-personalization@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29214,13 +29126,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/client-query-suggestions@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/client-query-suggestions@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29228,13 +29133,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/client-search@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/client-search@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29242,13 +29140,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/ingestion@1.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/ingestion@1.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29256,13 +29147,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/monitoring@1.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/monitoring@1.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29270,13 +29154,6 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/recommend@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - '@algolia/recommend@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -29284,26 +29161,14 @@ snapshots: '@algolia/requester-fetch': 5.17.1 '@algolia/requester-node-http': 5.17.1 - '@algolia/requester-browser-xhr@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-browser-xhr@5.17.1': dependencies: '@algolia/client-common': 5.17.1 - '@algolia/requester-fetch@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-fetch@5.17.1': dependencies: '@algolia/client-common': 5.17.1 - '@algolia/requester-node-http@5.15.0': - dependencies: - '@algolia/client-common': 5.15.0 - '@algolia/requester-node-http@5.17.1': dependencies: '@algolia/client-common': 5.17.1 @@ -32237,14 +32102,14 @@ snapshots: tar-stream: 3.1.7 which: 4.0.0 - '@docsearch/css@3.8.0': {} + '@docsearch/css@3.9.0': {} - '@docsearch/react@3.8.0(@algolia/client-search@5.17.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': + '@docsearch/react@3.9.0(@algolia/client-search@5.17.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.17.1)(algoliasearch@5.15.0) - '@docsearch/css': 3.8.0 - algoliasearch: 5.15.0 + '@algolia/autocomplete-core': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.9(@algolia/client-search@5.17.1)(algoliasearch@5.17.1) + '@docsearch/css': 3.9.0 + algoliasearch: 5.17.1 optionalDependencies: '@types/react': 18.3.12 react: 18.3.1 @@ -36846,22 +36711,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.15.0: - dependencies: - '@algolia/client-abtesting': 5.15.0 - '@algolia/client-analytics': 5.15.0 - '@algolia/client-common': 5.15.0 - '@algolia/client-insights': 5.15.0 - '@algolia/client-personalization': 5.15.0 - '@algolia/client-query-suggestions': 5.15.0 - '@algolia/client-search': 5.15.0 - '@algolia/ingestion': 1.15.0 - '@algolia/monitoring': 1.15.0 - '@algolia/recommend': 5.15.0 - '@algolia/requester-browser-xhr': 5.15.0 - '@algolia/requester-fetch': 5.15.0 - '@algolia/requester-node-http': 5.15.0 - algoliasearch@5.17.1: dependencies: '@algolia/client-abtesting': 5.17.1 From 5ea4a382da27424761cc75a17baf315a9878b032 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 7 Apr 2025 17:06:52 -0300 Subject: [PATCH 7/8] pnpm update --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e0f157ed550b2..78c6ad7133e9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3556,7 +3556,7 @@ importers: components/docparser: dependencies: '@pipedream/platform': - specifier: ^3.0.3 + specifier: ^3.0.0 version: 3.0.3 components/docraptor: {} From 034a8861223a488a48cda541bf39c70f4b39a05f Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 8 Apr 2025 18:24:33 -0300 Subject: [PATCH 8/8] some adjusts --- .../update-user-info/update-user-info.mjs | 76 ++++++------------- components/lucca/lucca.app.mjs | 42 +++++++--- 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/components/lucca/actions/update-user-info/update-user-info.mjs b/components/lucca/actions/update-user-info/update-user-info.mjs index 71d5e014b3869..be58c646ac512 100644 --- a/components/lucca/actions/update-user-info/update-user-info.mjs +++ b/components/lucca/actions/update-user-info/update-user-info.mjs @@ -1,3 +1,4 @@ +import { ConfigurationError } from "@pipedream/platform"; import lucca from "../../lucca.app.mjs"; export default { @@ -45,12 +46,6 @@ export default { ], optional: true, }, - cspId: { - type: "integer", - label: "CSP ID", - description: "The ID of the CSP", - optional: true, - }, calendarId: { type: "integer", label: "Calendar ID", @@ -69,31 +64,6 @@ export default { description: "The birth date of the user. Format: 'YYYY-MM-DD'.", optional: true, }, - departmentId: { - propDefinition: [ - lucca, - "departmentId", - ], - optional: true, - }, - managerId: { - type: "integer", - label: "Manager ID", - description: "The ID of the manager", - optional: true, - }, - rolePrincipalId: { - type: "integer", - label: "Role Principal ID", - description: "The ID of the role principal", - optional: true, - }, - cultureId: { - type: "integer", - label: "Culture ID", - description: "The ID of the culture", - optional: true, - }, address: { type: "string", label: "Address", @@ -112,12 +82,6 @@ export default { description: "The direct line of the user", optional: true, }, - jobTitle: { - type: "string", - label: "Job Title", - description: "The job title of the user", - optional: true, - }, gender: { type: "string", label: "Gender", @@ -125,9 +89,10 @@ export default { optional: true, }, nationality: { - type: "string", - label: "Nationality", - description: "The nationality of the user", + propDefinition: [ + lucca, + "nationalityId", + ], optional: true, }, personalEmail: { @@ -156,19 +121,26 @@ export default { }, }, async run({ $ }) { - const { - lucca, - userId, - ...data - } = this; + try { + const { + lucca, + userId, + ...data + } = this; + + const response = await lucca.updateUserProfile({ + $, + userId, + data, + }); - const response = await lucca.updateUserProfile({ - $, - userId, - data, - }); + $.export("$summary", `Successfully updated user with ID: ${this.userId}`); + return response; + } catch ({ message }) { + console.log("message: ", message); - $.export("$summary", `Successfully updated user with ID: ${this.userId}`); - return response; + const parsedError = JSON.parse(message); + throw new ConfigurationError(parsedError.Message || parsedError[0].message); + } }, }; diff --git a/components/lucca/lucca.app.mjs b/components/lucca/lucca.app.mjs index 782696770a293..264ad7783bd60 100644 --- a/components/lucca/lucca.app.mjs +++ b/components/lucca/lucca.app.mjs @@ -48,12 +48,13 @@ export default { label: "Legal Entity ID", description: "The ID of the legal entity", async options({ page }) { - const { data: { items } } = await this.listEstablishments({ + const { items } = await this.listEstablishments({ params: { paging: `${LIMIT * page},${LIMIT}`, status: 0, }, }); + return items.map(({ id: value, name: label, }) => ({ @@ -70,7 +71,6 @@ export default { const { data: { items } } = await this.listDepartments({ params: { paging: `${LIMIT * page},${LIMIT}`, - status: 0, }, }); return items.map(({ @@ -81,10 +81,24 @@ export default { })); }, }, + nationalityId: { + type: "string", + label: "Nationality", + description: "The nationality of the user", + async options() { + const { items } = await this.listCountries(); + return items.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, }, methods: { _baseUrl() { - return `${this.$auth.api_url}/api/v3`; + return `${this.$auth.api_url}`; }, _headers() { return { @@ -102,31 +116,37 @@ export default { }, listLeaveTypes(opts = {}) { return this._makeRequest({ - path: "/leaveperiods/leavetypes", + path: "/api/v3/leaveperiods/leavetypes", ...opts, }); }, listUsers(opts = {}) { return this._makeRequest({ - path: "/users", + path: "/api/v3/users", ...opts, }); }, listLeaveRequests(opts = {}) { return this._makeRequest({ - path: "/leaveRequests", + path: "/api/v3/leaveRequests", ...opts, }); }, listEstablishments(opts = {}) { return this._makeRequest({ - path: "/establishments", + path: "/organization/structure/api/establishments", + ...opts, + }); + }, + listCountries(opts = {}) { + return this._makeRequest({ + path: "/organization/structure/api/countries", ...opts, }); }, listDepartments(opts = {}) { return this._makeRequest({ - path: "/departments", + path: "/api/v3/departments", ...opts, }); }, @@ -135,7 +155,7 @@ export default { }) { return this._makeRequest({ method: "POST", - path: `/leaveRequests/${leaveRequestId}/approvals`, + path: `/api/v3/leaveRequests/${leaveRequestId}/approvals`, ...opts, }); }, @@ -144,13 +164,13 @@ export default { }) { return this._makeRequest({ method: "PUT", - path: `/users/${userId}`, + path: `/api/v3/users/${userId}`, ...opts, }); }, listExpenseClaims(opts = {}) { return this._makeRequest({ - path: "/expenseClaims", + path: "/api/v3/expenseClaims", ...opts, }); },