Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-jira-cloud
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-jira-cloud` to build the library.
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "@activepieces/piece-jira-cloud",
|
||||
"version": "0.1.20",
|
||||
"dependencies": {
|
||||
"@atlaskit/adf-schema": "50.4.0",
|
||||
"@atlaskit/editor-json-transformer": "8.27.2",
|
||||
"@atlaskit/editor-markdown-transformer": "5.16.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "pieces-jira-cloud",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/jira-cloud/src",
|
||||
"projectType": "library",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/jira-cloud",
|
||||
"tsConfig": "packages/pieces/community/jira-cloud/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/jira-cloud/package.json",
|
||||
"main": "packages/pieces/community/jira-cloud/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/jira-cloud/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/jira-cloud/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"prebuild",
|
||||
"^build"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-jira-cloud {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage/{projectRoot}"
|
||||
],
|
||||
"options": {
|
||||
"jestConfig": "packages/pieces/community/jira-cloud/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/jira-cloud",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
PieceAuth,
|
||||
Property,
|
||||
ShortTextProperty,
|
||||
StaticPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { getUsers, sendJiraRequest } from './lib/common';
|
||||
import { HttpError, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { z } from 'zod';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { AppConnectionType } from '@activepieces/shared';
|
||||
|
||||
export const jiraCloudAuth = PieceAuth.CustomAuth({
|
||||
description: `
|
||||
You can generate your API token from:
|
||||
***https://id.atlassian.com/manage-profile/security/api-tokens***
|
||||
`,
|
||||
required: true,
|
||||
props: {
|
||||
instanceUrl: Property.ShortText({
|
||||
displayName: 'Instance URL',
|
||||
description:
|
||||
'The link of your Jira instance (e.g https://example.atlassian.net)',
|
||||
required: true,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: 'The email you use to login to Jira',
|
||||
required: true,
|
||||
}),
|
||||
apiToken: PieceAuth.SecretText({
|
||||
displayName: 'API Token',
|
||||
description: 'Your Jira API Token',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
await propsValidation.validateZod(auth, {
|
||||
instanceUrl: z.string().url(),
|
||||
email: z.string().email(),
|
||||
});
|
||||
|
||||
await sendJiraRequest({
|
||||
auth: {
|
||||
type: AppConnectionType.CUSTOM_AUTH,
|
||||
props: auth,
|
||||
},
|
||||
method: HttpMethod.GET,
|
||||
url: 'myself',
|
||||
});
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (e) {
|
||||
const message = ((e as HttpError).response?.body as any)?.message;
|
||||
return {
|
||||
valid: false,
|
||||
error: message ?? 'Invalid credentials',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export type JiraAuth = AppConnectionValueForAuthProperty<typeof jiraCloudAuth>;
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"Jira Cloud": "Jira Cloud",
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "Email",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "User",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Fehlerverfolgung und Projektmanagement",
|
||||
"Instance URL": "Instanz URL",
|
||||
"Email": "E-Mail",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "Der Link deiner Jira-Instanz (z.B. https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "Die E-Mail-Adresse, mit der Sie sich bei Jira anmelden",
|
||||
"Your Jira API Token": "Ihr Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nDu kannst deinen API-Token generieren von:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Ticket erstellen",
|
||||
"Update Issue": "Problem aktualisieren",
|
||||
"Find User": "Benutzer finden",
|
||||
"Search Issues": "Probleme durchsuchen",
|
||||
"Assign Issue": "Ticket zuweisen",
|
||||
"Add Attachment to Issue": "Anhang zum Thema hinzufügen",
|
||||
"Get Issue Attachment": "Fehleranhang erhalten",
|
||||
"Add Watcher to Issue": "Beobachter zum Problem hinzufügen",
|
||||
"Add Issue Comment": "Ticket Kommentar hinzufügen",
|
||||
"Update Issue Comment": "Ticket Kommentar aktualisieren",
|
||||
"Link Issues": "Tickets verknüpfen",
|
||||
"List Issue Comments": "Ticket-Kommentare auflisten",
|
||||
"Delete Issue Comment": "Ticket-Kommentar löschen",
|
||||
"Markdown to Jira format": "Markdown zum Jira-Format",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Creates a new issue in a project.": "Erstellt ein neues Problem in einem Projekt.",
|
||||
"Updates an existing issue.": "Aktualisiert ein existierendes Problem.",
|
||||
"Finds an existing user.": "Findet einen existierenden Benutzer.",
|
||||
"Search for issues with JQL": "Suche nach Problemen mit JQL",
|
||||
"Assigns an issue to a user.": "Weist einem Benutzer ein Problem zu.",
|
||||
"Adds an attachment to an issue.": "Fügt einen Anhang zu einem Problem hinzu.",
|
||||
"Retrieves an attachment from an issue.": "Ruft einen Anhang von einem Problem ab.",
|
||||
"Adds a new watcher to an issue.": "Fügt einen neuen Beobachter zu einem Problem hinzu.",
|
||||
"Adds a comment to an issue.": "Fügt einen Kommentar zu einem Problem hinzu.",
|
||||
"Updates a comment to a specific issue.": "Aktualisiert einen Kommentar zu einem bestimmten Problem.",
|
||||
"Creates a link between two issues.": "Erzeugt eine Verbindung zwischen zwei Problemen.",
|
||||
"Returns all comments for an issue.": "Gibt alle Kommentare für ein Problem zurück.",
|
||||
"Deletes a comment on a specific issue.": "Löscht einen Kommentar zu einem bestimmten Thema.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Konvertieren Sie Markdown-formatierten Text in Jiras ADF-Syntax für Kommentare und Beschreibungen usw.",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Project ID or Key": "Projekt-ID oder Schlüssel",
|
||||
"Issue Type": "Ticket-Typ",
|
||||
"Fields": "Felder",
|
||||
"Fields in JSON Atlassian Document Format": "Felder im JSON Atlassian Document Format",
|
||||
"Issue ID or Key": "Ticket-ID oder Schlüssel",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Maximale Ergebnisse",
|
||||
"Sanitize JQL": "JQL sanitizen",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Anhang",
|
||||
"Attachment ID": "Anhang-ID",
|
||||
"User": "Benutzer",
|
||||
"Comment Body": "Kommentar-Text",
|
||||
"Comment is in JSON Atlassian Document Format": "Kommentar ist im JSON Atlassian Document Format",
|
||||
"Comment ID": "Kommentar-ID",
|
||||
"First Issue": "Erster Fall",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Zweiter Fall",
|
||||
"Order By": "Sortieren nach",
|
||||
"Limit": "Limit",
|
||||
"Markdown text": "Markdown Text",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopfzeilen",
|
||||
"Query Parameters": "Abfrageparameter",
|
||||
"Body": "Körper",
|
||||
"Response is Binary ?": "Antwort ist binär?",
|
||||
"No Error on Failure": "Kein Fehler bei Fehler",
|
||||
"Timeout (in seconds)": "Timeout (in Sekunden)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "Die JQL-Abfrage für die Suche",
|
||||
"Maximum number of results": "Maximale Anzahl der Ergebnisse",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
|
||||
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
|
||||
"Created (Descending)": "Erstellt (absteigend)",
|
||||
"Created (Ascending)": "Erstellt (absteigend)",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "Neuer Fall",
|
||||
"Updated Issue": "Aktualisierter Fall",
|
||||
"Updated Issue Status": "Aktualisierter Ticket Status",
|
||||
"Triggers when a new issue is created": "Wird ausgelöst, wenn ein neues Problem erstellt wird",
|
||||
"Triggers when an issue is updated": "Wird ausgelöst, wenn ein Problem aktualisiert wird",
|
||||
"Triggers when an issue status is updated": "Wird ausgelöst, wenn ein Ticket Status aktualisiert wird",
|
||||
"Use to filter issues watched": "Verwende es, um beobachtete Probleme zu filtern"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Seguimiento de incidencias y gestión de proyectos",
|
||||
"Instance URL": "URL de instancia",
|
||||
"Email": "E-mail",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "El enlace de su instancia de Jira (ej. https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "El correo electrónico que utiliza para iniciar sesión en Jira",
|
||||
"Your Jira API Token": "Tu token de API de Jira",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Crear asunto",
|
||||
"Update Issue": "Actualizar problema",
|
||||
"Find User": "Buscar usuario",
|
||||
"Search Issues": "Buscar problemas",
|
||||
"Assign Issue": "Asignar asunto",
|
||||
"Add Attachment to Issue": "Añadir adjunto al problema",
|
||||
"Get Issue Attachment": "Obtener archivo adjunto del problema",
|
||||
"Add Watcher to Issue": "Añadir Watcher al asunto",
|
||||
"Add Issue Comment": "Añadir comentario del asunto",
|
||||
"Update Issue Comment": "Actualizar comentario del problema",
|
||||
"Link Issues": "Problemas de enlace",
|
||||
"List Issue Comments": "Listar comentarios del problema",
|
||||
"Delete Issue Comment": "Eliminar Comentario del Problema",
|
||||
"Markdown to Jira format": "Formato Markdown a Jira",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Creates a new issue in a project.": "Crea un nuevo asunto en un proyecto.",
|
||||
"Updates an existing issue.": "Actualiza un problema existente.",
|
||||
"Finds an existing user.": "Encuentra un usuario existente.",
|
||||
"Search for issues with JQL": "Buscar problemas con JQL",
|
||||
"Assigns an issue to a user.": "Asigna un problema a un usuario.",
|
||||
"Adds an attachment to an issue.": "Añade un archivo adjunto a un problema.",
|
||||
"Retrieves an attachment from an issue.": "Recuperar un archivo adjunto de un problema.",
|
||||
"Adds a new watcher to an issue.": "Añade un nuevo observador a un problema.",
|
||||
"Adds a comment to an issue.": "Añade un comentario a un problema.",
|
||||
"Updates a comment to a specific issue.": "Actualiza un comentario a un asunto específico.",
|
||||
"Creates a link between two issues.": "Crea un enlace entre dos cuestiones.",
|
||||
"Returns all comments for an issue.": "Devuelve todos los comentarios para un problema.",
|
||||
"Deletes a comment on a specific issue.": "Elimina un comentario sobre un asunto específico.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Convierte el texto con formato Markdown a la sintaxis ADF de Jira para usarlo en comentarios y descripciones, etc.",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Project ID or Key": "ID o clave del proyecto",
|
||||
"Issue Type": "Tipo de asunto",
|
||||
"Fields": "Campos",
|
||||
"Fields in JSON Atlassian Document Format": "Campos en formato JSON Atlassian Document",
|
||||
"Issue ID or Key": "Emitir ID o Clave",
|
||||
"Status": "Estado",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Resultados máximos",
|
||||
"Sanitize JQL": "Sanitizar JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Adjunto",
|
||||
"Attachment ID": "ID de adjunto",
|
||||
"User": "Usuario",
|
||||
"Comment Body": "Comentar cuerpo",
|
||||
"Comment is in JSON Atlassian Document Format": "El comentario está en formato JSON Atlassian Document",
|
||||
"Comment ID": "Comentario ID",
|
||||
"First Issue": "Primer asunto",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Segundo problema",
|
||||
"Order By": "Ordenar por",
|
||||
"Limit": "Límite",
|
||||
"Markdown text": "Texto Markdown",
|
||||
"Method": "Método",
|
||||
"Headers": "Encabezados",
|
||||
"Query Parameters": "Parámetros de consulta",
|
||||
"Body": "Cuerpo",
|
||||
"Response is Binary ?": "¿Respuesta es binaria?",
|
||||
"No Error on Failure": "No hay ningún error en fallo",
|
||||
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "La consulta JQL a usar en la búsqueda",
|
||||
"Maximum number of results": "Número máximo de resultados",
|
||||
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
|
||||
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
|
||||
"Created (Descending)": "Creado (Descendente)",
|
||||
"Created (Ascending)": "Creado (Ascendente)",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO",
|
||||
"New Issue": "Nuevo problema",
|
||||
"Updated Issue": "Problema actualizado",
|
||||
"Updated Issue Status": "Estado del asunto actualizado",
|
||||
"Triggers when a new issue is created": "Desencadena cuando se crea un nuevo problema",
|
||||
"Triggers when an issue is updated": "Dispara cuando se actualiza un problema",
|
||||
"Triggers when an issue status is updated": "Dispara cuando se actualiza el estado de una incidencia",
|
||||
"Use to filter issues watched": "Utilizar para filtrar problemas vistos"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Suivi des anomalies et gestion des projets",
|
||||
"Instance URL": "URL de l'instance",
|
||||
"Email": "Courriel",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "Le lien de votre instance Jira (par exemple https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "L'e-mail que vous utilisez pour vous connecter à Jira",
|
||||
"Your Jira API Token": "Votre jeton API Jira",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nVous pouvez générer votre jeton API depuis :\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Créer un problème",
|
||||
"Update Issue": "Mettre à jour le problème",
|
||||
"Find User": "Trouver un utilisateur",
|
||||
"Search Issues": "Rechercher des problèmes",
|
||||
"Assign Issue": "Assigner un ticket",
|
||||
"Add Attachment to Issue": "Ajouter une pièce jointe au ticket",
|
||||
"Get Issue Attachment": "Récupérer la pièce jointe",
|
||||
"Add Watcher to Issue": "Ajouter un observateur au ticket",
|
||||
"Add Issue Comment": "Ajouter un commentaire à un problème",
|
||||
"Update Issue Comment": "Commentaire de mise à jour du problème",
|
||||
"Link Issues": "Lier les tickets",
|
||||
"List Issue Comments": "Lister les commentaires de problèmes",
|
||||
"Delete Issue Comment": "Supprimer le commentaire du problème",
|
||||
"Markdown to Jira format": "Format Markdown vers Jira",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Creates a new issue in a project.": "Crée un nouveau ticket dans un projet.",
|
||||
"Updates an existing issue.": "Met à jour un ticket existant.",
|
||||
"Finds an existing user.": "Trouve un utilisateur existant.",
|
||||
"Search for issues with JQL": "Rechercher des problèmes avec JQL",
|
||||
"Assigns an issue to a user.": "Assigne un ticket à un utilisateur.",
|
||||
"Adds an attachment to an issue.": "Ajoute une pièce jointe à un ticket.",
|
||||
"Retrieves an attachment from an issue.": "Récupère une pièce jointe à partir d'un ticket.",
|
||||
"Adds a new watcher to an issue.": "Ajoute un nouveau observateur à un ticket.",
|
||||
"Adds a comment to an issue.": "Ajoute un commentaire à un ticket.",
|
||||
"Updates a comment to a specific issue.": "Met à jour un commentaire à un problème spécifique.",
|
||||
"Creates a link between two issues.": "Crée un lien entre deux tickets.",
|
||||
"Returns all comments for an issue.": "Renvoie tous les commentaires pour un ticket.",
|
||||
"Deletes a comment on a specific issue.": "Supprime un commentaire sur un problème spécifique.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Convertir le texte formaté par Markdown en syntaxe ADF de Jira pour l'utiliser dans les commentaires et descriptions etc",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Project ID or Key": "ID ou clé du projet",
|
||||
"Issue Type": "Type de problème",
|
||||
"Fields": "Champs",
|
||||
"Fields in JSON Atlassian Document Format": "Champs au format JSON Atlassian Document",
|
||||
"Issue ID or Key": "ID du ticket ou clé",
|
||||
"Status": "Statut",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Nombre maximum de résultats",
|
||||
"Sanitize JQL": "Assainissement JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Pièce jointe",
|
||||
"Attachment ID": "ID de la pièce jointe",
|
||||
"User": "Utilisateur",
|
||||
"Comment Body": "Corps du commentaire",
|
||||
"Comment is in JSON Atlassian Document Format": "Le commentaire est en format JSON Atlassian Document",
|
||||
"Comment ID": "ID du commentaire",
|
||||
"First Issue": "Premier problème",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Deuxième problème",
|
||||
"Order By": "Trier par",
|
||||
"Limit": "Limite",
|
||||
"Markdown text": "Texte Markdown",
|
||||
"Method": "Méthode",
|
||||
"Headers": "En-têtes",
|
||||
"Query Parameters": "Paramètres de requête",
|
||||
"Body": "Corps",
|
||||
"Response is Binary ?": "La réponse est Binaire ?",
|
||||
"No Error on Failure": "Aucune erreur en cas d'échec",
|
||||
"Timeout (in seconds)": "Délai d'attente (en secondes)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "La requête JQL à utiliser dans la recherche",
|
||||
"Maximum number of results": "Nombre maximum de résultats",
|
||||
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
|
||||
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
|
||||
"Created (Descending)": "Créé (Descendant)",
|
||||
"Created (Ascending)": "Créé (Ascendant)",
|
||||
"GET": "OBTENIR",
|
||||
"POST": "POSTER",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "EFFACER",
|
||||
"DELETE": "SUPPRIMER",
|
||||
"HEAD": "TÊTE",
|
||||
"New Issue": "Nouveau problème",
|
||||
"Updated Issue": "Problème mis à jour",
|
||||
"Updated Issue Status": "Statut du problème mis à jour",
|
||||
"Triggers when a new issue is created": "Déclenche quand un nouveau ticket est créé",
|
||||
"Triggers when an issue is updated": "Déclenche quand un problème est mis à jour",
|
||||
"Triggers when an issue status is updated": "Déclenche quand un statut de ticket est mis à jour",
|
||||
"Use to filter issues watched": "Utiliser pour filtrer les problèmes vus"
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"Jira Cloud": "Jira Cloud",
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "Email",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "User",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"Jira Cloud": "Jira Cloud",
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "Email",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "User",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "課題の追跡とプロジェクト管理",
|
||||
"Instance URL": "インスタンス URL",
|
||||
"Email": "Eメールアドレス",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "Jiraインスタンスのリンク (https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "Jiraにログインするために使用するメールアドレス",
|
||||
"Your Jira API Token": "Jira API トークン",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\n以下からAPIトークンを生成できます:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "課題を作成",
|
||||
"Update Issue": "問題を更新",
|
||||
"Find User": "ユーザーを検索",
|
||||
"Search Issues": "問題を検索",
|
||||
"Assign Issue": "課題を割り当てる",
|
||||
"Add Attachment to Issue": "課題に添付ファイルを追加",
|
||||
"Get Issue Attachment": "課題の添付を取得",
|
||||
"Add Watcher to Issue": "ワッチャーを課題に追加",
|
||||
"Add Issue Comment": "課題コメントを追加",
|
||||
"Update Issue Comment": "課題のコメントを更新",
|
||||
"Link Issues": "問題をリンクする",
|
||||
"List Issue Comments": "課題のコメントを一覧表示",
|
||||
"Delete Issue Comment": "課題のコメントを削除",
|
||||
"Markdown to Jira format": "Markdown to Jira format",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Creates a new issue in a project.": "プロジェクトで新しい課題を作成します。",
|
||||
"Updates an existing issue.": "既存の問題を更新します。",
|
||||
"Finds an existing user.": "既存のユーザーを検索します。",
|
||||
"Search for issues with JQL": "JQL での課題を検索",
|
||||
"Assigns an issue to a user.": "ユーザに課題を割り当てます。",
|
||||
"Adds an attachment to an issue.": "課題に添付ファイルを追加します。",
|
||||
"Retrieves an attachment from an issue.": "課題から添付ファイルを取得します。",
|
||||
"Adds a new watcher to an issue.": "新しいウォッチャーを課題に追加します。",
|
||||
"Adds a comment to an issue.": "課題にコメントを追加します。",
|
||||
"Updates a comment to a specific issue.": "特定の課題にコメントを更新します。",
|
||||
"Creates a link between two issues.": "2つの課題間のリンクを作成します。",
|
||||
"Returns all comments for an issue.": "課題のすべてのコメントを返します。",
|
||||
"Deletes a comment on a specific issue.": "特定の課題に関するコメントを削除します。",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "コメントや説明などに使用するために、Markdown形式のテキストをJiraのADF構文に変換する",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Project ID or Key": "プロジェクト ID またはキー",
|
||||
"Issue Type": "課題の種類",
|
||||
"Fields": "フィールド",
|
||||
"Fields in JSON Atlassian Document Format": "JSON Atlassian ドキュメント形式のフィールド",
|
||||
"Issue ID or Key": "課題 ID またはキー",
|
||||
"Status": "ステータス",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "最大結果",
|
||||
"Sanitize JQL": "JQL サニタイズ",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "添付ファイル",
|
||||
"Attachment ID": "添付ファイルID",
|
||||
"User": "ユーザー",
|
||||
"Comment Body": "コメント本文",
|
||||
"Comment is in JSON Atlassian Document Format": "コメントは JSON Atlassian ドキュメントフォーマットにあります",
|
||||
"Comment ID": "コメント ID",
|
||||
"First Issue": "最初の課題",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "2号目",
|
||||
"Order By": "並び替え",
|
||||
"Limit": "制限",
|
||||
"Markdown text": "Markdown テキスト",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "検索で使用する JQL クエリ",
|
||||
"Maximum number of results": "結果の最大数",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"Created (Descending)": "作成済み (降順)",
|
||||
"Created (Ascending)": "作成されました (昇順)",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭",
|
||||
"New Issue": "新しい課題",
|
||||
"Updated Issue": "更新された課題",
|
||||
"Updated Issue Status": "更新された課題ステータス",
|
||||
"Triggers when a new issue is created": "新しい課題が作成されたときにトリガーする",
|
||||
"Triggers when an issue is updated": "課題が更新されたときに発生する",
|
||||
"Triggers when an issue status is updated": "課題の状態が更新されたときに発行されます",
|
||||
"Use to filter issues watched": "監視されている課題をフィルタリングするために使用します"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Probleem bijhouden en projectbeheer",
|
||||
"Instance URL": "Aanleg URL",
|
||||
"Email": "E-mail",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "De link van uw Jira exemplaar (bijv. https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "De e-mail die u gebruikt om in te loggen op Jira",
|
||||
"Your Jira API Token": "Je Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nU kunt uw API-token genereren van:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Probleem aanmaken",
|
||||
"Update Issue": "Probleem bijwerken",
|
||||
"Find User": "Gebruiker zoeken",
|
||||
"Search Issues": "Problemen zoeken",
|
||||
"Assign Issue": "Issue toewijzen",
|
||||
"Add Attachment to Issue": "Bijlage toevoegen aan issue",
|
||||
"Get Issue Attachment": "Verkrijg issue-bijlage",
|
||||
"Add Watcher to Issue": "Voeg Watcher toe aan Issue",
|
||||
"Add Issue Comment": "Issue Opmerking toevoegen",
|
||||
"Update Issue Comment": "Wijzig probleemreactie",
|
||||
"Link Issues": "Koppel problemen",
|
||||
"List Issue Comments": "Issue reacties weergeven",
|
||||
"Delete Issue Comment": "Issue Opmerking verwijderen",
|
||||
"Markdown to Jira format": "Markdown naar Jira formaat",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Maakt een nieuw issue aan in een project.",
|
||||
"Updates an existing issue.": "Werkt een bestaand probleem bij.",
|
||||
"Finds an existing user.": "Vindt een bestaande gebruiker.",
|
||||
"Search for issues with JQL": "Zoek naar issues met JQL",
|
||||
"Assigns an issue to a user.": "Wijst een issue toe aan een gebruiker.",
|
||||
"Adds an attachment to an issue.": "Voegt een bijlage toe aan een probleem.",
|
||||
"Retrieves an attachment from an issue.": "Haal een bijlage op van een probleem.",
|
||||
"Adds a new watcher to an issue.": "Voegt een nieuwe watcher toe aan een probleem.",
|
||||
"Adds a comment to an issue.": "Voegt een reactie toe aan een probleem.",
|
||||
"Updates a comment to a specific issue.": "Werkt een opmerking bij een specifiek probleem.",
|
||||
"Creates a link between two issues.": "Maakt een verband tussen twee problemen.",
|
||||
"Returns all comments for an issue.": "Geeft als resultaat alle reacties op een probleem.",
|
||||
"Deletes a comment on a specific issue.": "Verwijdert een reactie op een specifiek probleem.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Converteer markdown-geformatteerde tekst naar Jira's ADF-syntaxis voor gebruik in commentaren en beschrijvingen enz",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Project ID or Key": "Project ID of sleutel",
|
||||
"Issue Type": "Type probleem",
|
||||
"Fields": "Velden",
|
||||
"Fields in JSON Atlassian Document Format": "Velden in JSON Atlassian Document Formaat",
|
||||
"Issue ID or Key": "Issue ID of sleutel",
|
||||
"Status": "status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max. aantal resultaten",
|
||||
"Sanitize JQL": "Sanitiseer JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Bijlage",
|
||||
"Attachment ID": "Bijlage ID",
|
||||
"User": "Gebruiker",
|
||||
"Comment Body": "Commentaar inhoud",
|
||||
"Comment is in JSON Atlassian Document Format": "Commentaar is in JSON Atlassian Document Formaat",
|
||||
"Comment ID": "Commentaar ID",
|
||||
"First Issue": "Eerste probleem",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Tweede probleem",
|
||||
"Order By": "Sorteer op",
|
||||
"Limit": "Limiet",
|
||||
"Markdown text": "Markdown tekst",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopteksten",
|
||||
"Query Parameters": "Query parameters",
|
||||
"Body": "Lichaam",
|
||||
"Response is Binary ?": "Antwoord is binair?",
|
||||
"No Error on Failure": "Geen fout bij fout",
|
||||
"Timeout (in seconds)": "Time-out (in seconden)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structuur",
|
||||
"The JQL query to use in the search": "De JQL query te gebruiken in de zoekopdracht",
|
||||
"Maximum number of results": "Maximum aantal resultaten",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
|
||||
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
|
||||
"Created (Descending)": "Gemaakt (aflopend)",
|
||||
"Created (Ascending)": "Aangemaakt (Ascending)",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD",
|
||||
"New Issue": "Nieuw probleem",
|
||||
"Updated Issue": "Probleem bijgewerkt",
|
||||
"Updated Issue Status": "Bijgewerkte probleemstatus",
|
||||
"Triggers when a new issue is created": "Triggert wanneer een nieuw issue wordt aangemaakt",
|
||||
"Triggers when an issue is updated": "Triggert wanneer een issue wordt bijgewerkt",
|
||||
"Triggers when an issue status is updated": "Triggert wanneer een issuestatus wordt bijgewerkt",
|
||||
"Use to filter issues watched": "Gebruik om problemen te filteren"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Acompanhamento de problemas e gerenciamento de projetos",
|
||||
"Instance URL": "Instância URL",
|
||||
"Email": "e-mail",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "O link da sua instância do Jira (ex: https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "O e-mail que você usa para acessar o Jira",
|
||||
"Your Jira API Token": "Token de API Jira",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nVocê pode gerar o seu token de API em:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Criar issue",
|
||||
"Update Issue": "Atualizar issue",
|
||||
"Find User": "Localizar usuário",
|
||||
"Search Issues": "Pesquisar Problemas",
|
||||
"Assign Issue": "Atribuir Issue",
|
||||
"Add Attachment to Issue": "Adicionar anexo à issue",
|
||||
"Get Issue Attachment": "Obter Anexo da Solicitação",
|
||||
"Add Watcher to Issue": "Adicionar Watcher à Issue",
|
||||
"Add Issue Comment": "Adicionar comentário à issue",
|
||||
"Update Issue Comment": "Atualizar comentário da issue",
|
||||
"Link Issues": "Ligar issues",
|
||||
"List Issue Comments": "Listar Comentários da Solicitação",
|
||||
"Delete Issue Comment": "Excluir comentário da issue",
|
||||
"Markdown to Jira format": "Formato Jira Markdown",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Creates a new issue in a project.": "Cria uma nova issue em um projeto.",
|
||||
"Updates an existing issue.": "Atualiza uma issue existente.",
|
||||
"Finds an existing user.": "Localiza um usuário existente.",
|
||||
"Search for issues with JQL": "Pesquisar por problemas com JQL",
|
||||
"Assigns an issue to a user.": "Atribui uma issue a um usuário.",
|
||||
"Adds an attachment to an issue.": "Adiciona um anexo a uma issue.",
|
||||
"Retrieves an attachment from an issue.": "Recupera um anexo de uma issue.",
|
||||
"Adds a new watcher to an issue.": "Adiciona um novo observador a uma issue.",
|
||||
"Adds a comment to an issue.": "Adiciona um comentário a uma issue.",
|
||||
"Updates a comment to a specific issue.": "Atualiza um comentário para uma issue específica.",
|
||||
"Creates a link between two issues.": "Cria uma ligação entre duas issues.",
|
||||
"Returns all comments for an issue.": "Retorna todos os comentários para uma issue.",
|
||||
"Deletes a comment on a specific issue.": "Exclui um comentário em uma issue específica.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Converter texto formatado em Markdown-formatado para sintaxe ADF da Jaria para uso em comentários e descrições, etc.",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Project ID or Key": "ID ou Chave do Projeto",
|
||||
"Issue Type": "Tipo de problema",
|
||||
"Fields": "campos",
|
||||
"Fields in JSON Atlassian Document Format": "Campos no formato de documento JSON Atlassian",
|
||||
"Issue ID or Key": "ID ou Chave de Problema",
|
||||
"Status": "Estado",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "QEQ",
|
||||
"Max Results": "Resultados no Máx.",
|
||||
"Sanitize JQL": "JQL Sanitizado",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Anexo",
|
||||
"Attachment ID": "ID do anexo",
|
||||
"User": "Usuário",
|
||||
"Comment Body": "Corpo do Comentário",
|
||||
"Comment is in JSON Atlassian Document Format": "Comentário está em formato de documento JSON Atlassian",
|
||||
"Comment ID": "ID do comentário",
|
||||
"First Issue": "Primeira Solicitação",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Segunda questão",
|
||||
"Order By": "Ordenar Por",
|
||||
"Limit": "Limitar",
|
||||
"Markdown text": "Texto Markdown",
|
||||
"Method": "Método",
|
||||
"Headers": "Cabeçalhos",
|
||||
"Query Parameters": "Parâmetros da consulta",
|
||||
"Body": "Conteúdo",
|
||||
"Response is Binary ?": "A resposta é binária ?",
|
||||
"No Error on Failure": "Nenhum erro no Failure",
|
||||
"Timeout (in seconds)": "Tempo limite (em segundos)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "A consulta JQL a ser usada na busca",
|
||||
"Maximum number of results": "Número máximo de resultados",
|
||||
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
|
||||
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
|
||||
"Created (Descending)": "Criado (decrescente)",
|
||||
"Created (Ascending)": "Criado (Ascendente)",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA",
|
||||
"New Issue": "Nova issue",
|
||||
"Updated Issue": "Issue atualizada",
|
||||
"Updated Issue Status": "Status atualizado da tarefa",
|
||||
"Triggers when a new issue is created": "Dispara quando uma nova issue é criada",
|
||||
"Triggers when an issue is updated": "Dispara quando uma issue é atualizada",
|
||||
"Triggers when an issue status is updated": "Aciona quando um status de issue é atualizado",
|
||||
"Use to filter issues watched": "Use para filtrar issues assistidas"
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"Jira Cloud": "Облако Jira",
|
||||
"Issue tracking and project management": "Отслеживание проблем и управление проектами",
|
||||
"Instance URL": "URL экземпляра",
|
||||
"Email": "Почта",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "Ссылка вашего экземпляра Jira (например https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "Электронная почта, которую вы используете для входа в Jira",
|
||||
"Your Jira API Token": "Ваш Jira API токен",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nВы можете сгенерировать ваш API токен из:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Создать запрос",
|
||||
"Update Issue": "Проблема с обновлением",
|
||||
"Find User": "Найти пользователя",
|
||||
"Search Issues": "Поиск проблем",
|
||||
"Assign Issue": "Назначить задачу",
|
||||
"Add Attachment to Issue": "Добавить вложение в запрос",
|
||||
"Get Issue Attachment": "Получить вложение задач",
|
||||
"Add Watcher to Issue": "Добавить наблюдателя к проблеме",
|
||||
"Add Issue Comment": "Добавить комментарий проблемы",
|
||||
"Update Issue Comment": "Комментарий об ошибке обновления",
|
||||
"Link Issues": "Ссылка на Замечания",
|
||||
"List Issue Comments": "Комментарии к выпуску",
|
||||
"Delete Issue Comment": "Удалить комментарий к проблеме",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Creates a new issue in a project.": "Создает новый запрос в проекте.",
|
||||
"Updates an existing issue.": "Обновляет существующую проблему.",
|
||||
"Finds an existing user.": "Поиск существующего пользователя.",
|
||||
"Search for issues with JQL": "Поиск проблем с JQL",
|
||||
"Assigns an issue to a user.": "Присвоить запрос пользователю.",
|
||||
"Adds an attachment to an issue.": "Добавляет вложение к задаче.",
|
||||
"Retrieves an attachment from an issue.": "Извлекает вложение из проблемы.",
|
||||
"Adds a new watcher to an issue.": "Добавляет нового наблюдателя к задаче.",
|
||||
"Adds a comment to an issue.": "Добавляет комментарий к проблеме.",
|
||||
"Updates a comment to a specific issue.": "Обновляет комментарий к конкретной проблеме.",
|
||||
"Creates a link between two issues.": "Создает связь между двумя задачами.",
|
||||
"Returns all comments for an issue.": "Возвращает все комментарии к проблеме.",
|
||||
"Deletes a comment on a specific issue.": "Удаляет комментарий к конкретной задаче.",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Project ID or Key": "ID проекта или ключ",
|
||||
"Issue Type": "Тип задачи",
|
||||
"Fields": "Поля",
|
||||
"Issue ID or Key": "ID задачи или ключ",
|
||||
"Status": "Статус",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Макс. результатов",
|
||||
"Sanitize JQL": "Санитизировать JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Вложение",
|
||||
"Attachment ID": "ID вложения",
|
||||
"User": "Пользователь",
|
||||
"Comment Body": "Тело комментария",
|
||||
"Comment ID": "ID комментария",
|
||||
"First Issue": "Первая задача",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Вторая задача",
|
||||
"Order By": "Сортировать по",
|
||||
"Limit": "Лимит",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"The JQL query to use in the search": "JQL запрос для использования в поиске",
|
||||
"Maximum number of results": "Максимальное количество результатов",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"Created (Descending)": "Создано (по убыванию)",
|
||||
"Created (Ascending)": "Создано (по возрастанию)",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "Новая задача",
|
||||
"Updated Issue": "Задача обновлена",
|
||||
"Updated Issue Status": "Статус задачи обновлен",
|
||||
"Triggers when a new issue is created": "Триггеры при создании новой задачи",
|
||||
"Triggers when an issue is updated": "Триггеры при обновлении задачи",
|
||||
"Triggers when an issue status is updated": "Триггеры при обновлении статуса задачи",
|
||||
"Use to filter issues watched": "Использовать для фильтрации задач просмотрено"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "Email",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Markdown to Jira format": "Markdown to Jira format",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Fields in JSON Atlassian Document Format": "Fields in JSON Atlassian Document Format",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "User",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment is in JSON Atlassian Document Format": "Comment is in JSON Atlassian Document Format",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Markdown text": "Markdown text",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"Jira Cloud": "Jira Cloud",
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "Email",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "Status",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "User",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"Issue tracking and project management": "Issue tracking and project management",
|
||||
"Instance URL": "Instance URL",
|
||||
"Email": "电子邮件地址",
|
||||
"API Token": "API Token",
|
||||
"The link of your Jira instance (e.g https://example.atlassian.net)": "The link of your Jira instance (e.g https://example.atlassian.net)",
|
||||
"The email you use to login to Jira": "The email you use to login to Jira",
|
||||
"Your Jira API Token": "Your Jira API Token",
|
||||
"\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ": "\nYou can generate your API token from:\n***https://id.atlassian.com/manage-profile/security/api-tokens***\n ",
|
||||
"Create Issue": "Create Issue",
|
||||
"Update Issue": "Update Issue",
|
||||
"Find User": "Find User",
|
||||
"Search Issues": "Search Issues",
|
||||
"Assign Issue": "Assign Issue",
|
||||
"Add Attachment to Issue": "Add Attachment to Issue",
|
||||
"Get Issue Attachment": "Get Issue Attachment",
|
||||
"Add Watcher to Issue": "Add Watcher to Issue",
|
||||
"Add Issue Comment": "Add Issue Comment",
|
||||
"Update Issue Comment": "Update Issue Comment",
|
||||
"Link Issues": "Link Issues",
|
||||
"List Issue Comments": "List Issue Comments",
|
||||
"Delete Issue Comment": "Delete Issue Comment",
|
||||
"Markdown to Jira format": "Markdown to Jira format",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Creates a new issue in a project.": "Creates a new issue in a project.",
|
||||
"Updates an existing issue.": "Updates an existing issue.",
|
||||
"Finds an existing user.": "Finds an existing user.",
|
||||
"Search for issues with JQL": "Search for issues with JQL",
|
||||
"Assigns an issue to a user.": "Assigns an issue to a user.",
|
||||
"Adds an attachment to an issue.": "Adds an attachment to an issue.",
|
||||
"Retrieves an attachment from an issue.": "Retrieves an attachment from an issue.",
|
||||
"Adds a new watcher to an issue.": "Adds a new watcher to an issue.",
|
||||
"Adds a comment to an issue.": "Adds a comment to an issue.",
|
||||
"Updates a comment to a specific issue.": "Updates a comment to a specific issue.",
|
||||
"Creates a link between two issues.": "Creates a link between two issues.",
|
||||
"Returns all comments for an issue.": "Returns all comments for an issue.",
|
||||
"Deletes a comment on a specific issue.": "Deletes a comment on a specific issue.",
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc": "Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Project ID or Key": "Project ID or Key",
|
||||
"Issue Type": "Issue Type",
|
||||
"Fields": "Fields",
|
||||
"Fields in JSON Atlassian Document Format": "Fields in JSON Atlassian Document Format",
|
||||
"Issue ID or Key": "Issue ID or Key",
|
||||
"Status": "状态",
|
||||
"Keyword": "Keyword",
|
||||
"JQL": "JQL",
|
||||
"Max Results": "Max Results",
|
||||
"Sanitize JQL": "Sanitize JQL",
|
||||
"Assignee": "Assignee",
|
||||
"Attachment": "Attachment",
|
||||
"Attachment ID": "Attachment ID",
|
||||
"User": "用户",
|
||||
"Comment Body": "Comment Body",
|
||||
"Comment is in JSON Atlassian Document Format": "Comment is in JSON Atlassian Document Format",
|
||||
"Comment ID": "Comment ID",
|
||||
"First Issue": "First Issue",
|
||||
"Link Type": "Link Type",
|
||||
"Second Issue": "Second Issue",
|
||||
"Order By": "Order By",
|
||||
"Limit": "Limit",
|
||||
"Markdown text": "Markdown text",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"https://developer.atlassian.com/cloud/jira/platform/apis/document/structure": "https://developer.atlassian.com/cloud/jira/platform/apis/document/structure",
|
||||
"The JQL query to use in the search": "The JQL query to use in the search",
|
||||
"Maximum number of results": "Maximum number of results",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Created (Descending)": "Created (Descending)",
|
||||
"Created (Ascending)": "Created (Ascending)",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色",
|
||||
"New Issue": "New Issue",
|
||||
"Updated Issue": "Updated Issue",
|
||||
"Updated Issue Status": "Updated Issue Status",
|
||||
"Triggers when a new issue is created": "Triggers when a new issue is created",
|
||||
"Triggers when an issue is updated": "Triggers when an issue is updated",
|
||||
"Triggers when an issue status is updated": "Triggers when an issue status is updated",
|
||||
"Use to filter issues watched": "Use to filter issues watched"
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { createPiece } from '@activepieces/pieces-framework';
|
||||
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { JiraAuth, jiraCloudAuth } from './auth';
|
||||
import { createIssueAction } from './lib/actions/create-issue';
|
||||
import { searchIssues } from './lib/actions/search-issues';
|
||||
import { newIssue } from './lib/triggers/new-issue';
|
||||
import { updatedIssue } from './lib/triggers/updated-issue';
|
||||
import { updatedIssueStatus } from './lib/triggers/updated-issue-status';
|
||||
import { addCommentToIssueAction } from './lib/actions/add-comment-to-issue';
|
||||
import { addAttachmentToIssueAction } from './lib/actions/add-attachment-to-issue';
|
||||
import { updateIssueCommentAction } from './lib/actions/update-issue-comment';
|
||||
import { deleteIssueCommentAction } from './lib/actions/delete-issue-comment';
|
||||
import { updateIssueAction } from './lib/actions/update-issue';
|
||||
import { assignIssueAction } from './lib/actions/assign-issue';
|
||||
import { listIssueCommentsAction } from './lib/actions/list-issue-comments';
|
||||
import { findUserAction } from './lib/actions/find-user';
|
||||
import { addWatcherToIssueAction } from './lib/actions/add-watcher-to-issue';
|
||||
import { linkIssuesAction } from './lib/actions/link-issues';
|
||||
import { getIssueAttachmentAction } from './lib/actions/get-issue-attachment';
|
||||
import { markdownToJiraFormat } from './lib/actions/markdown-to-jira-format';
|
||||
import { getIssueAction } from './lib/actions/get-issue';
|
||||
|
||||
export const jiraCloud = createPiece({
|
||||
displayName: 'Jira Cloud',
|
||||
description: 'Issue tracking and project management',
|
||||
|
||||
auth: jiraCloudAuth,
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/jira.png',
|
||||
categories: [PieceCategory.PRODUCTIVITY],
|
||||
authors: ['kishanprmr', 'MoShizzle', 'abuaboud', 'prasanna2000-max'],
|
||||
actions: [
|
||||
createIssueAction,
|
||||
updateIssueAction,
|
||||
findUserAction,
|
||||
searchIssues,
|
||||
assignIssueAction,
|
||||
addAttachmentToIssueAction,
|
||||
getIssueAttachmentAction,
|
||||
addWatcherToIssueAction,
|
||||
addCommentToIssueAction,
|
||||
updateIssueCommentAction,
|
||||
linkIssuesAction,
|
||||
listIssueCommentsAction,
|
||||
deleteIssueCommentAction,
|
||||
markdownToJiraFormat,
|
||||
getIssueAction,
|
||||
createCustomApiCallAction({
|
||||
baseUrl: (auth) => {
|
||||
return auth ? `${(auth).props.instanceUrl}/rest/api/3` : '';
|
||||
},
|
||||
auth: jiraCloudAuth,
|
||||
authMapping: async (auth) => {
|
||||
const typedAuth = auth as JiraAuth;
|
||||
return {
|
||||
Authorization: `Basic ${Buffer.from(`${typedAuth.props.email}:${typedAuth.props.apiToken}`).toString(
|
||||
'base64',
|
||||
)}`,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [newIssue, updatedIssue, updatedIssueStatus],
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import FormData from 'form-data';
|
||||
import { getProjectIdDropdown, getIssueIdDropdown } from '../common/props';
|
||||
|
||||
export const addAttachmentToIssueAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'add_issue_attachment',
|
||||
displayName: 'Add Attachment to Issue',
|
||||
description: 'Adds an attachment to an issue.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
attachment: Property.File({
|
||||
displayName: 'Attachment',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, attachment } = context.propsValue;
|
||||
const formData = new FormData();
|
||||
const fileBuffer = Buffer.from(attachment.base64, 'base64');
|
||||
formData.append('file', fileBuffer, attachment.filename);
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `issue/${issueId}/attachments`,
|
||||
auth: context.auth,
|
||||
headers: {
|
||||
'X-Atlassian-Token': 'no-check',
|
||||
...formData.getHeaders(),
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getIssueIdDropdown, getProjectIdDropdown } from '../common/props';
|
||||
|
||||
export const addCommentToIssueAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'add_issue_comment',
|
||||
displayName: 'Add Issue Comment',
|
||||
description: 'Adds a comment to an issue.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
comment: Property.LongText({
|
||||
displayName: 'Comment Body',
|
||||
required: true,
|
||||
}),
|
||||
isADF: Property.Checkbox({
|
||||
displayName: 'Comment is in JSON Atlassian Document Format',
|
||||
description: 'https://developer.atlassian.com/cloud/jira/platform/apis/document/structure',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, comment, isADF } = context.propsValue;
|
||||
|
||||
let commentBody = {}
|
||||
|
||||
if (isADF) {
|
||||
commentBody = JSON.parse(comment);
|
||||
} else {
|
||||
commentBody = {
|
||||
version: 1,
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: comment,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `issue/${issueId}/comment`,
|
||||
auth: context.auth,
|
||||
body: {
|
||||
body: commentBody,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { getUsersDropdown, issueIdOrKeyProp } from '../common/props';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { jiraApiCall } from '../common';
|
||||
import { HttpError, HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const addWatcherToIssueAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'add-watcher-to-issue',
|
||||
displayName: 'Add Watcher to Issue',
|
||||
description: 'Adds a new watcher to an issue.',
|
||||
props: {
|
||||
issueId: issueIdOrKeyProp('Issue ID or Key', true),
|
||||
userId: getUsersDropdown({
|
||||
displayName: 'User',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, userId } = context.propsValue;
|
||||
if (isNil(issueId)) {
|
||||
throw new Error('Issue ID is required');
|
||||
}
|
||||
if (isNil(userId)) {
|
||||
throw new Error('User ID is required');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await jiraApiCall({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/issue/${issueId}/watchers`,
|
||||
body: `"${userId}"`,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
return { success: false, error: (e as HttpError).message };
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getIssueIdDropdown, getProjectIdDropdown, getUsersDropdown } from '../common/props';
|
||||
|
||||
export const assignIssueAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'assign_issue',
|
||||
displayName: 'Assign Issue',
|
||||
description: 'Assigns an issue to a user.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
assignee: getUsersDropdown({
|
||||
displayName: 'Assignee',
|
||||
refreshers: ['projectId'],
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, assignee } = context.propsValue;
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.PUT,
|
||||
url: `issue/${issueId}/assignee`,
|
||||
auth: context.auth,
|
||||
body: {
|
||||
accountId: assignee,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,160 @@
|
||||
import { createAction, DynamicPropsValue, Property } from '@activepieces/pieces-framework';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import {
|
||||
getProjectIdDropdown,
|
||||
formatIssueFields,
|
||||
issueTypeIdProp,
|
||||
createPropertyDefinition,
|
||||
transformCustomFields,
|
||||
isFieldAdfCompatible,
|
||||
} from '../common/props';
|
||||
import { jiraApiCall, jiraPaginatedApiCall } from '../common';
|
||||
import { IssueFieldMetaData, VALID_CUSTOM_FIELD_TYPES } from '../common/types';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
async function getFields(auth: JiraAuth, projectId: string, issueTypeId: string): Promise<IssueFieldMetaData[]> {
|
||||
const fields = await jiraPaginatedApiCall<IssueFieldMetaData, 'fields'>({
|
||||
auth: auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/createmeta/${projectId}/issuetypes/${issueTypeId}`,
|
||||
propertyName: 'fields',
|
||||
});
|
||||
|
||||
if (!fields || !Array.isArray(fields)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
export const createIssueAction = createAction({
|
||||
name: 'create_issue',
|
||||
displayName: 'Create Issue',
|
||||
description: 'Creates a new issue in a project.',
|
||||
auth: jiraCloudAuth,
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueTypeId: issueTypeIdProp('Issue Type'),
|
||||
issueFields: Property.DynamicProperties({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Fields',
|
||||
required: true,
|
||||
refreshers: ['projectId', 'issueTypeId'],
|
||||
props: async ({ auth, projectId, issueTypeId }) => {
|
||||
if (!auth || !issueTypeId || !projectId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const props: DynamicPropsValue = {};
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const projectIdValue = projectId as unknown as string;
|
||||
const issueTypeIdValue = issueTypeId as unknown as string;
|
||||
|
||||
const fields = await getFields(authValue, projectIdValue, issueTypeIdValue);
|
||||
|
||||
for (const field of fields) {
|
||||
// skip invalid custom fields
|
||||
if (field.schema.custom) {
|
||||
const customFieldType = field.schema.custom.split(':')[1];
|
||||
if (!VALID_CUSTOM_FIELD_TYPES.includes(customFieldType)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (['project', 'issuetype'].includes(field.key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
props[field.key] = await createPropertyDefinition(authValue, field, field.required);
|
||||
}
|
||||
// Remove null props
|
||||
return Object.fromEntries(Object.entries(props).filter(([_, prop]) => prop !== null));
|
||||
},
|
||||
}),
|
||||
adfFields: Property.MultiSelectDropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Fields in JSON Atlassian Document Format',
|
||||
description: 'https://developer.atlassian.com/cloud/jira/platform/apis/document/structure',
|
||||
required: false,
|
||||
refreshers: ['projectId', 'issueTypeId'],
|
||||
options: async ({ auth, projectId, issueTypeId }) => {
|
||||
if (!auth || !issueTypeId || !projectId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const projectIdValue = projectId as unknown as string;
|
||||
const issueTypeIdValue = issueTypeId as unknown as string;
|
||||
|
||||
const fields = await getFields(authValue, projectIdValue, issueTypeIdValue);
|
||||
const adfCompatibleFields = fields.filter(isFieldAdfCompatible);
|
||||
const fieldOptions = adfCompatibleFields.map(field => ({
|
||||
label: field.name,
|
||||
value: field.key,
|
||||
}))
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: fieldOptions,
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { projectId, issueTypeId, adfFields } = context.propsValue;
|
||||
const inputIssueFields = context.propsValue.issueFields ?? {};
|
||||
|
||||
if (isNil(projectId) || isNil(issueTypeId)) {
|
||||
throw new Error('Project ID and Issue Type ID are required');
|
||||
}
|
||||
|
||||
const issueTypeFields = await jiraPaginatedApiCall<IssueFieldMetaData, 'fields'>({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/createmeta/${projectId}/issuetypes/${issueTypeId}`,
|
||||
propertyName: 'fields',
|
||||
});
|
||||
|
||||
const formattedAdfFields = adfFields || [];
|
||||
const formattedFields = formatIssueFields(issueTypeFields, inputIssueFields, formattedAdfFields);
|
||||
|
||||
const response = await jiraApiCall<{ id: string; key: string }>({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/issue`,
|
||||
body: {
|
||||
fields: {
|
||||
issuetype: {
|
||||
id: issueTypeId,
|
||||
},
|
||||
project: {
|
||||
id: projectId,
|
||||
},
|
||||
...formattedFields,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const issue = await jiraApiCall<{
|
||||
expand: string;
|
||||
id: string;
|
||||
key: string;
|
||||
fields: Record<string, any>;
|
||||
}>({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/${response.id}`,
|
||||
});
|
||||
|
||||
const updatedIssueProperties = transformCustomFields(issueTypeFields, issue.fields);
|
||||
|
||||
return {
|
||||
...issue,
|
||||
fields: updatedIssueProperties,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
import { createAction, PiecePropValueSchema, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getIssueIdDropdown, getProjectIdDropdown } from '../common/props';
|
||||
|
||||
export const deleteIssueCommentAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'delete_issue_comment',
|
||||
displayName: 'Delete Issue Comment',
|
||||
description: 'Deletes a comment on a specific issue.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
commentId: Property.Dropdown<string, true, typeof jiraCloudAuth>({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Comment ID',
|
||||
refreshers: ['issueId'],
|
||||
required: true,
|
||||
options: async ({ auth, issueId }) => {
|
||||
if (!auth || !issueId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account and select issue.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `issue/${issueId}/comment`,
|
||||
auth: auth,
|
||||
queryParams: {
|
||||
orderBy: '-created',
|
||||
expand: 'renderedBody',
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.body.comments.map((comment: { id: string; renderedBody: string }) => {
|
||||
return {
|
||||
label: comment.renderedBody,
|
||||
value: comment.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, commentId } = context.propsValue;
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
url: `issue/${issueId}/comment/${commentId}`,
|
||||
auth: context.auth,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { jiraCloudAuth } from "../../auth";
|
||||
import { jiraApiCall } from "../common";
|
||||
import { HttpMethod } from "@activepieces/pieces-common";
|
||||
|
||||
export const findUserAction = createAction({
|
||||
auth:jiraCloudAuth,
|
||||
name:'find-user',
|
||||
displayName:'Find User',
|
||||
description:'Finds an existing user.',
|
||||
props:{
|
||||
keyword:Property.ShortText({
|
||||
displayName:'Keyword',
|
||||
required:true,
|
||||
})
|
||||
},
|
||||
async run(context){
|
||||
const response = await jiraApiCall<Array<Record<string,any>>>({
|
||||
auth:context.auth,
|
||||
method:HttpMethod.GET,
|
||||
resourceUri:'/user/search',
|
||||
query:{
|
||||
query:context.propsValue.keyword
|
||||
}
|
||||
})
|
||||
|
||||
return{
|
||||
found:response.length>0,
|
||||
data:response
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,48 @@
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { jiraCloudAuth } from "../../auth";
|
||||
import { jiraApiCall } from "../common";
|
||||
import { AuthenticationType, httpClient, HttpMethod } from "@activepieces/pieces-common";
|
||||
|
||||
export const getIssueAttachmentAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'get-issue-attachment',
|
||||
displayName: 'Get Issue Attachment',
|
||||
description: 'Retrieves an attachment from an issue.',
|
||||
props: {
|
||||
attachmentId: Property.ShortText({
|
||||
displayName: 'Attachment ID',
|
||||
required: true
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const { attachmentId } = context.propsValue;
|
||||
|
||||
// https://community.developer.atlassian.com/t/download-attachment-from-rest-api/40860/2
|
||||
const attachmentResponse = await jiraApiCall<{ filename: string, content: string }>({
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/attachment/${attachmentId}`,
|
||||
auth: context.auth,
|
||||
})
|
||||
|
||||
const { filename, content } = attachmentResponse;
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
url: content,
|
||||
method: HttpMethod.GET,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: context.auth.props.email,
|
||||
password: context.auth.props.apiToken,
|
||||
},
|
||||
responseType:'arraybuffer'
|
||||
})
|
||||
|
||||
return {
|
||||
...attachmentResponse,
|
||||
file: await context.files.write({
|
||||
fileName: filename,
|
||||
data: Buffer.from(response.body)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,158 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getIssueIdDropdown, getProjectIdDropdown } from '../common/props';
|
||||
|
||||
function mapFieldNames(
|
||||
fields: Record<string, any>,
|
||||
fieldNames: Record<string, string>
|
||||
) {
|
||||
const mappedFields = {} as Record<string, any>;
|
||||
|
||||
for (const [fieldId, fieldValue] of Object.entries(fields)) {
|
||||
const fieldName = fieldNames?.[fieldId];
|
||||
if (fieldName) {
|
||||
mappedFields[fieldName] = fieldValue;
|
||||
} else {
|
||||
// fallback in case field cannot be mapped (but this should not happen)
|
||||
mappedFields[fieldId] = fieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
return mappedFields;
|
||||
}
|
||||
|
||||
export const getIssueAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'get_issue',
|
||||
displayName: 'Get Issue',
|
||||
description: 'Get issue data.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
expand: Property.StaticMultiSelectDropdown({
|
||||
displayName: 'Expand',
|
||||
description:
|
||||
'Include additional information about the issue in the response',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{
|
||||
label: 'Rendered Fields',
|
||||
value: 'renderedFields',
|
||||
},
|
||||
{
|
||||
label: 'Names',
|
||||
value: 'names',
|
||||
},
|
||||
{
|
||||
label: 'Schema',
|
||||
value: 'schema',
|
||||
},
|
||||
{
|
||||
label: 'Transitions',
|
||||
value: 'transitions',
|
||||
},
|
||||
{
|
||||
label: 'Edit Meta',
|
||||
value: 'editmeta',
|
||||
},
|
||||
{
|
||||
label: 'Changelog',
|
||||
value: 'changelog',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
mapNames: Property.Checkbox({
|
||||
displayName: 'Map Field Names',
|
||||
description: `
|
||||
Map human readable names to Fields, Rendered Fields, Schema and Edit Meta.
|
||||
Notes:
|
||||
- This would implicitly add "names" to the expand field
|
||||
- If there are fields with the same name, they may be overridden
|
||||
`.trim(),
|
||||
required: true,
|
||||
defaultValue: false,
|
||||
}),
|
||||
mapTransitions: Property.Checkbox({
|
||||
displayName: 'Map Transition Names',
|
||||
description: `
|
||||
Map human readable names to Transitions.
|
||||
Notes:
|
||||
- If there are transitions with the same name, they may be overridden
|
||||
- This changes the original data structure from list to map
|
||||
`.trim(),
|
||||
required: true,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, expand, mapNames, mapTransitions } = context.propsValue;
|
||||
|
||||
const queryParams = {} as QueryParams;
|
||||
let expandParams = expand as string[];
|
||||
|
||||
// implicitly expand names which is needed for mapping
|
||||
if (mapNames) {
|
||||
expandParams = [...new Set(expandParams).add('names')];
|
||||
}
|
||||
|
||||
if (expandParams) {
|
||||
queryParams['expand'] = expandParams.join(',');
|
||||
}
|
||||
|
||||
// https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `issue/${issueId}`,
|
||||
auth: context.auth,
|
||||
queryParams: queryParams,
|
||||
});
|
||||
|
||||
const data = response.body;
|
||||
|
||||
if (mapNames) {
|
||||
const fieldNames = data.names || {};
|
||||
|
||||
const mappedFields = mapFieldNames(data.fields, fieldNames);
|
||||
data['fields'] = mappedFields;
|
||||
|
||||
if (data.renderedFields) {
|
||||
const mappedRenderedFields = mapFieldNames(
|
||||
data.renderedFields,
|
||||
fieldNames
|
||||
);
|
||||
data['renderedFields'] = mappedRenderedFields;
|
||||
}
|
||||
|
||||
if (data.schema) {
|
||||
const mappedSchemaFields = mapFieldNames(data.schema, fieldNames);
|
||||
data['schema'] = mappedSchemaFields;
|
||||
}
|
||||
|
||||
if (data.editmeta?.fields) {
|
||||
const mappedEditmetaFields = mapFieldNames(
|
||||
data.editmeta.fields,
|
||||
fieldNames
|
||||
);
|
||||
data['editmeta']['fields'] = mappedEditmetaFields;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapTransitions && data.transitions) {
|
||||
const mappedTransitions = data.transitions.reduce(
|
||||
(acc: Record<string, any>, transition: any) => {
|
||||
acc[transition.name] = transition;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
data['transitions'] = mappedTransitions;
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { issueIdOrKeyProp, issueLinkTypeIdProp } from '../common/props';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { HttpError, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { jiraApiCall } from '../common';
|
||||
|
||||
export const linkIssuesAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'link-issues',
|
||||
displayName: 'Link Issues',
|
||||
description: 'Creates a link between two issues.',
|
||||
props: {
|
||||
firstIssueId: issueIdOrKeyProp('First Issue', true),
|
||||
issueLinkTypeId: issueLinkTypeIdProp('Link Type', true),
|
||||
secondIssueId: issueIdOrKeyProp('Second Issue', true),
|
||||
},
|
||||
async run(context) {
|
||||
const { firstIssueId, issueLinkTypeId, secondIssueId } = context.propsValue;
|
||||
|
||||
if (isNil(firstIssueId) || isNil(issueLinkTypeId) || isNil(secondIssueId)) {
|
||||
throw new Error('First Issue, Link Type, and Second Issue are required');
|
||||
}
|
||||
try {
|
||||
const response = await jiraApiCall({
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: '/issueLink',
|
||||
auth: context.auth,
|
||||
body: {
|
||||
type: {
|
||||
id: issueLinkTypeId,
|
||||
},
|
||||
inwardIssue: {
|
||||
id: secondIssueId,
|
||||
},
|
||||
outwardIssue: {
|
||||
id: firstIssueId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
return { success: false, error: (e as HttpError).message };
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getProjectIdDropdown, getIssueIdDropdown } from '../common/props';
|
||||
|
||||
export const listIssueCommentsAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'list_issue_comments',
|
||||
displayName: 'List Issue Comments',
|
||||
description: 'Returns all comments for an issue.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
orderBy: Property.StaticDropdown({
|
||||
displayName: 'Order By',
|
||||
required: true,
|
||||
defaultValue: '-created',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{
|
||||
label: 'Created (Descending)',
|
||||
value: '-created',
|
||||
},
|
||||
{
|
||||
label: 'Created (Ascending)',
|
||||
value: '+created',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
limit: Property.Number({
|
||||
displayName: 'Limit',
|
||||
description: 'Maximum number of results',
|
||||
required: true,
|
||||
defaultValue: 10,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, orderBy, limit } = context.propsValue;
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `issue/${issueId}/comment`,
|
||||
auth: context.auth,
|
||||
queryParams: {
|
||||
orderBy: orderBy,
|
||||
maxResults: limit.toString(),
|
||||
expand: 'renderedBody',
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { defaultSchema } from '@atlaskit/adf-schema/schema-default';
|
||||
import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
||||
import { MarkdownTransformer } from '@atlaskit/editor-markdown-transformer';
|
||||
|
||||
export const markdownToJiraFormat = createAction({
|
||||
name: 'markdownToJiraFormat',
|
||||
displayName: 'Markdown to Jira format',
|
||||
description:
|
||||
"Convert Markdown-formatted text to Jira's ADF syntax for use in comments and descriptions etc",
|
||||
requireAuth: false,
|
||||
props: {
|
||||
markdown: Property.LongText({
|
||||
displayName: 'Markdown text',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true,
|
||||
},
|
||||
},
|
||||
async run({ propsValue }) {
|
||||
const jsonTransformer = new JSONTransformer();
|
||||
const markdownTransformer = new MarkdownTransformer(defaultSchema);
|
||||
|
||||
const adfDocument = jsonTransformer.encode(
|
||||
markdownTransformer.parse(propsValue.markdown)
|
||||
);
|
||||
|
||||
return adfDocument;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import {
|
||||
Property,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { searchIssuesByJql } from '../common';
|
||||
import { z } from 'zod';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
|
||||
export const searchIssues = createAction({
|
||||
name: 'search_issues',
|
||||
displayName: 'Search Issues',
|
||||
description: 'Search for issues with JQL',
|
||||
auth: jiraCloudAuth,
|
||||
props: {
|
||||
jql: Property.LongText({
|
||||
displayName: 'JQL',
|
||||
description: 'The JQL query to use in the search',
|
||||
defaultValue: `type = story and created > '2023-12-13 14:00'`,
|
||||
required: true,
|
||||
}),
|
||||
maxResults: Property.Number({
|
||||
displayName: 'Max Results',
|
||||
defaultValue: 50,
|
||||
required: true,
|
||||
}),
|
||||
sanitizeJql: Property.Checkbox({
|
||||
displayName: 'Sanitize JQL',
|
||||
required: true,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
run: async ({ auth, propsValue }) => {
|
||||
await propsValidation.validateZod(propsValue, {
|
||||
maxResults: z.number().min(1).max(100),
|
||||
});
|
||||
const { jql, maxResults, sanitizeJql } = propsValue;
|
||||
return await searchIssuesByJql({
|
||||
auth,
|
||||
jql,
|
||||
maxResults: maxResults,
|
||||
sanitizeJql,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
import { createAction, PiecePropValueSchema, Property } from '@activepieces/pieces-framework';
|
||||
import { jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { sendJiraRequest } from '../common';
|
||||
import { getIssueIdDropdown, getProjectIdDropdown } from '../common/props';
|
||||
|
||||
export const updateIssueCommentAction = createAction({
|
||||
auth: jiraCloudAuth,
|
||||
name: 'update_issue_comment',
|
||||
displayName: 'Update Issue Comment',
|
||||
description: 'Updates a comment to a specific issue.',
|
||||
props: {
|
||||
projectId: getProjectIdDropdown(),
|
||||
issueId: getIssueIdDropdown({ refreshers: ['projectId'] }),
|
||||
commentId: Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Comment ID',
|
||||
refreshers: ['issueId'],
|
||||
required: true,
|
||||
options: async ({ auth, issueId }) => {
|
||||
if (!auth || !issueId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account and select issue.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `issue/${issueId}/comment`,
|
||||
auth: auth,
|
||||
queryParams: {
|
||||
orderBy: '-created',
|
||||
expand: 'renderedBody',
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.body.comments.map((comment: { id: string; renderedBody: string }) => {
|
||||
return {
|
||||
label: comment.renderedBody,
|
||||
value: comment.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
comment: Property.LongText({
|
||||
displayName: 'Comment Body',
|
||||
required: true,
|
||||
}),
|
||||
isADF: Property.Checkbox({
|
||||
displayName: 'Comment is in JSON Atlassian Document Format',
|
||||
description: 'https://developer.atlassian.com/cloud/jira/platform/apis/document/structure',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, comment, commentId, isADF } = context.propsValue;
|
||||
|
||||
let commentBody = {}
|
||||
|
||||
if (isADF) {
|
||||
commentBody = JSON.parse(comment);
|
||||
} else {
|
||||
commentBody = {
|
||||
version: 1,
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: comment,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.PUT,
|
||||
url: `issue/${issueId}/comment/${commentId}`,
|
||||
auth: context.auth,
|
||||
body: {
|
||||
body: commentBody,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,182 @@
|
||||
import { DynamicPropsValue, Property, createAction } from '@activepieces/pieces-framework';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import {
|
||||
createPropertyDefinition,
|
||||
formatIssueFields,
|
||||
issueIdOrKeyProp,
|
||||
issueStatusIdProp,
|
||||
transformCustomFields,
|
||||
isFieldAdfCompatible,
|
||||
} from '../common/props';
|
||||
import { jiraApiCall } from '../common';
|
||||
import { IssueFieldMetaData, VALID_CUSTOM_FIELD_TYPES } from '../common/types';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
async function getFields(auth: JiraAuth, issueId: string): Promise<IssueFieldMetaData[]> {
|
||||
const response = await jiraApiCall<{ fields: { [x: string]: IssueFieldMetaData } }>({
|
||||
auth: auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/${issueId}/editmeta`,
|
||||
});
|
||||
|
||||
const fields: IssueFieldMetaData[] = [];
|
||||
for (const key in response.fields) {
|
||||
fields.push(response.fields[key]);
|
||||
}
|
||||
|
||||
if (!fields || !Array.isArray(fields)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
export const updateIssueAction = createAction({
|
||||
name: 'update_issue',
|
||||
displayName: 'Update Issue',
|
||||
description: 'Updates an existing issue.',
|
||||
auth: jiraCloudAuth,
|
||||
props: {
|
||||
issueId: issueIdOrKeyProp('Issue ID or Key', true),
|
||||
statusId: issueStatusIdProp('Status', false),
|
||||
issueFields: Property.DynamicProperties({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Fields',
|
||||
required: true,
|
||||
refreshers: ['issueId'],
|
||||
props: async ({ auth, issueId }) => {
|
||||
if (!auth || !issueId) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const props: DynamicPropsValue = {};
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const issueIdValue = issueId as unknown as string;
|
||||
|
||||
const fields = await getFields(authValue, issueIdValue);
|
||||
|
||||
for (const field of fields) {
|
||||
// skip invalid custom fields
|
||||
if (field.schema.custom) {
|
||||
const customFieldType = field.schema.custom.split(':')[1];
|
||||
if (!VALID_CUSTOM_FIELD_TYPES.includes(customFieldType)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (field.key === 'issuetype') {
|
||||
props[field.key] = Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
options: {
|
||||
disabled: false,
|
||||
options: field.allowedValues
|
||||
? field.allowedValues.map((option) => ({
|
||||
label: option.name,
|
||||
value: option.id,
|
||||
}))
|
||||
: [],
|
||||
},
|
||||
});
|
||||
} else {
|
||||
props[field.key] = await createPropertyDefinition(authValue, field, false);
|
||||
}
|
||||
}
|
||||
// Remove null props
|
||||
return Object.fromEntries(Object.entries(props).filter(([_, prop]) => prop !== null));
|
||||
},
|
||||
}),
|
||||
adfFields: Property.MultiSelectDropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: 'Fields in JSON Atlassian Document Format',
|
||||
description: 'https://developer.atlassian.com/cloud/jira/platform/apis/document/structure',
|
||||
required: false,
|
||||
refreshers: ['issueId'],
|
||||
options: async ({ auth, issueId }) => {
|
||||
if (!auth || !issueId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const issueIdValue = issueId as unknown as string;
|
||||
|
||||
const fields = await getFields(authValue, issueIdValue);
|
||||
const adfCompatibleFields = fields.filter(isFieldAdfCompatible);
|
||||
const fieldOptions = adfCompatibleFields.map(field => ({
|
||||
label: field.name,
|
||||
value: field.key,
|
||||
}))
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: fieldOptions,
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { issueId, statusId, adfFields } = context.propsValue;
|
||||
const inputIssueFields = context.propsValue.issueFields ?? {};
|
||||
|
||||
if (isNil(issueId)) {
|
||||
throw new Error('Issue ID is required');
|
||||
}
|
||||
|
||||
if (!isNil(statusId) && statusId !== '') {
|
||||
await jiraApiCall({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/issue/${issueId}/transitions`,
|
||||
body: {
|
||||
transition: {
|
||||
id: statusId,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const issueTypeFields = await jiraApiCall<{ fields: { [x: string]: IssueFieldMetaData } }>({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/${issueId}/editmeta`,
|
||||
});
|
||||
|
||||
const flattenedFields = Object.values(issueTypeFields.fields);
|
||||
|
||||
const formattedAdfFields = adfFields || [];
|
||||
const formattedFields = formatIssueFields(flattenedFields, inputIssueFields, formattedAdfFields);
|
||||
|
||||
const response = await jiraApiCall({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.PUT,
|
||||
resourceUri: `/issue/${issueId}`,
|
||||
body: {
|
||||
fields: formattedFields,
|
||||
},
|
||||
query: { returnIssue: 'true' },
|
||||
});
|
||||
|
||||
const issue = await jiraApiCall<{
|
||||
expand: string;
|
||||
id: string;
|
||||
key: string;
|
||||
fields: Record<string, any>;
|
||||
}>({
|
||||
auth: context.auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/${issueId}`,
|
||||
});
|
||||
|
||||
const updatedIssueProperties = transformCustomFields(flattenedFields, issue.fields);
|
||||
|
||||
return {
|
||||
...issue,
|
||||
fields: updatedIssueProperties,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,382 @@
|
||||
import {
|
||||
AuthenticationType,
|
||||
HttpMessageBody,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
QueryParams,
|
||||
httpClient,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { JiraAuth } from '../../auth';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
export async function sendJiraRequest(request: HttpRequest & { auth: JiraAuth }) {
|
||||
return httpClient.sendRequest({
|
||||
...request,
|
||||
url: `${request.auth.props.instanceUrl}/rest/api/3/${request.url}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: request.auth.props.email,
|
||||
password: request.auth.props.apiToken,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUsers(auth: JiraAuth) {
|
||||
const response = await sendJiraRequest({
|
||||
url: 'users/search',
|
||||
method: HttpMethod.GET,
|
||||
auth: auth,
|
||||
queryParams: {
|
||||
maxResults: '1000',
|
||||
},
|
||||
});
|
||||
|
||||
return response.body as any[];
|
||||
}
|
||||
|
||||
export async function getProjects(auth: JiraAuth): Promise<JiraProject[]> {
|
||||
|
||||
const response = await jiraPaginatedApiCall<JiraProject,'values'>({
|
||||
auth,
|
||||
method:HttpMethod.GET,
|
||||
resourceUri:'/project/search',
|
||||
propertyName:'values'
|
||||
})
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function getIssueTypes({ auth, projectId }: { auth: JiraAuth; projectId: string }) {
|
||||
const response = await sendJiraRequest({
|
||||
url: 'issuetype/project',
|
||||
method: HttpMethod.GET,
|
||||
auth: auth,
|
||||
queryParams: {
|
||||
projectId,
|
||||
},
|
||||
});
|
||||
|
||||
return response.body as any[];
|
||||
}
|
||||
|
||||
export async function getPriorities({ auth }: { auth: JiraAuth }) {
|
||||
const response = await sendJiraRequest({
|
||||
url: 'priority',
|
||||
method: HttpMethod.GET,
|
||||
auth: auth,
|
||||
});
|
||||
|
||||
return response.body as any[];
|
||||
}
|
||||
|
||||
export async function executeJql({
|
||||
auth,
|
||||
jql,
|
||||
sanitizeJql,
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
body,
|
||||
}: {
|
||||
auth: JiraAuth;
|
||||
jql: string;
|
||||
sanitizeJql: boolean;
|
||||
url: string;
|
||||
method: HttpMethod;
|
||||
queryParams?: QueryParams;
|
||||
body?: HttpMessageBody;
|
||||
}) {
|
||||
let reqJql = jql;
|
||||
if (sanitizeJql) {
|
||||
const sanitizeResult = (
|
||||
await sendJiraRequest({
|
||||
auth: auth,
|
||||
url: 'jql/sanitize',
|
||||
method: HttpMethod.POST,
|
||||
body: {
|
||||
queries: [
|
||||
{
|
||||
query: jql,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
).body as {
|
||||
queries: {
|
||||
initialQuery: string;
|
||||
sanitizedQuery: string;
|
||||
}[];
|
||||
};
|
||||
reqJql = sanitizeResult.queries[0].sanitizedQuery;
|
||||
}
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
auth,
|
||||
url,
|
||||
method,
|
||||
body: {
|
||||
...body,
|
||||
jql: reqJql,
|
||||
},
|
||||
queryParams,
|
||||
});
|
||||
return response.body;
|
||||
}
|
||||
|
||||
export async function searchIssuesByJql({
|
||||
auth,
|
||||
jql,
|
||||
maxResults,
|
||||
sanitizeJql,
|
||||
}: {
|
||||
auth: JiraAuth;
|
||||
jql: string;
|
||||
maxResults: number;
|
||||
sanitizeJql: boolean;
|
||||
}) {
|
||||
const respJql = (
|
||||
(await executeJql({
|
||||
auth,
|
||||
url: 'search/jql',
|
||||
method: HttpMethod.POST,
|
||||
jql,
|
||||
body: {
|
||||
maxResults,
|
||||
},
|
||||
sanitizeJql,
|
||||
})) as { issues: any[] }
|
||||
).issues;
|
||||
|
||||
const issueIds = respJql.map(issue => issue['id']);
|
||||
if (issueIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (
|
||||
(await sendJiraRequest({
|
||||
auth,
|
||||
url: 'issue/bulkfetch',
|
||||
method: HttpMethod.POST,
|
||||
body: {
|
||||
issueIdsOrKeys: issueIds,
|
||||
},
|
||||
})).body as any as { issues: any[] }
|
||||
).issues;
|
||||
}
|
||||
|
||||
export async function createJiraIssue(data: CreateIssueParams) {
|
||||
const fields: any = {
|
||||
project: {
|
||||
id: data.projectId,
|
||||
},
|
||||
summary: data.summary,
|
||||
issuetype: {
|
||||
id: data.issueTypeId,
|
||||
},
|
||||
};
|
||||
if (data.assignee) fields.assignee = { id: data.assignee };
|
||||
if (data.priority) fields.priority = { id: data.priority };
|
||||
if (data.description)
|
||||
fields.description = {
|
||||
content: [
|
||||
{
|
||||
content: [
|
||||
{
|
||||
text: data.description,
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'paragraph',
|
||||
},
|
||||
],
|
||||
type: 'doc',
|
||||
version: 1,
|
||||
};
|
||||
|
||||
if (data.parentKey) {
|
||||
fields.parent = { key: data.parentKey };
|
||||
}
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
url: 'issue',
|
||||
method: HttpMethod.POST,
|
||||
auth: data.auth,
|
||||
body: {
|
||||
fields: fields,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
}
|
||||
|
||||
export async function updateJiraIssue(data: UpdateIssueParams) {
|
||||
const fields: any = {};
|
||||
if (data.summary) fields.summary = data.summary;
|
||||
if (data.issueTypeId) fields.issuetype = { id: data.issueTypeId };
|
||||
if (data.assignee) fields.assignee = { id: data.assignee };
|
||||
if (data.priority) fields.priority = { id: data.priority };
|
||||
if (data.description)
|
||||
fields.description = {
|
||||
content: [
|
||||
{
|
||||
content: [
|
||||
{
|
||||
text: data.description,
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
type: 'paragraph',
|
||||
},
|
||||
],
|
||||
type: 'doc',
|
||||
version: 1,
|
||||
};
|
||||
|
||||
if (data.parentKey) {
|
||||
fields.parent = { key: data.parentKey };
|
||||
}
|
||||
|
||||
const response = await sendJiraRequest({
|
||||
url: `issue/${data.issueId}`,
|
||||
method: HttpMethod.PUT,
|
||||
auth: data.auth,
|
||||
queryParams: {
|
||||
returnIssue: 'true',
|
||||
},
|
||||
body: {
|
||||
fields: fields,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
}
|
||||
export interface JiraIssueType {
|
||||
id: string;
|
||||
description: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface JiraProject {
|
||||
id: string;
|
||||
key: string;
|
||||
name: string;
|
||||
expand: string;
|
||||
self: string;
|
||||
projectTypeKey: string;
|
||||
simplified: boolean;
|
||||
style: string;
|
||||
isPrivate: boolean;
|
||||
properties: any;
|
||||
}
|
||||
|
||||
export interface CreateIssueParams {
|
||||
auth: JiraAuth;
|
||||
projectId: string;
|
||||
summary: string;
|
||||
description?: string;
|
||||
issueTypeId: string;
|
||||
assignee?: string;
|
||||
priority?: string;
|
||||
parentKey?: string;
|
||||
}
|
||||
|
||||
export interface UpdateIssueParams {
|
||||
auth: JiraAuth;
|
||||
issueId?: string;
|
||||
summary?: string;
|
||||
description?: string;
|
||||
issueTypeId: string;
|
||||
assignee?: string;
|
||||
priority?: string;
|
||||
parentKey?: string;
|
||||
}
|
||||
export type RequestParams = Record<string, string | number | string[] | undefined>;
|
||||
|
||||
export type JiraApiCallParams = {
|
||||
auth:JiraAuth,
|
||||
method: HttpMethod;
|
||||
resourceUri: string;
|
||||
query?: RequestParams;
|
||||
body?: any;
|
||||
};
|
||||
|
||||
export async function jiraApiCall<T extends HttpMessageBody>({
|
||||
auth,
|
||||
method,
|
||||
resourceUri,
|
||||
query,
|
||||
body,
|
||||
}: JiraApiCallParams): Promise<T> {
|
||||
const baseUrl = `${auth.props.instanceUrl}/rest/api/3`;
|
||||
const qs: QueryParams = {};
|
||||
if (query) {
|
||||
for (const [key, value] of Object.entries(query)) {
|
||||
if (value !== null && value !== undefined) {
|
||||
qs[key] = String(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const request: HttpRequest = {
|
||||
method,
|
||||
url: baseUrl + resourceUri,
|
||||
queryParams: qs,
|
||||
body,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username:auth.props.email,
|
||||
password:auth.props.apiToken,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
export async function jiraPaginatedApiCall<T extends HttpMessageBody, K extends string>({
|
||||
auth,
|
||||
method,
|
||||
resourceUri,
|
||||
query,
|
||||
body,
|
||||
propertyName,
|
||||
}: JiraApiCallParams & { propertyName: K }): Promise<T[]> {
|
||||
const qs = query ? query : {};
|
||||
|
||||
qs['startAt'] = 0;
|
||||
qs['maxResults'] = 100;
|
||||
|
||||
const resultData: T[] = [];
|
||||
let hasMore = true;
|
||||
|
||||
type PaginatedResponse<T, K extends string> = {
|
||||
startAt: number;
|
||||
maxResults: number;
|
||||
total: number;
|
||||
isLast?: boolean;
|
||||
} & Record<K, T[]>;
|
||||
|
||||
do {
|
||||
const response = await jiraApiCall<PaginatedResponse<T, K>>({
|
||||
auth,
|
||||
method,
|
||||
resourceUri,
|
||||
query: qs,
|
||||
body,
|
||||
});
|
||||
|
||||
if (isNil(response[propertyName])) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (Array.isArray(response[propertyName])) {
|
||||
resultData.push(...response[propertyName]);
|
||||
}
|
||||
|
||||
qs['startAt'] += 100;
|
||||
hasMore =
|
||||
response.isLast === undefined
|
||||
? response.startAt + response.maxResults < response.total
|
||||
: !response.isLast;
|
||||
} while (hasMore);
|
||||
|
||||
return resultData;
|
||||
}
|
||||
@@ -0,0 +1,681 @@
|
||||
import {
|
||||
getIssueTypes,
|
||||
getProjects,
|
||||
getUsers,
|
||||
jiraApiCall,
|
||||
jiraPaginatedApiCall,
|
||||
sendJiraRequest,
|
||||
} from '.';
|
||||
import { DropdownOption, Property } from '@activepieces/pieces-framework';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { IssueFieldMetaData, IssueTypeMetadata } from './types';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export function getProjectIdDropdown(data?: DropdownParams) {
|
||||
return Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: data?.displayName ?? 'Project ID or Key',
|
||||
description: data?.description,
|
||||
required: data?.required ?? true,
|
||||
refreshers: data?.refreshers ?? [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const projects = await getProjects(auth as JiraAuth);
|
||||
return {
|
||||
options: projects.map((project) => {
|
||||
return {
|
||||
label: project.name,
|
||||
value: project.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getIssueIdDropdown(data?: DropdownParams) {
|
||||
return Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: data?.displayName ?? 'Issue ID or Key',
|
||||
description: data?.description,
|
||||
required: data?.required ?? true,
|
||||
refreshers: data?.refreshers ?? [],
|
||||
options: async ({ auth, projectId }) => {
|
||||
if (!auth || !projectId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
let hasMore = true
|
||||
let nextPageToken:string|undefined;
|
||||
const options: DropdownOption<string>[] = [];
|
||||
do {
|
||||
const response = await sendJiraRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: 'search/jql',
|
||||
auth: auth as JiraAuth,
|
||||
body: {
|
||||
fields: ['summary'],
|
||||
jql: `project=${projectId}`,
|
||||
nextPageToken,
|
||||
maxResults: 100,
|
||||
},
|
||||
});
|
||||
const issueList = response.body as SearchIssuesResponse;
|
||||
options.push(
|
||||
...issueList.issues.map((issue) => {
|
||||
return {
|
||||
label: `[${issue.key}] ${issue.fields.summary}`,
|
||||
value: issue.id,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
nextPageToken = issueList.nextPageToken;
|
||||
hasMore = !issueList.isLast
|
||||
} while (hasMore);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getIssueTypeIdDropdown(data?: DropdownParams) {
|
||||
return Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: data?.displayName ?? 'Issue Type',
|
||||
description: data?.description,
|
||||
required: data?.required ?? true,
|
||||
refreshers: data?.refreshers ?? ['projectId'],
|
||||
options: async ({ auth, projectId }) => {
|
||||
if (!auth || !projectId) {
|
||||
return {
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const issueTypes = await getIssueTypes({
|
||||
auth: auth as JiraAuth,
|
||||
projectId: projectId as string,
|
||||
});
|
||||
return {
|
||||
options: issueTypes.map((issueType) => {
|
||||
return {
|
||||
label: issueType.name,
|
||||
value: issueType.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getUsersDropdown(data?: DropdownParams) {
|
||||
return Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName: data?.displayName ?? 'User',
|
||||
description: data?.description,
|
||||
required: data?.required ?? true,
|
||||
refreshers: data?.refreshers ?? [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const users = (await getUsers(auth as JiraAuth)).filter(
|
||||
(user) => user.accountType === 'atlassian',
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => {
|
||||
return {
|
||||
label: user.displayName,
|
||||
value: user.accountId,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export interface DropdownParams {
|
||||
required?: boolean;
|
||||
refreshers?: string[];
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface SearchIssuesResponse {
|
||||
nextPageToken?:string,
|
||||
isLast: boolean;
|
||||
issues: Array<{
|
||||
id: string;
|
||||
key: string;
|
||||
fields: {
|
||||
summary: string;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
|
||||
async function fetchGroupsOptions(auth: JiraAuth): Promise<DropdownOption<string>[]> {
|
||||
const response = await jiraApiCall<{
|
||||
groups: Array<{ groupId: string; name: string }>;
|
||||
}>({
|
||||
auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/groups/picker`,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
for (const group of response.groups) {
|
||||
options.push({
|
||||
value: group.groupId,
|
||||
label: group.name,
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
async function fetchProjectVersionsOptions(
|
||||
auth: JiraAuth,
|
||||
projectId: string,
|
||||
): Promise<DropdownOption<string>[]> {
|
||||
const response = await jiraApiCall<Array<{ id: string; name: string }>>({
|
||||
auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/project/${projectId}/versions`,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
for (const version of response) {
|
||||
options.push({
|
||||
value: version.id,
|
||||
label: version.name,
|
||||
});
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
async function fetchUsersOptions(auth: JiraAuth): Promise<DropdownOption<string>[]> {
|
||||
const response = (await getUsers(auth)) as Array<{
|
||||
accountId: string;
|
||||
accountType: string;
|
||||
displayName: string;
|
||||
}>;
|
||||
|
||||
const options = response
|
||||
.filter((user) => user.accountType === 'atlassian')
|
||||
.map((user) => {
|
||||
return {
|
||||
label: user.displayName,
|
||||
value: user.accountId,
|
||||
};
|
||||
});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
export const issueTypeIdProp = (displayName: string, required = true) =>
|
||||
Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName,
|
||||
refreshers: ['projectId'],
|
||||
required,
|
||||
options: async ({ auth, projectId }) => {
|
||||
if (!auth || !projectId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first',
|
||||
};
|
||||
}
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const response = await jiraPaginatedApiCall<IssueTypeMetadata, 'issueTypes'>({
|
||||
auth: authValue,
|
||||
resourceUri: `/issue/createmeta/${projectId}/issuetypes`,
|
||||
propertyName: 'issueTypes',
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
for (const issueType of response) {
|
||||
options.push({
|
||||
value: issueType.id,
|
||||
label: issueType.name,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const issueLinkTypeIdProp = (displayName: string, required = true) =>
|
||||
Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName,
|
||||
refreshers: [],
|
||||
required,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first',
|
||||
};
|
||||
}
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const response = await jiraApiCall<{ issueLinkTypes: Array<{ id: string; inward: string }> }>({
|
||||
auth: authValue,
|
||||
resourceUri: `/issueLinkType`,
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
for (const linkType of response.issueLinkTypes) {
|
||||
options.push({
|
||||
value: linkType.id,
|
||||
label: linkType.inward,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const issueIdOrKeyProp = (displayName: string, required = true) =>
|
||||
Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName,
|
||||
refreshers: [],
|
||||
required,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first',
|
||||
};
|
||||
}
|
||||
const authValue = auth as JiraAuth;
|
||||
const response = await jiraPaginatedApiCall<{ id: string; key: string }, 'issues'>({
|
||||
auth: authValue,
|
||||
resourceUri: '/search',
|
||||
propertyName: 'issues',
|
||||
query: { fields: 'summary' },
|
||||
method: HttpMethod.GET,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
for (const issue of response) {
|
||||
options.push({
|
||||
value: issue.id,
|
||||
label: issue.key,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const issueStatusIdProp = (displayName: string, required = true) =>
|
||||
Property.Dropdown({
|
||||
auth: jiraCloudAuth,
|
||||
displayName,
|
||||
refreshers: ['issueId'],
|
||||
required,
|
||||
options: async ({ auth, issueId }) => {
|
||||
if (!auth || !issueId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first and select an issue.',
|
||||
};
|
||||
}
|
||||
|
||||
const authValue = auth as JiraAuth;
|
||||
const response = await jiraApiCall<{ transitions: Array<{ id: string; name: string }> }>({
|
||||
auth: authValue,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/issue/${issueId}/transitions`,
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
for (const status of response.transitions ?? []) {
|
||||
options.push({
|
||||
value: status.id,
|
||||
label: status.name,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export async function createPropertyDefinition(
|
||||
auth: JiraAuth,
|
||||
field: IssueFieldMetaData,
|
||||
isRequired = false,
|
||||
) {
|
||||
// Determine if the field is an array type
|
||||
const isArray = field.schema.type === 'array';
|
||||
const fieldType = isArray ? field.schema.items : field.schema.type;
|
||||
|
||||
switch (fieldType) {
|
||||
case 'user': {
|
||||
const userOptions = await fetchUsersOptions(auth);
|
||||
return isArray
|
||||
? Property.StaticMultiSelectDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: userOptions },
|
||||
})
|
||||
: Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: userOptions },
|
||||
});
|
||||
}
|
||||
case 'group': {
|
||||
const groupOptions = await fetchGroupsOptions(auth);
|
||||
return isArray
|
||||
? Property.StaticMultiSelectDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: groupOptions },
|
||||
})
|
||||
: Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: groupOptions },
|
||||
});
|
||||
}
|
||||
case 'version': {
|
||||
const versionOptions = field.allowedValues
|
||||
? field.allowedValues.map((option) => ({
|
||||
label: option.name,
|
||||
value: option.id,
|
||||
}))
|
||||
: [];
|
||||
return isArray
|
||||
? Property.StaticMultiSelectDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: versionOptions },
|
||||
})
|
||||
: Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: versionOptions },
|
||||
});
|
||||
}
|
||||
case 'priority': {
|
||||
const priorityOptions = field.allowedValues
|
||||
? field.allowedValues.map((option) => ({
|
||||
label: option.name,
|
||||
value: option.id,
|
||||
}))
|
||||
: [];
|
||||
|
||||
return Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: priorityOptions },
|
||||
});
|
||||
}
|
||||
case 'component': {
|
||||
const componentOptions = field.allowedValues
|
||||
? field.allowedValues.map((option) => ({
|
||||
label: option.name,
|
||||
value: option.id,
|
||||
}))
|
||||
: [];
|
||||
|
||||
return isArray
|
||||
? Property.StaticMultiSelectDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: componentOptions },
|
||||
})
|
||||
: Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: componentOptions },
|
||||
});
|
||||
}
|
||||
case 'option': {
|
||||
const options = field.allowedValues
|
||||
? field.allowedValues.map((option) => ({
|
||||
label: option.value,
|
||||
value: option.id,
|
||||
}))
|
||||
: [];
|
||||
|
||||
return isArray
|
||||
? Property.StaticMultiSelectDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: options },
|
||||
})
|
||||
: Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
options: { disabled: false, options: options },
|
||||
});
|
||||
}
|
||||
case 'string': {
|
||||
return isArray
|
||||
? Property.Array({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
})
|
||||
: Property.LongText({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
});
|
||||
}
|
||||
case 'date':
|
||||
return Property.DateTime({
|
||||
displayName: field.name,
|
||||
description: 'Provide date in YYYY-MM-DD format.',
|
||||
required: isRequired,
|
||||
});
|
||||
|
||||
case 'datetime':
|
||||
return Property.DateTime({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
});
|
||||
|
||||
case 'number':
|
||||
return Property.Number({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
});
|
||||
|
||||
case 'project':
|
||||
return Property.ShortText({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
description: 'Provide project key.',
|
||||
});
|
||||
|
||||
case 'issuelink':
|
||||
return Property.ShortText({
|
||||
displayName: field.name,
|
||||
required: isRequired,
|
||||
description: 'Provide issue key.',
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Only certain fields support ADF in issues
|
||||
// https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/#version
|
||||
// - description and environment fields in issues.
|
||||
// - textarea type custom fields (multi-line text fields) in issues. Single line custom fields (textfield) accept a string and don't handle Atlassian Document Format content.
|
||||
export function isFieldAdfCompatible(field: IssueFieldMetaData) {
|
||||
const standardFields = ['description', 'environment'];
|
||||
|
||||
return field.schema.custom?.includes('textarea') || standardFields.includes(field.key);
|
||||
}
|
||||
|
||||
function parseArray(value: Array<string> | string): Array<string> {
|
||||
try {
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const parsedValue = JSON.parse(value);
|
||||
if (Array.isArray(parsedValue)) {
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
return [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Function to format issue fields
|
||||
// https://support.atlassian.com/cloud-automation/docs/advanced-field-editing-using-json/#Multi-user-picker-custom-field
|
||||
|
||||
export function formatIssueFields(
|
||||
fieldsMetadata: IssueFieldMetaData[],
|
||||
fieldsInput: Record<string, any>,
|
||||
adfFields: string[],
|
||||
) {
|
||||
const fieldsOutput: Record<string, any> = {};
|
||||
|
||||
for (const field of fieldsMetadata) {
|
||||
const key = field.key;
|
||||
const fieldInputValue = fieldsInput[key];
|
||||
|
||||
// Skip if value is null, undefined, or empty string
|
||||
if (isNil(fieldInputValue) || fieldInputValue === '') continue;
|
||||
|
||||
switch (field.schema.type) {
|
||||
case 'array': {
|
||||
const parsedArrayValue = parseArray(fieldInputValue);
|
||||
if (parsedArrayValue.length === 0) continue;
|
||||
|
||||
fieldsOutput[key] =
|
||||
field.schema.items === 'string'
|
||||
? parsedArrayValue // Keep as flat array of strings
|
||||
: parsedArrayValue.map((item) =>
|
||||
field.schema.items === 'group' ? { groupId: item } : { id: item },
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'user':
|
||||
fieldsOutput[key] = { accountId: fieldInputValue };
|
||||
break;
|
||||
case 'version':
|
||||
case 'option':
|
||||
case 'priority':
|
||||
case 'issuetype':
|
||||
case 'component':
|
||||
fieldsOutput[key] = { id: fieldInputValue };
|
||||
break;
|
||||
|
||||
case 'issuelink':
|
||||
fieldsOutput[key] = { key: fieldInputValue };
|
||||
break;
|
||||
|
||||
case 'group':
|
||||
fieldsOutput[key] = { groupId: fieldInputValue };
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
fieldsOutput[key] = dayjs(fieldInputValue).format('YYYY-MM-DD');
|
||||
break;
|
||||
|
||||
case 'datetime':
|
||||
fieldsOutput[key] = dayjs(fieldInputValue).toISOString();
|
||||
break;
|
||||
|
||||
case 'number':
|
||||
fieldsOutput[key] = Number(fieldInputValue);
|
||||
break;
|
||||
|
||||
case 'project':
|
||||
fieldsOutput[key] = { key: fieldInputValue };
|
||||
break;
|
||||
|
||||
case 'string': {
|
||||
if (isFieldAdfCompatible(field)) {
|
||||
if (adfFields.includes(key)) {
|
||||
fieldsOutput[key] = JSON.parse(fieldInputValue);
|
||||
} else {
|
||||
fieldsOutput[key] = {
|
||||
type: 'doc',
|
||||
version: 1,
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [{ text: fieldInputValue, type: 'text' }],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
} else {
|
||||
fieldsOutput[key] = fieldInputValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fieldsOutput;
|
||||
}
|
||||
|
||||
export function transformCustomFields(
|
||||
fieldsMetadata: IssueFieldMetaData[],
|
||||
fieldsInput: Record<string, any>,
|
||||
): Record<string, any> {
|
||||
const result: Record<string, any> = {};
|
||||
|
||||
const fieldsMapping = fieldsMetadata.reduce((acc, field) => {
|
||||
acc[field.key] = field.name;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
|
||||
for (const [key, value] of Object.entries(fieldsInput)) {
|
||||
result[key.startsWith('customfield_') ? fieldsMapping[key] ?? key : key] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
export type IssueTypeMetadata = {
|
||||
id:string,
|
||||
name:string
|
||||
}
|
||||
|
||||
export type IssueFieldMetaData ={
|
||||
required:boolean,
|
||||
name:string,
|
||||
key:string,
|
||||
fieldId:string,
|
||||
schema:{
|
||||
type:"string"|"date"|"datetime"|"array"|"number"|"option"|"user"|"group"|"version"|"project"|"issuelink"|"priority"|"issuetype"|"component", // "option-with-child",
|
||||
items:string,
|
||||
custom?:string,
|
||||
customId?:number,
|
||||
},
|
||||
allowedValues?:Array<{value:string,id:string,name:string}>
|
||||
}
|
||||
|
||||
export const VALID_CUSTOM_FIELD_TYPES = [
|
||||
'userpicker',
|
||||
'participants',
|
||||
'multiuserpicker',
|
||||
'multiversion',
|
||||
'version',
|
||||
'multigrouppicker',
|
||||
'grouppicker',
|
||||
'multicheckboxes',
|
||||
'multiselect',
|
||||
'datepicker',
|
||||
'datetime',
|
||||
'labels',
|
||||
'float',
|
||||
'textarea',
|
||||
'radiobuttons',
|
||||
'select',
|
||||
'textfield',
|
||||
'url',
|
||||
'project',
|
||||
];
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
TriggerStrategy,
|
||||
createTrigger,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
Polling,
|
||||
DedupeStrategy,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import { searchIssuesByJql } from '../common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<
|
||||
JiraAuth,
|
||||
{ jql?: string; sanitizeJql?: boolean }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, lastFetchEpochMS, propsValue }) => {
|
||||
const { jql, sanitizeJql } = propsValue;
|
||||
const searchQuery = `${jql ? jql + ' AND ' : ''}created > '${dayjs(
|
||||
lastFetchEpochMS
|
||||
).format('YYYY-MM-DD HH:mm')}'`;
|
||||
const issues = await searchIssuesByJql({
|
||||
auth,
|
||||
jql: searchQuery,
|
||||
maxResults: 50,
|
||||
sanitizeJql: sanitizeJql ?? false,
|
||||
});
|
||||
return issues.map((issue) => ({
|
||||
epochMilliSeconds: Date.parse(issue.fields.created),
|
||||
data: issue,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newIssue = createTrigger({
|
||||
name: 'new_issue',
|
||||
displayName: 'New Issue',
|
||||
description: 'Triggers when a new issue is created',
|
||||
auth: jiraCloudAuth,
|
||||
type: TriggerStrategy.POLLING,
|
||||
props: {
|
||||
jql: Property.LongText({
|
||||
displayName: 'JQL',
|
||||
description: 'Use to filter issues watched',
|
||||
required: false,
|
||||
}),
|
||||
sanitizeJql: Property.Checkbox({
|
||||
displayName: 'Sanitize JQL',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
sampleData: {},
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, context);
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
TriggerStrategy,
|
||||
createTrigger,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
Polling,
|
||||
DedupeStrategy,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import { searchIssuesByJql } from '../common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<
|
||||
JiraAuth,
|
||||
{ jql?: string; sanitizeJql?: boolean }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, lastFetchEpochMS, propsValue }) => {
|
||||
const { jql, sanitizeJql } = propsValue;
|
||||
const searchQuery = `${jql ? jql + ' AND ' : ''}updated > '${dayjs(
|
||||
lastFetchEpochMS
|
||||
).format('YYYY-MM-DD HH:mm')}'`;
|
||||
const issues = await searchIssuesByJql({
|
||||
auth,
|
||||
jql: searchQuery,
|
||||
maxResults: 50,
|
||||
sanitizeJql: sanitizeJql ?? false,
|
||||
});
|
||||
return issues.map((issue) => ({
|
||||
epochMilliSeconds: Date.parse(issue.fields.statuscategorychangedate),
|
||||
data: issue,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const updatedIssueStatus = createTrigger({
|
||||
name: 'updated_issue_status',
|
||||
displayName: 'Updated Issue Status',
|
||||
description: 'Triggers when an issue status is updated',
|
||||
auth: jiraCloudAuth,
|
||||
type: TriggerStrategy.POLLING,
|
||||
props: {
|
||||
jql: Property.LongText({
|
||||
displayName: 'JQL',
|
||||
description: 'Use to filter issues watched',
|
||||
required: false,
|
||||
}),
|
||||
sanitizeJql: Property.Checkbox({
|
||||
displayName: 'Sanitize JQL',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
sampleData: {},
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, context);
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
TriggerStrategy,
|
||||
createTrigger,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
Polling,
|
||||
DedupeStrategy,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { JiraAuth, jiraCloudAuth } from '../../auth';
|
||||
import { searchIssuesByJql } from '../common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling< JiraAuth,
|
||||
{ jql?: string; sanitizeJql?: boolean }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, lastFetchEpochMS, propsValue }) => {
|
||||
const { jql, sanitizeJql } = propsValue;
|
||||
const searchQuery = `${jql ? jql + ' AND ' : ''}updated > '${dayjs(
|
||||
lastFetchEpochMS
|
||||
).format('YYYY-MM-DD HH:mm')}'`;
|
||||
const issues = await searchIssuesByJql({
|
||||
auth,
|
||||
jql: searchQuery,
|
||||
maxResults: 50,
|
||||
sanitizeJql: sanitizeJql ?? false,
|
||||
});
|
||||
return issues.map((issue) => ({
|
||||
epochMilliSeconds: Date.parse(issue.fields.updated),
|
||||
data: issue,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const updatedIssue = createTrigger({
|
||||
name: 'updated_issue',
|
||||
displayName: 'Updated Issue',
|
||||
description: 'Triggers when an issue is updated',
|
||||
auth: jiraCloudAuth,
|
||||
type: TriggerStrategy.POLLING,
|
||||
props: {
|
||||
jql: Property.LongText({
|
||||
displayName: 'JQL',
|
||||
description: 'Use to filter issues watched',
|
||||
required: false,
|
||||
}),
|
||||
sanitizeJql: Property.Checkbox({
|
||||
displayName: 'Sanitize JQL',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
sampleData: {},
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, context);
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user