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,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "Du kannst deinen API-Schlüssel erhalten, indem du auf **Einstellungen->Erweitert** klickst.",
|
||||
"Create Task": "Aufgabe erstellen",
|
||||
"Create Time Entry": "Erstelle Zeiteintrag",
|
||||
"Start Timer": "Timer starten",
|
||||
"Stop Timer": "Timer stoppen",
|
||||
"Find Task": "Aufgabe finden",
|
||||
"Find Time Entry": "Zeiteintrag finden",
|
||||
"Find Running Timer": "Suche Laufzeit",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Creates a new in a specific project.": "Erstellt ein neues in einem bestimmten Projekt.",
|
||||
"Creates a new time entry.": "Erstellt einen neuen Zeiteintrag.",
|
||||
"Starts a new time entry.": "Startet einen neuen Zeiteintrag.",
|
||||
"Stops currently running timer on specified workspace.": "Stoppt derzeit den Timer auf dem angegebenen Arbeitsbereich.",
|
||||
"Finds an existing task in a specific project.": "Findet eine bestehende Aufgabe in einem bestimmten Projekt.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Findet einen Zeiteintrag nach Beschreibung, Startdatum oder Enddatum.",
|
||||
"Finds currently running timer on specified workspace.": "Findet derzeit einen Timer auf dem angegebenen Arbeitsbereich.",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Workspace": "Arbeitsbereich",
|
||||
"Project": "Projekt",
|
||||
"Task Name": "Aufgabenname",
|
||||
"Status": "Status",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Beginndatum",
|
||||
"End Datetime": "Enddatum",
|
||||
"Entry Description": "Eintragsbeschreibung",
|
||||
"Task": "Aufgabe",
|
||||
"Billable": "Abrechenbar",
|
||||
"Tags": "Tags",
|
||||
"Exact Match ?": "Genaues Match ?",
|
||||
"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)",
|
||||
"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..",
|
||||
"Active": "Aktiv",
|
||||
"Done": "Done",
|
||||
"All": "Alle",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD",
|
||||
"New Task": "Neue Aufgabe",
|
||||
"New Time Entry": "Neuer Zeiteintrag",
|
||||
"New Timer Started": "Neuer Timer gestartet",
|
||||
"Triggers when a new task is created in specified project.": "Wird ausgelöst, wenn eine neue Aufgabe in einem bestimmten Projekt erstellt wird.",
|
||||
"Triggers when a new time entry is created.": "Wird ausgelöst, wenn ein neuer Zeiteintrag erstellt wird.",
|
||||
"Triggers when a new entry is started and running.": "Wird ausgelöst, wenn ein neuer Eintrag gestartet wird und läuft."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "Puedes obtener tu clave de API navegando a **Preferencias->Avanzadas**.",
|
||||
"Create Task": "Crear tarea",
|
||||
"Create Time Entry": "Crear entrada de tiempo",
|
||||
"Start Timer": "Iniciar Temporizador",
|
||||
"Stop Timer": "Detener temporizador",
|
||||
"Find Task": "Buscar tarea",
|
||||
"Find Time Entry": "Encontrar entrada de hora",
|
||||
"Find Running Timer": "Encontrar temporizador en ejecución",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Creates a new in a specific project.": "Crea un nuevo en un proyecto específico.",
|
||||
"Creates a new time entry.": "Crea una nueva entrada de hora.",
|
||||
"Starts a new time entry.": "Inicia una nueva entrada de hora.",
|
||||
"Stops currently running timer on specified workspace.": "Detiene el temporizador actual en un área de trabajo especificada.",
|
||||
"Finds an existing task in a specific project.": "Encuentra una tarea existente en un proyecto específico.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Encuentra una entrada de hora por descripción, fecha de inicio o fecha de fin.",
|
||||
"Finds currently running timer on specified workspace.": "Encuentra el temporizador en ejecución en el área de trabajo especificada.",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Workspace": "Espacio de trabajo",
|
||||
"Project": "Projekt",
|
||||
"Task Name": "Nombre de tarea",
|
||||
"Status": "Estado",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Fecha de inicio",
|
||||
"End Datetime": "Fecha de fin",
|
||||
"Entry Description": "Descripción de la entrada",
|
||||
"Task": "Tarea",
|
||||
"Billable": "Facturable",
|
||||
"Tags": "Etiquetas",
|
||||
"Exact Match ?": "Partida exacta ?",
|
||||
"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)",
|
||||
"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.",
|
||||
"Active": "Activo",
|
||||
"Done": "Hecho",
|
||||
"All": "Todos",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO",
|
||||
"New Task": "Nueva tarea",
|
||||
"New Time Entry": "Nueva entrada de hora",
|
||||
"New Timer Started": "Nuevo temporizador iniciado",
|
||||
"Triggers when a new task is created in specified project.": "Se activa cuando se crea una nueva tarea en un proyecto especificado.",
|
||||
"Triggers when a new time entry is created.": "Dispara cuando se crea una nueva entrada de tiempo.",
|
||||
"Triggers when a new entry is started and running.": "Se activa cuando se inicia y se ejecuta una nueva entrada."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "Vous pouvez obtenir votre clé API en accédant à **Preferences->Advanced**.",
|
||||
"Create Task": "Créer une tâche",
|
||||
"Create Time Entry": "Créer une entrée de temps",
|
||||
"Start Timer": "Démarrer le minuteur",
|
||||
"Stop Timer": "Arrêter minuteur",
|
||||
"Find Task": "Trouver une tâche",
|
||||
"Find Time Entry": "Rechercher la saisie de l'heure",
|
||||
"Find Running Timer": "Trouver le minuteur en cours",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Creates a new in a specific project.": "Crée un nouveau dans un projet spécifique.",
|
||||
"Creates a new time entry.": "Crée une nouvelle entrée horaire.",
|
||||
"Starts a new time entry.": "Démarre une nouvelle entrée de temps.",
|
||||
"Stops currently running timer on specified workspace.": "Arrête le minuteur en cours d'exécution sur l'espace de travail spécifié.",
|
||||
"Finds an existing task in a specific project.": "Trouve une tâche existante dans un projet spécifique.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Trouve une entrée heure par description, date de début ou date de fin.",
|
||||
"Finds currently running timer on specified workspace.": "Trouve le minuteur en cours d'exécution sur l'espace de travail spécifié.",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Workspace": "Espace de travail",
|
||||
"Project": "Projet",
|
||||
"Task Name": "Nom de la tâche",
|
||||
"Status": "Statut",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Date de début",
|
||||
"End Datetime": "Date de fin",
|
||||
"Entry Description": "Description de l'entrée",
|
||||
"Task": "Tâche",
|
||||
"Billable": "Facturable",
|
||||
"Tags": "Tags",
|
||||
"Exact Match ?": "Correspondance exacte ?",
|
||||
"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)",
|
||||
"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.",
|
||||
"Active": "Actif",
|
||||
"Done": "Terminé",
|
||||
"All": "Tous",
|
||||
"GET": "OBTENIR",
|
||||
"POST": "POSTER",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "EFFACER",
|
||||
"DELETE": "SUPPRIMER",
|
||||
"HEAD": "TÊTE",
|
||||
"New Task": "Nouvelle tâche",
|
||||
"New Time Entry": "Nouvelle entrée de temps",
|
||||
"New Timer Started": "Nouveau minuteur démarré",
|
||||
"Triggers when a new task is created in specified project.": "Déclenche lorsqu'une nouvelle tâche est créée dans le projet spécifié.",
|
||||
"Triggers when a new time entry is created.": "Déclenche quand une nouvelle entrée de temps est créée.",
|
||||
"Triggers when a new entry is started and running.": "Déclenche quand une nouvelle entrée est démarrée et en cours d'exécution."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "API キーは **Preferences->Advanced** に移動して取得できます。",
|
||||
"Create Task": "タスクを作成",
|
||||
"Create Time Entry": "タイムエントリを作成",
|
||||
"Start Timer": "開始タイマー",
|
||||
"Stop Timer": "停止タイマー",
|
||||
"Find Task": "タスクを検索",
|
||||
"Find Time Entry": "タイムエントリを検索",
|
||||
"Find Running Timer": "実行中のタイマーを検索",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Creates a new in a specific project.": "特定のプロジェクトに新規作成します。",
|
||||
"Creates a new time entry.": "新しいタイムエントリを作成します。",
|
||||
"Starts a new time entry.": "新しい時刻の入力を開始します。",
|
||||
"Stops currently running timer on specified workspace.": "指定されたワークスペースで現在実行中のタイマーを停止します。",
|
||||
"Finds an existing task in a specific project.": "特定のプロジェクトの既存のタスクを検索します。",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "時刻の項目を説明、開始日時、終了日時で検索します。",
|
||||
"Finds currently running timer on specified workspace.": "指定されたワークスペースで現在実行中のタイマーを検索します。",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Workspace": "ワークスペース",
|
||||
"Project": "プロジェクト",
|
||||
"Task Name": "タスク名",
|
||||
"Status": "ステータス",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "開始日時",
|
||||
"End Datetime": "終了日時",
|
||||
"Entry Description": "エントリの説明",
|
||||
"Task": "タスク",
|
||||
"Billable": "請求可能",
|
||||
"Tags": "タグ",
|
||||
"Exact Match ?": "完全一致 ?",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"Active": "有効",
|
||||
"Done": "完了",
|
||||
"All": "すべて",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭",
|
||||
"New Task": "新しいタスク",
|
||||
"New Time Entry": "新しい時間入力",
|
||||
"New Timer Started": "新しいタイマーが開始されました",
|
||||
"Triggers when a new task is created in specified project.": "指定したプロジェクトで新しいタスクが作成されたときにトリガーされます。",
|
||||
"Triggers when a new time entry is created.": "新しい時間エントリが作成されたときにトリガーします。",
|
||||
"Triggers when a new entry is started and running.": "新しいエントリが起動して実行されたときにトリガーします。"
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "U kunt uw API-sleutel verkrijgen door naar **Voorkeuren>Geavanceerd**.",
|
||||
"Create Task": "Taak maken",
|
||||
"Create Time Entry": "Tijdsinvoer aanmaken",
|
||||
"Start Timer": "Start tijdmeter",
|
||||
"Stop Timer": "Stop timer",
|
||||
"Find Task": "Zoek Taak",
|
||||
"Find Time Entry": "Vind tijdsinvoer",
|
||||
"Find Running Timer": "Zoek Running Timer",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new in a specific project.": "Maakt een nieuw in een specifiek project.",
|
||||
"Creates a new time entry.": "Maakt een nieuwe tijdsinvoer aan.",
|
||||
"Starts a new time entry.": "Start een nieuwe tijd invoer.",
|
||||
"Stops currently running timer on specified workspace.": "Stopt momenteel timer op opgegeven werkruimte.",
|
||||
"Finds an existing task in a specific project.": "Vindt een bestaande taak in een specifiek project.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Vindt een tijdsvermelding op beschrijving, startdatum of einddatetime.",
|
||||
"Finds currently running timer on specified workspace.": "Gevonden caches met momenteel lopende timer op opgegeven werkruimte.",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Workspace": "werkruimte",
|
||||
"Project": "Project",
|
||||
"Task Name": "Taak naam",
|
||||
"Status": "status",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Start datum",
|
||||
"End Datetime": "Eind datum",
|
||||
"Entry Description": "Beschrijving item",
|
||||
"Task": "Opdracht",
|
||||
"Billable": "Factureerbaar",
|
||||
"Tags": "Labels",
|
||||
"Exact Match ?": "Exacte overeenkomst ?",
|
||||
"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)",
|
||||
"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..",
|
||||
"Active": "Actief",
|
||||
"Done": "Voltooid",
|
||||
"All": "Allemaal",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD",
|
||||
"New Task": "Nieuwe taak",
|
||||
"New Time Entry": "Nieuwe tijd invoer",
|
||||
"New Timer Started": "Nieuwe Timer gestart",
|
||||
"Triggers when a new task is created in specified project.": "Triggert wanneer een nieuwe taak wordt aangemaakt in het opgegeven project.",
|
||||
"Triggers when a new time entry is created.": "Triggert wanneer een nieuwe tijdsvermelding wordt aangemaakt.",
|
||||
"Triggers when a new entry is started and running.": "Triggert wanneer een nieuwe invoer wordt gestart en uitgevoerd."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "Você pode obter sua chave de API navegando até **Preferências->Avançado**.",
|
||||
"Create Task": "Criar tarefa",
|
||||
"Create Time Entry": "Criar Registro de Tempo",
|
||||
"Start Timer": "Iniciar Temporizador",
|
||||
"Stop Timer": "Parar Temporizador",
|
||||
"Find Task": "Procurar Tarefa",
|
||||
"Find Time Entry": "Encontrar Registro de Tempo",
|
||||
"Find Running Timer": "Encontrar Temporizador em Execução",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Creates a new in a specific project.": "Cria um novo projeto específico.",
|
||||
"Creates a new time entry.": "Cria uma nova entrada de tempo.",
|
||||
"Starts a new time entry.": "Inicia uma nova entrada de tempo.",
|
||||
"Stops currently running timer on specified workspace.": "Para o temporizador atual no espaço de trabalho especificado.",
|
||||
"Finds an existing task in a specific project.": "Encontra uma tarefa existente em um projeto específico.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Localiza uma entrada de hora por descrição, inicia data ou hora de término.",
|
||||
"Finds currently running timer on specified workspace.": "Localiza o temporizador atualmente em execução no espaço de trabalho especificado.",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Workspace": "Workspace",
|
||||
"Project": "Projecto",
|
||||
"Task Name": "Nome da tarefa",
|
||||
"Status": "Estado",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Data de início",
|
||||
"End Datetime": "Data de término",
|
||||
"Entry Description": "Descrição da postagem",
|
||||
"Task": "Tarefas",
|
||||
"Billable": "Faturável",
|
||||
"Tags": "Etiquetas",
|
||||
"Exact Match ?": "Partida exata ?",
|
||||
"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)",
|
||||
"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..",
|
||||
"Active": "Ativo",
|
||||
"Done": "Concluído",
|
||||
"All": "TODOS",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA",
|
||||
"New Task": "Nova tarefa",
|
||||
"New Time Entry": "Novo Registro de Tempo",
|
||||
"New Timer Started": "Novo Temporizador Iniciado",
|
||||
"Triggers when a new task is created in specified project.": "Aciona quando uma nova tarefa é criada no projeto especificado.",
|
||||
"Triggers when a new time entry is created.": "Aciona quando uma nova entrada é criada.",
|
||||
"Triggers when a new entry is started and running.": "Dispara quando uma nova entrada é iniciada e executada."
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Clockify": "Клокафировать",
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "Ключ API можно получить, перейдя по ссылке **Preferences->Advanced**.",
|
||||
"Create Task": "Создать задачу",
|
||||
"Create Time Entry": "Создать запись",
|
||||
"Start Timer": "Запустить таймер",
|
||||
"Stop Timer": "Остановить таймер",
|
||||
"Find Task": "Найти задачу",
|
||||
"Find Time Entry": "Поиск времени входа",
|
||||
"Find Running Timer": "Найти таймер",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Creates a new in a specific project.": "Создает новый в конкретном проекте.",
|
||||
"Creates a new time entry.": "Создает новую запись времени.",
|
||||
"Starts a new time entry.": "Начинает новую запись.",
|
||||
"Stops currently running timer on specified workspace.": "Остановка таймера на указанном рабочем пространстве.",
|
||||
"Finds an existing task in a specific project.": "Находит существующее задание в конкретном проекте.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Находит запись времени по описанию, дате начала или дате окончания.",
|
||||
"Finds currently running timer on specified workspace.": "Идет текущий таймер на указанном рабочем пространстве.",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Workspace": "Рабочая область",
|
||||
"Project": "Проект",
|
||||
"Task Name": "Название задачи",
|
||||
"Status": "Status",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Дата начала",
|
||||
"End Datetime": "Дата окончания",
|
||||
"Entry Description": "Описание записи",
|
||||
"Task": "Задача",
|
||||
"Billable": "Оплачиваемый",
|
||||
"Tags": "Теги",
|
||||
"Exact Match ?": "Точное совпадение ?",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"Active": "Активен",
|
||||
"Done": "Done",
|
||||
"All": "Все",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD",
|
||||
"New Task": "Новая задача",
|
||||
"New Time Entry": "Новое время",
|
||||
"New Timer Started": "Новый таймер начался",
|
||||
"Triggers when a new task is created in specified project.": "Запускает при создании новой задачи в указанном проекте.",
|
||||
"Triggers when a new time entry is created.": "Триггеры при создании новой записи времени.",
|
||||
"Triggers when a new entry is started and running.": "Триггеры при запуске и запуске новой записи."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "You can obtain your API key by navigating to **Preferences->Advanced**.",
|
||||
"Create Task": "Create Task",
|
||||
"Create Time Entry": "Create Time Entry",
|
||||
"Start Timer": "Start Timer",
|
||||
"Stop Timer": "Stop Timer",
|
||||
"Find Task": "Find Task",
|
||||
"Find Time Entry": "Find Time Entry",
|
||||
"Find Running Timer": "Find Running Timer",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new in a specific project.": "Creates a new in a specific project.",
|
||||
"Creates a new time entry.": "Creates a new time entry.",
|
||||
"Starts a new time entry.": "Starts a new time entry.",
|
||||
"Stops currently running timer on specified workspace.": "Stops currently running timer on specified workspace.",
|
||||
"Finds an existing task in a specific project.": "Finds an existing task in a specific project.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Finds a time entry by description, start datetime or end datetime.",
|
||||
"Finds currently running timer on specified workspace.": "Finds currently running timer on specified workspace.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Workspace": "Workspace",
|
||||
"Project": "Project",
|
||||
"Task Name": "Task Name",
|
||||
"Status": "Status",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Start Datetime",
|
||||
"End Datetime": "End Datetime",
|
||||
"Entry Description": "Entry Description",
|
||||
"Task": "Task",
|
||||
"Billable": "Billable",
|
||||
"Tags": "Tags",
|
||||
"Exact Match ?": "Exact Match ?",
|
||||
"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)",
|
||||
"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..",
|
||||
"Active": "Active",
|
||||
"Done": "Done",
|
||||
"All": "All",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Task": "New Task",
|
||||
"New Time Entry": "New Time Entry",
|
||||
"New Timer Started": "New Timer Started",
|
||||
"Triggers when a new task is created in specified project.": "Triggers when a new task is created in specified project.",
|
||||
"Triggers when a new time entry is created.": "Triggers when a new time entry is created.",
|
||||
"Triggers when a new entry is started and running.": "Triggers when a new entry is started and running."
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Clockify": "Clockify",
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "You can obtain your API key by navigating to **Preferences->Advanced**.",
|
||||
"Create Task": "Create Task",
|
||||
"Create Time Entry": "Create Time Entry",
|
||||
"Start Timer": "Start Timer",
|
||||
"Stop Timer": "Stop Timer",
|
||||
"Find Task": "Find Task",
|
||||
"Find Time Entry": "Find Time Entry",
|
||||
"Find Running Timer": "Find Running Timer",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Creates a new in a specific project.": "Creates a new in a specific project.",
|
||||
"Creates a new time entry.": "Creates a new time entry.",
|
||||
"Starts a new time entry.": "Starts a new time entry.",
|
||||
"Stops currently running timer on specified workspace.": "Stops currently running timer on specified workspace.",
|
||||
"Finds an existing task in a specific project.": "Finds an existing task in a specific project.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Finds a time entry by description, start datetime or end datetime.",
|
||||
"Finds currently running timer on specified workspace.": "Finds currently running timer on specified workspace.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Workspace": "Workspace",
|
||||
"Project": "Project",
|
||||
"Task Name": "Task Name",
|
||||
"Status": "Status",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Start Datetime",
|
||||
"End Datetime": "End Datetime",
|
||||
"Entry Description": "Entry Description",
|
||||
"Task": "Task",
|
||||
"Billable": "Billable",
|
||||
"Tags": "Tags",
|
||||
"Exact Match ?": "Exact Match ?",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Active": "Tích cực",
|
||||
"Done": "Done",
|
||||
"All": "Tất cả",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Task": "New Task",
|
||||
"New Time Entry": "New Time Entry",
|
||||
"New Timer Started": "New Timer Started",
|
||||
"Triggers when a new task is created in specified project.": "Triggers when a new task is created in specified project.",
|
||||
"Triggers when a new time entry is created.": "Triggers when a new time entry is created.",
|
||||
"Triggers when a new entry is started and running.": "Triggers when a new entry is started and running."
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"You can obtain your API key by navigating to **Preferences->Advanced**.": "You can obtain your API key by navigating to **Preferences->Advanced**.",
|
||||
"Create Task": "Create Task",
|
||||
"Create Time Entry": "Create Time Entry",
|
||||
"Start Timer": "Start Timer",
|
||||
"Stop Timer": "Stop Timer",
|
||||
"Find Task": "Find Task",
|
||||
"Find Time Entry": "Find Time Entry",
|
||||
"Find Running Timer": "Find Running Timer",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Creates a new in a specific project.": "Creates a new in a specific project.",
|
||||
"Creates a new time entry.": "Creates a new time entry.",
|
||||
"Starts a new time entry.": "Starts a new time entry.",
|
||||
"Stops currently running timer on specified workspace.": "Stops currently running timer on specified workspace.",
|
||||
"Finds an existing task in a specific project.": "Finds an existing task in a specific project.",
|
||||
"Finds a time entry by description, start datetime or end datetime.": "Finds a time entry by description, start datetime or end datetime.",
|
||||
"Finds currently running timer on specified workspace.": "Finds currently running timer on specified workspace.",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Workspace": "Workspace",
|
||||
"Project": "项目",
|
||||
"Task Name": "Task Name",
|
||||
"Status": "状态",
|
||||
"Assignee": "Assignee",
|
||||
"Start Datetime": "Start Datetime",
|
||||
"End Datetime": "End Datetime",
|
||||
"Entry Description": "Entry Description",
|
||||
"Task": "Task",
|
||||
"Billable": "Billable",
|
||||
"Tags": "标签",
|
||||
"Exact Match ?": "精确匹配 ?",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Active": "使用中",
|
||||
"Done": "完成",
|
||||
"All": "所有的",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色",
|
||||
"New Task": "New Task",
|
||||
"New Time Entry": "New Time Entry",
|
||||
"New Timer Started": "New Timer Started",
|
||||
"Triggers when a new task is created in specified project.": "Triggers when a new task is created in specified project.",
|
||||
"Triggers when a new time entry is created.": "Triggers when a new time entry is created.",
|
||||
"Triggers when a new entry is started and running.": "Triggers when a new entry is started and running."
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { createCustomApiCallAction, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { createTaskAction } from './lib/actions/create-task';
|
||||
import { createTimeEntryAction } from './lib/actions/create-time-entry';
|
||||
import { findRunningTimerAction } from './lib/actions/find-running-timer';
|
||||
import { findTaskAction } from './lib/actions/find-task';
|
||||
import { findTimeEntryAction } from './lib/actions/find-time-entry';
|
||||
import { startTimerAction } from './lib/actions/start-timer';
|
||||
import { stopTimerAction } from './lib/actions/stop-timer';
|
||||
import { BASE_URL, clockifyApiCall } from './lib/common/client';
|
||||
import { newTaskTrigger } from './lib/triggers/new-task';
|
||||
import { newTimeEntryTrigger } from './lib/triggers/new-time-entry';
|
||||
import { newTimerStartedTrigger } from './lib/triggers/new-timer-started';
|
||||
|
||||
export const clockifyAuth = PieceAuth.SecretText({
|
||||
displayName:'API Key',
|
||||
description: `You can obtain your API key by navigating to **Preferences->Advanced**.`,
|
||||
required: true,
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
await clockifyApiCall({
|
||||
apiKey: auth,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: '/user',
|
||||
});
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API Key.',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const clockify = createPiece({
|
||||
displayName: 'Clockify',
|
||||
auth: clockifyAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/clockify.png',
|
||||
authors: ['rimjhimyadav', 'kishanprmr'],
|
||||
actions: [
|
||||
createTaskAction,
|
||||
createTimeEntryAction,
|
||||
startTimerAction,
|
||||
stopTimerAction,
|
||||
findTaskAction,
|
||||
findTimeEntryAction,
|
||||
findRunningTimerAction,
|
||||
createCustomApiCallAction({
|
||||
auth: clockifyAuth,
|
||||
baseUrl: () => BASE_URL,
|
||||
authMapping: async (auth) => {
|
||||
return {
|
||||
'X-Api-Key': auth.secret_text,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [newTaskTrigger, newTimeEntryTrigger, newTimerStartedTrigger],
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { assigneeIds, projectId, workspaceId } from '../common/props';
|
||||
|
||||
export const createTaskAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'create-task',
|
||||
displayName: 'Create Task',
|
||||
description: 'Creates a new in a specific project.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: true,
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Task Name',
|
||||
required: true,
|
||||
}),
|
||||
status: Property.StaticDropdown({
|
||||
displayName: 'Status',
|
||||
required: false,
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{
|
||||
label: 'Active',
|
||||
value: 'ACTIVE',
|
||||
},
|
||||
{
|
||||
label: 'Done',
|
||||
value: 'DONE',
|
||||
},
|
||||
{
|
||||
label: 'All',
|
||||
value: 'ALL',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
assigneeIds: assigneeIds({
|
||||
displayName: 'Assignee',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId, projectId, name, status } = context.propsValue;
|
||||
const assigneeIds = context.propsValue.assigneeIds ?? [];
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/projects/${projectId}/tasks`,
|
||||
body: {
|
||||
name,
|
||||
status,
|
||||
assigneeIds,
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, tagIds, taskId, workspaceId } from '../common/props';
|
||||
|
||||
export const createTimeEntryAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'create-time-entry',
|
||||
displayName: 'Create Time Entry',
|
||||
description: 'Creates a new time entry.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
start: Property.DateTime({
|
||||
displayName: 'Start Datetime',
|
||||
required: true,
|
||||
}),
|
||||
end: Property.DateTime({
|
||||
displayName: 'End Datetime',
|
||||
required: true,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Entry Description',
|
||||
required: false,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: false,
|
||||
}),
|
||||
taskId: taskId({
|
||||
displayName: 'Task',
|
||||
required: false,
|
||||
}),
|
||||
billable: Property.Checkbox({
|
||||
displayName: 'Billable',
|
||||
required: false,
|
||||
}),
|
||||
tagIds: tagIds({
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId, projectId, start, end, description, billable, taskId } =
|
||||
context.propsValue;
|
||||
const tagIds = context.propsValue.tagIds ?? [];
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/time-entries`,
|
||||
body: {
|
||||
billable,
|
||||
description,
|
||||
start,
|
||||
end,
|
||||
projectId,
|
||||
taskId,
|
||||
tagIds,
|
||||
type: 'REGULAR',
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { workspaceId } from '../common/props';
|
||||
|
||||
export const findRunningTimerAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'find-running-timer',
|
||||
displayName: 'Find Running Timer',
|
||||
description: 'Finds currently running timer on specified workspace.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/time-entries/status/in-progress`,
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, workspaceId } from '../common/props';
|
||||
|
||||
export const findTaskAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'find-task',
|
||||
displayName: 'Find Task',
|
||||
description: 'Finds an existing task in a specific project.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: true,
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Task Name',
|
||||
required: true,
|
||||
}),
|
||||
exactMatch: Property.Checkbox({
|
||||
displayName: 'Exact Match ?',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId, projectId, name, exactMatch } = context.propsValue;
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/projects/${projectId}/tasks`,
|
||||
query: {
|
||||
name,
|
||||
'strict-name-search': exactMatch ? 'true' : 'false',
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, taskId, workspaceId } from '../common/props';
|
||||
|
||||
export const findTimeEntryAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'find-time-entry',
|
||||
displayName: 'Find Time Entry',
|
||||
description: 'Finds a time entry by description, start datetime or end datetime.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
start: Property.DateTime({
|
||||
displayName: 'Start Datetime',
|
||||
required: false,
|
||||
}),
|
||||
end: Property.DateTime({
|
||||
displayName: 'End Datetime',
|
||||
required: false,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Entry Description',
|
||||
required: false,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: false,
|
||||
}),
|
||||
taskId: taskId({
|
||||
displayName: 'Task',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId, projectId, start, end, description, taskId } = context.propsValue;
|
||||
|
||||
const currentUserResponse = await clockifyApiCall<{ id: string; email: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/user`,
|
||||
});
|
||||
|
||||
const userId = currentUserResponse.id;
|
||||
|
||||
const qs: QueryParams = { hydrated: 'true' };
|
||||
|
||||
if (description) qs['description'] = description;
|
||||
if (start) qs['start'] = start;
|
||||
if (end) qs['end'] = end;
|
||||
if (projectId) qs['project'] = projectId as string;
|
||||
if (taskId) qs['task'] = taskId as string;
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/user/${userId}/time-entries`,
|
||||
query: qs,
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, tagIds, taskId, workspaceId } from '../common/props';
|
||||
|
||||
export const startTimerAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'start-timer',
|
||||
displayName: 'Start Timer',
|
||||
description: 'Starts a new time entry.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Entry Description',
|
||||
required: false,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: false,
|
||||
}),
|
||||
taskId: taskId({
|
||||
displayName: 'Task',
|
||||
required: false,
|
||||
}),
|
||||
billable: Property.Checkbox({
|
||||
displayName: 'Billable',
|
||||
required: false,
|
||||
}),
|
||||
tagIds: tagIds({
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId, projectId, description, billable, taskId } = context.propsValue;
|
||||
const tagIds = context.propsValue.tagIds ?? [];
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/time-entries`,
|
||||
body: {
|
||||
billable,
|
||||
description,
|
||||
start: new Date().toISOString(),
|
||||
projectId,
|
||||
taskId,
|
||||
tagIds,
|
||||
type: 'REGULAR',
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { workspaceId } from '../common/props';
|
||||
|
||||
export const stopTimerAction = createAction({
|
||||
auth: clockifyAuth,
|
||||
name: 'stop-timer',
|
||||
displayName: 'Stop Timer',
|
||||
description: 'Stops currently running timer on specified workspace.',
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const currentUserResponse = await clockifyApiCall<{ id: string; email: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/user`,
|
||||
});
|
||||
|
||||
const userId = currentUserResponse.id;
|
||||
|
||||
const response = await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.PATCH,
|
||||
resourceUri: `/workspaces/${workspaceId}/user/${userId}/time-entries`,
|
||||
body: {
|
||||
end: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import {
|
||||
httpClient,
|
||||
HttpMessageBody,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
QueryParams,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
export type ClockifyApiCallParams = {
|
||||
apiKey: string;
|
||||
method: HttpMethod;
|
||||
resourceUri: string;
|
||||
query?: Record<string, string | number | string[] | undefined>;
|
||||
body?: any;
|
||||
};
|
||||
|
||||
export const BASE_URL = 'https://api.clockify.me/api/v1';
|
||||
|
||||
export async function clockifyApiCall<T extends HttpMessageBody>({
|
||||
apiKey,
|
||||
method,
|
||||
resourceUri,
|
||||
query,
|
||||
body,
|
||||
}: ClockifyApiCallParams): Promise<T> {
|
||||
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: BASE_URL + resourceUri,
|
||||
headers: {
|
||||
'X-Api-Key': apiKey,
|
||||
},
|
||||
queryParams: qs,
|
||||
body,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { clockifyApiCall } from './client';
|
||||
import { clockifyAuth } from '../..';
|
||||
|
||||
interface DropdownParams {
|
||||
displayName: string;
|
||||
description?: string;
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const workspaceId = (params: DropdownParams) =>
|
||||
Property.Dropdown({
|
||||
auth: clockifyAuth,
|
||||
displayName: params.displayName,
|
||||
description: params.description,
|
||||
required: params.required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
const response = await clockifyApiCall<{ id: string; name: string }[]>({
|
||||
apiKey: auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: '/workspaces',
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((workspace) => ({
|
||||
label: workspace.name,
|
||||
value: workspace.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const projectId = (params: DropdownParams) =>
|
||||
Property.Dropdown({
|
||||
auth: clockifyAuth,
|
||||
displayName: params.displayName,
|
||||
description: params.description,
|
||||
required: params.required,
|
||||
refreshers: ['workspaceId'],
|
||||
options: async ({ auth, workspaceId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select workspace first.',
|
||||
};
|
||||
}
|
||||
|
||||
const response = await clockifyApiCall<{ id: string; name: string }[]>({
|
||||
apiKey: auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/projects`,
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((project) => ({
|
||||
label: project.name,
|
||||
value: project.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const assigneeIds = (params: DropdownParams) =>
|
||||
Property.MultiSelectDropdown({
|
||||
auth: clockifyAuth,
|
||||
displayName: params.displayName,
|
||||
description: params.description,
|
||||
required: params.required,
|
||||
refreshers: ['workspaceId'],
|
||||
options: async ({ auth, workspaceId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select workspace first.',
|
||||
};
|
||||
}
|
||||
|
||||
const response = await clockifyApiCall<{ id: string; email: string }[]>({
|
||||
apiKey: auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/users`,
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((user) => ({
|
||||
label: user.email,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const taskId = (params: DropdownParams) =>
|
||||
Property.Dropdown({
|
||||
auth: clockifyAuth,
|
||||
displayName: params.displayName,
|
||||
description: params.description,
|
||||
required: params.required,
|
||||
refreshers: ['workspaceId', 'projectId'],
|
||||
options: async ({ auth, workspaceId, projectId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select workspace first.',
|
||||
};
|
||||
}
|
||||
|
||||
if (!projectId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select project first.',
|
||||
};
|
||||
}
|
||||
|
||||
const response = await clockifyApiCall<{ id: string; name: string }[]>({
|
||||
apiKey: auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/projects/${projectId}/tasks`,
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((task) => ({
|
||||
label: task.name,
|
||||
value: task.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const tagIds = (params: DropdownParams) =>
|
||||
Property.MultiSelectDropdown({
|
||||
auth: clockifyAuth,
|
||||
displayName: params.displayName,
|
||||
description: params.description,
|
||||
required: params.required,
|
||||
refreshers: ['workspaceId'],
|
||||
options: async ({ auth, workspaceId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please select workspace first.',
|
||||
};
|
||||
}
|
||||
const response = await clockifyApiCall<{ id: string; name: string }[]>({
|
||||
apiKey: auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/tags`,
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, workspaceId } from '../common/props';
|
||||
|
||||
const TRIGGER_KEY = 'new-task-trigger';
|
||||
|
||||
export const newTaskTrigger = createTrigger({
|
||||
auth: clockifyAuth,
|
||||
name: 'new-task',
|
||||
displayName: 'New Task',
|
||||
description: 'Triggers when a new task is created in specified project.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { workspaceId, projectId } = context.propsValue;
|
||||
|
||||
const response = await clockifyApiCall<{ id: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks`,
|
||||
body: {
|
||||
url: context.webhookUrl,
|
||||
webhookEvent: 'NEW_TASK',
|
||||
triggerSourceType: 'PROJECT_ID',
|
||||
triggerSource: [projectId],
|
||||
},
|
||||
});
|
||||
|
||||
await context.store.put<string>(TRIGGER_KEY, response.id);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const webhookId = await context.store.get<string>(TRIGGER_KEY);
|
||||
|
||||
if (!isNil(webhookId)) {
|
||||
await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.DELETE,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks/${webhookId}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
async test(context) {
|
||||
const { workspaceId, projectId } = context.propsValue;
|
||||
|
||||
const response = await clockifyApiCall<{ id: string }[]>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/projects/${projectId}/tasks`,
|
||||
query: {
|
||||
page: '1',
|
||||
'page-size': 5,
|
||||
},
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
sampleData: {
|
||||
id: '684538940300f917a02f642f',
|
||||
name: 'Test',
|
||||
projectId: '68444b15551a9934b5034263',
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
assigneeIds: [],
|
||||
assigneeId: '',
|
||||
userGroupIds: [],
|
||||
estimate: 'PT0S',
|
||||
status: 'ACTIVE',
|
||||
budgetEstimate: 0,
|
||||
billable: true,
|
||||
hourlyRate: null,
|
||||
costRate: null,
|
||||
progress: null,
|
||||
duration: 'PT0S',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,187 @@
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { projectId, taskId, workspaceId } from '../common/props';
|
||||
|
||||
const TRIGGER_KEY = 'new-time-entry-trigger';
|
||||
|
||||
export const newTimeEntryTrigger = createTrigger({
|
||||
auth: clockifyAuth,
|
||||
name: 'new-time-entry',
|
||||
displayName: 'New Time Entry',
|
||||
description: 'Triggers when a new time entry is created.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
projectId: projectId({
|
||||
displayName: 'Project',
|
||||
required: false,
|
||||
}),
|
||||
taskId: taskId({
|
||||
displayName: 'Task',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { workspaceId, projectId, taskId } = context.propsValue;
|
||||
|
||||
const payload: Record<string, any> = {
|
||||
url: context.webhookUrl,
|
||||
webhookEvent: 'NEW_TIME_ENTRY',
|
||||
};
|
||||
|
||||
if (workspaceId) {
|
||||
payload['triggerSourceType'] = 'WORKSPACE_ID';
|
||||
payload['triggerSource'] = [workspaceId];
|
||||
}
|
||||
|
||||
if (projectId) {
|
||||
payload['triggerSourceType'] = 'PROJECT_ID';
|
||||
payload['triggerSource'] = [projectId];
|
||||
}
|
||||
|
||||
if (taskId) {
|
||||
payload['triggerSourceType'] = 'TASK_ID';
|
||||
payload['triggerSource'] = [taskId];
|
||||
}
|
||||
|
||||
const response = await clockifyApiCall<{ id: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks`,
|
||||
body: payload,
|
||||
});
|
||||
|
||||
await context.store.put<string>(TRIGGER_KEY, response.id);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const webhookId = await context.store.get<string>(TRIGGER_KEY);
|
||||
|
||||
if (!isNil(webhookId)) {
|
||||
await clockifyApiCall({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.DELETE,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks/${webhookId}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
async test(context) {
|
||||
const { workspaceId, projectId, taskId } = context.propsValue;
|
||||
const currentUserResponse = await clockifyApiCall<{ id: string; email: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/user`,
|
||||
});
|
||||
|
||||
const userId = currentUserResponse.id;
|
||||
|
||||
const qs: QueryParams = { hydrated: 'true', page: '1', 'page-size': '5' };
|
||||
|
||||
if (projectId) qs['project'] = projectId as string;
|
||||
if (taskId) qs['task'] = taskId as string;
|
||||
|
||||
const response = await clockifyApiCall<{id:string}[]>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/workspaces/${workspaceId}/user/${userId}/time-entries`,
|
||||
query: qs,
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
sampleData: {
|
||||
id: '68453d0cf0c88d522704ab76',
|
||||
description: 'Test',
|
||||
userId: '684446430300f917a02c198a',
|
||||
billable: true,
|
||||
projectId: '68444b15551a9934b5034263',
|
||||
timeInterval: {
|
||||
start: '2025-06-16T07:05:00Z',
|
||||
end: '2025-06-16T18:53:00Z',
|
||||
duration: 'PT11H48M',
|
||||
timeZone: 'Asia/Calcutta',
|
||||
offsetStart: 19800,
|
||||
offsetEnd: 19800,
|
||||
zonedStart: '2025-06-16T12:35:00',
|
||||
zonedEnd: '2025-06-17T00:23:00',
|
||||
},
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
isLocked: false,
|
||||
hourlyRate: null,
|
||||
costRate: null,
|
||||
customFieldValues: [],
|
||||
type: 'REGULAR',
|
||||
kioskId: null,
|
||||
approvalStatus: null,
|
||||
projectCurrency: null,
|
||||
currentlyRunning: false,
|
||||
project: {
|
||||
name: 'Test',
|
||||
clientId: '',
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
billable: true,
|
||||
estimate: {
|
||||
estimate: 'PT0S',
|
||||
type: 'AUTO',
|
||||
},
|
||||
color: '#039BE5',
|
||||
archived: false,
|
||||
clientName: '',
|
||||
duration: 'PT47H12M45S',
|
||||
note: '',
|
||||
activeEstimate: 'NONE',
|
||||
timeEstimate: {
|
||||
includeNonBillable: true,
|
||||
estimate: 0,
|
||||
type: 'AUTO',
|
||||
resetOption: null,
|
||||
},
|
||||
budgetEstimate: null,
|
||||
id: '68444b15551a9934b5034263',
|
||||
public: true,
|
||||
template: false,
|
||||
},
|
||||
task: {
|
||||
name: 'test',
|
||||
projectId: '68444b15551a9934b5034263',
|
||||
assigneeId: '684446430300f917a02c198a',
|
||||
assigneeIds: ['684446430300f917a02c198a'],
|
||||
userGroupIds: [],
|
||||
estimate: 'PT0S',
|
||||
status: 'ACTIVE',
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
budgetEstimate: 0,
|
||||
billable: true,
|
||||
hourlyRate: null,
|
||||
costRate: null,
|
||||
auditMetadata: {
|
||||
updatedAt: 1749306307000,
|
||||
},
|
||||
id: '68444badb7688b61f151284d',
|
||||
duration: 'PT35H24M41S',
|
||||
},
|
||||
user: {
|
||||
id: '684446430300f917a02c198a',
|
||||
name: 'johndoe',
|
||||
status: 'ACTIVE',
|
||||
},
|
||||
tags: [
|
||||
{
|
||||
name: 'new',
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
archived: false,
|
||||
id: '68452a1b0300f917a02f30bc',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { clockifyAuth } from '../../index';
|
||||
import { clockifyApiCall } from '../common/client';
|
||||
import { workspaceId } from '../common/props';
|
||||
|
||||
const TRIGGER_KEY = 'new-timer-started-trigger';
|
||||
|
||||
export const newTimerStartedTrigger = createTrigger({
|
||||
auth: clockifyAuth,
|
||||
name: 'new-timer-started',
|
||||
displayName: 'New Timer Started',
|
||||
description: 'Triggers when a new entry is started and running.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {
|
||||
workspaceId: workspaceId({
|
||||
displayName: 'Workspace',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const response = await clockifyApiCall<{ id: string }>({
|
||||
apiKey: context.auth.secret_text,
|
||||
method: HttpMethod.POST,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks`,
|
||||
body: {
|
||||
url: context.webhookUrl,
|
||||
webhookEvent: 'NEW_TIMER_STARTED',
|
||||
triggerSourceType: 'WORKSPACE_ID',
|
||||
triggerSource: [workspaceId],
|
||||
},
|
||||
});
|
||||
|
||||
await context.store.put<string>(TRIGGER_KEY, response.id);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const { workspaceId } = context.propsValue;
|
||||
|
||||
const webhookId = await context.store.get<string>(TRIGGER_KEY);
|
||||
|
||||
if (!isNil(webhookId)) {
|
||||
await clockifyApiCall<{ id: string }>({
|
||||
apiKey: context.auth.secret_text ,
|
||||
method: HttpMethod.DELETE,
|
||||
resourceUri: `/workspaces/${workspaceId}/webhooks/${webhookId}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
sampleData: {
|
||||
id: '684538940300f917a02f642f',
|
||||
name: 'Test',
|
||||
projectId: '68444b15551a9934b5034263',
|
||||
workspaceId: '684446430300f917a02c198b',
|
||||
assigneeIds: [],
|
||||
assigneeId: '',
|
||||
userGroupIds: [],
|
||||
estimate: 'PT0S',
|
||||
status: 'ACTIVE',
|
||||
budgetEstimate: 0,
|
||||
billable: true,
|
||||
hourlyRate: null,
|
||||
costRate: null,
|
||||
progress: null,
|
||||
duration: 'PT0S',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user