- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.5k
New Components - cats #14656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Components - cats #14656
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||||||||||||||||||||||||||
| import cats from "../../cats.app.mjs"; | ||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
| export default { | ||||||||||||||||||||||||||||||
| key: "cats-add-candidate-pipeline", | ||||||||||||||||||||||||||||||
| name: "Add Candidate to Job Pipeline", | ||||||||||||||||||||||||||||||
| description: "Adds a specific candidate to a job pipeline in CATS. [See the documentation](https://docs.catsone.com/api/v3/#jobs-create-a-job)", | ||||||||||||||||||||||||||||||
| version: "0.0.1", | ||||||||||||||||||||||||||||||
| type: "action", | ||||||||||||||||||||||||||||||
| props: { | ||||||||||||||||||||||||||||||
| cats, | ||||||||||||||||||||||||||||||
| createActivity: { | ||||||||||||||||||||||||||||||
| type: "boolean", | ||||||||||||||||||||||||||||||
| label: "Create Activity", | ||||||||||||||||||||||||||||||
| description: "Whether a corresponding activity should be created automatically. This mimics what happens when a pipeline is created from the CATS UI.", | ||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| candidateId: { | ||||||||||||||||||||||||||||||
| propDefinition: [ | ||||||||||||||||||||||||||||||
| cats, | ||||||||||||||||||||||||||||||
| "candidateId", | ||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| jobId: { | ||||||||||||||||||||||||||||||
| propDefinition: [ | ||||||||||||||||||||||||||||||
| cats, | ||||||||||||||||||||||||||||||
| "jobId", | ||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| rating: { | ||||||||||||||||||||||||||||||
| type: "integer", | ||||||||||||||||||||||||||||||
| label: "Rating", | ||||||||||||||||||||||||||||||
| description: "The record's rating for the job (0-5).", | ||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| 
      Comment on lines
    
      +29
     to 
      +34
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation for rating range The rating property is described to accept values between 0-5, but there's no validation to enforce this range.    rating: {
     type: "integer",
     label: "Rating",
     description: "The record's rating for the job (0-5).",
     optional: true,
+    min: 0,
+    max: 5,
   },📝 Committable suggestion
 
        Suggested change
       
 | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| async run({ $ }) { | ||||||||||||||||||||||||||||||
| const { headers } = await this.cats.addCandidateToJobPipeline({ | ||||||||||||||||||||||||||||||
| $, | ||||||||||||||||||||||||||||||
| returnFullResponse: true, | ||||||||||||||||||||||||||||||
| params: { | ||||||||||||||||||||||||||||||
| create_activity: this.createActivity, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| data: { | ||||||||||||||||||||||||||||||
| candidate_id: this.candidateId, | ||||||||||||||||||||||||||||||
| job_id: this.jobId, | ||||||||||||||||||||||||||||||
| rating: this.rating, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
| const location = headers.location.split("/"); | ||||||||||||||||||||||||||||||
| const pipelineId = location[location.length - 1]; | ||||||||||||||||||||||||||||||
| 
      Comment on lines
    
      +50
     to 
      +51
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add robust error handling for location header parsing The current implementation assumes the location header will always be present and in the expected format. This could lead to runtime errors if the API response changes. -    const location = headers.location.split("/");
-    const pipelineId = location[location.length - 1];
+    if (!headers?.location) {
+      throw new Error("Failed to get pipeline ID from response");
+    }
+    const pipelineId = headers.location.split("/").pop();
+    if (!pipelineId) {
+      throw new Error("Invalid pipeline ID format in response");
+    }📝 Committable suggestion
 
        Suggested change
       
 | ||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
| $.export("$summary", `Successfully added candidate ID ${this.candidateId} to job ID ${this.jobId}`); | ||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||
| pipelineId, | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,308 @@ | ||
| import cats from "../../cats.app.mjs"; | ||
| import { parseObject } from "../../common/utils.mjs"; | ||
|  | ||
| export default { | ||
| key: "cats-create-candidate", | ||
| name: "Create Candidate", | ||
| description: "Create a new candidate in your CATS database. [See the documentation](https://docs.catsone.com/api/v3/#candidates-create-a-candidate)", | ||
| version: "0.0.1", | ||
| type: "action", | ||
| props: { | ||
| cats, | ||
| checkDuplicate: { | ||
| propDefinition: [ | ||
| cats, | ||
| "checkDuplicate", | ||
| ], | ||
| }, | ||
| firstName: { | ||
| propDefinition: [ | ||
| cats, | ||
| "firstName", | ||
| ], | ||
| }, | ||
| middleName: { | ||
| propDefinition: [ | ||
| cats, | ||
| "middleName", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| lastName: { | ||
| propDefinition: [ | ||
| cats, | ||
| "lastName", | ||
| ], | ||
| }, | ||
| title: { | ||
| propDefinition: [ | ||
| cats, | ||
| "title", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| emails: { | ||
| propDefinition: [ | ||
| cats, | ||
| "emails", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| phones: { | ||
| propDefinition: [ | ||
| cats, | ||
| "phones", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| addressStreet: { | ||
| propDefinition: [ | ||
| cats, | ||
| "addressStreet", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| addressCity: { | ||
| propDefinition: [ | ||
| cats, | ||
| "addressCity", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| addressState: { | ||
| propDefinition: [ | ||
| cats, | ||
| "addressState", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| addressPostalCode: { | ||
| propDefinition: [ | ||
| cats, | ||
| "addressPostalCode", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| countryCode: { | ||
| propDefinition: [ | ||
| cats, | ||
| "countryCode", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| socialMediaUrls: { | ||
| propDefinition: [ | ||
| cats, | ||
| "socialMediaUrls", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| website: { | ||
| type: "string", | ||
| label: "Website", | ||
| description: "The website of the record.", | ||
| optional: true, | ||
| }, | ||
| bestTimeToCall: { | ||
| propDefinition: [ | ||
| cats, | ||
| "bestTimeToCall", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| currentEmployer: { | ||
| propDefinition: [ | ||
| cats, | ||
| "currentEmployer", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| dateAvailable: { | ||
| type: "string", | ||
| label: "Date Available", | ||
| description: "The date the record is available for an opening. **Format: YYYY-MM-DD**.", | ||
| optional: true, | ||
| }, | ||
| currentPay: { | ||
| type: "string", | ||
| label: "Current Pay", | ||
| description: "The current pay of the record.", | ||
| optional: true, | ||
| }, | ||
| desiredPay: { | ||
| propDefinition: [ | ||
| cats, | ||
| "desiredPay", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| isWillingToRelocate: { | ||
| propDefinition: [ | ||
| cats, | ||
| "isWillingToRelocate", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| keySkills: { | ||
| propDefinition: [ | ||
| cats, | ||
| "keySkills", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| notes: { | ||
| propDefinition: [ | ||
| cats, | ||
| "notes", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| source: { | ||
| propDefinition: [ | ||
| cats, | ||
| "source", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| ownerId: { | ||
| propDefinition: [ | ||
| cats, | ||
| "ownerId", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| isActive: { | ||
| type: "boolean", | ||
| label: "Is Active", | ||
| description: "A flag indicating if the candidate is active.", | ||
| optional: true, | ||
| }, | ||
| isHot: { | ||
| propDefinition: [ | ||
| cats, | ||
| "isHot", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| password: { | ||
| type: "string", | ||
| label: "password", | ||
| description: "The candidate's password if they are \"registering\".", | ||
| secret: true, | ||
| optional: true, | ||
| }, | ||
| customFields: { | ||
| propDefinition: [ | ||
| cats, | ||
| "customFields", | ||
| ], | ||
| withLabel: true, | ||
| reloadProps: true, | ||
| optional: true, | ||
| }, | ||
| workHistory: { | ||
| propDefinition: [ | ||
| cats, | ||
| "workHistory", | ||
| ], | ||
| optional: true, | ||
| }, | ||
| }, | ||
| async additionalProps() { | ||
| const props = {}; | ||
| (this.customFields || []).map(({ | ||
| label, value, | ||
| }) => { | ||
| props[value] = { | ||
| type: "string", | ||
| label: `Custom Field: ${label}`, | ||
| optional: true, | ||
| }; | ||
| }, {}); | ||
|  | ||
| return props; | ||
| }, | ||
| async run({ $ }) { | ||
| const { | ||
| cats, // eslint-disable-next-line no-unused-vars | ||
| customFields, | ||
| firstName, | ||
| lastName, | ||
| ownerId, | ||
| middleName, | ||
| checkDuplicate, | ||
| bestTimeToCall, | ||
| currentEmployer, | ||
| emails, | ||
| phones, | ||
| addressStreet, | ||
| addressCity, | ||
| addressState, | ||
| addressPostalCode, | ||
| countryCode, | ||
| socialMediaUrls, | ||
| dateAvailable, | ||
| currentPay, | ||
| desiredPay, | ||
| isWillingToRelocate, | ||
| keySkills, | ||
| isActive, | ||
| isHot, | ||
| workHistory, | ||
| ...data | ||
| } = this; | ||
|  | ||
| const customFieldsObject = customFields | ||
| ? customFields.map(({ value }) => { | ||
| return { | ||
| id: value, | ||
| value: data[value], | ||
| }; | ||
| }) | ||
| : {}; | ||
|         
                  luancazarine marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
|  | ||
| const { headers } = await cats.createCandidate({ | ||
| $, | ||
| returnFullResponse: true, | ||
| params: { | ||
| check_duplicate: checkDuplicate, | ||
| }, | ||
| data: { | ||
| first_name: firstName, | ||
| middle_name: middleName, | ||
| last_name: lastName, | ||
| emails: parseObject(emails), | ||
| phones: parseObject(phones), | ||
| address: { | ||
| street: addressStreet, | ||
| city: addressCity, | ||
| state: addressState, | ||
| postal_code: addressPostalCode, | ||
| }, | ||
| country_code: countryCode, | ||
| social_media_urls: parseObject(socialMediaUrls), | ||
| best_time_to_call: bestTimeToCall, | ||
| current_employer: currentEmployer, | ||
| date_available: dateAvailable, | ||
| current_pay: currentPay, | ||
| desired_pay: desiredPay, | ||
| is_willing_to_relocate: isWillingToRelocate, | ||
| key_skills: keySkills, | ||
| owner_id: ownerId, | ||
| is_active: isActive, | ||
| is_hot: isHot, | ||
| work_history: parseObject(workHistory), | ||
| custom_fields: customFieldsObject, | ||
| ...data, | ||
|         
                  luancazarine marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| }, | ||
| }); | ||
|  | ||
| const location = headers.location.split("/"); | ||
| const candidateId = location[location.length - 1]; | ||
|  | ||
|         
                  luancazarine marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| $.export("$summary", `Created candidate with ID ${candidateId}`); | ||
| return { | ||
| candidateId, | ||
| }; | ||
| }, | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect documentation link
The documentation link in the description points to the job creation API endpoint (
/jobs-create-a-job), but this action is about adding candidates to job pipelines. Please update the link to point to the correct API endpoint documentation.📝 Committable suggestion