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:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Business-Intelligenz- und Analyseplattform für die Datenvisualisierung",
"Server URL": "Server-URL",
"API Version": "API-Version",
"Site Content URL": "URL des Seiteninhalts",
"Username": "Benutzername",
"Password": "Kennwort",
"Personal Access Token Name": "Name des persönlichen Zugangs-Token",
"Personal Access Token Secret": "Persönlicher Zugangs-Token Geheimnis",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Ihre Tableau Server oder Tableau Cloud URL (z.B. https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Tableau REST API Version (z.B. 3.19, 3.20, 3.26). Überprüfen Sie Ihre Tableau Server-Dokumentation auf unterstützte Versionen. Verwenden Sie 3.26 für die meisten Tableau Cloud-Instanzen.",
"Your Tableau site name (leave empty for default site)": "Ihr Tableau-Site Name (leer lassen für Standardseite)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Ihr Tableau Benutzername (E-Mail für Tableau Cloud oder Domain\\Benutzername für Server)",
"Your Tableau password": "Ihr Tableau Passwort",
"Name of your Personal Access Token": "Name Ihres persönlichen Zugangs-Token",
"Secret value of your Personal Access Token": "Geheimer Wert Ihres persönlichen Zugangs-Token",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentifizierung Setup\n\n### Für Tableau Cloud:\n- **Server URL**: Verwenden Sie Ihre Tableau Cloud URL (z.B. https://10az.online.tableau.com oder https://us-east-1.online.tableau. om)\n- **Site Content URL**: Your site name (leave leer für die Standardseite)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e. ., https://tableau.yourcompany. om)\n- **Site Content URL**: Ihre Site Name (lassen Sie leer für die Standardseite)\n\n### Authentifizierungsmethoden:\nWählen Sie **entweder** Benutzername/Passwort **or** Persönliches Zugangs-Token:\n\n#### Option 1: Benutzername und Passwort\n- Geben Sie Ihren Tableau Benutzernamen und Passwort\n- Für Tableau Cloud, verwenden Sie Ihre E-Mail-Adresse als Benutzername\n- Für Tableau Server, Verwenden Sie Ihre Domain\\username wenn Sie Active Directory\n\n#### Option 2: Persönliches Zugangs-Token (Empfohlen)\n- Gehen Sie zu Ihren Kontoeinstellungen\n- Erstellen Sie ein persönliches Zugangs-Token\n- Geben Sie den Token-Namen und das Geheimnis\n\n**Sicherheits-Hinweis:** Persönliche Zugriffs-Token werden für die Produktion empfohlen, da sie für bessere Sicherheit sorgen und individuell widerrufen werden können.\n",
"Download View": "Download Ansicht",
"Run Extract Refresh Task": "Extrahiere Aktualisierungsaufgabe ausführen",
"Refresh Workbook": "Arbeitsbuch aktualisieren",
"Find View": "Ansicht finden",
"Find Workbook": "Arbeitsbuch finden",
"Download a view from a workbook in the specified format": "Eine Ansicht aus einem Arbeitsbuch im angegebenen Format herunterladen",
"Runs the specified extract refresh task and returns job information": "Führt den angegebenen Extrakt Aktualisierungsauftrag aus und gibt Jobinformationen zurück",
"Refreshes the specified workbook immediately": "Aktualisiert das angegebene Arbeitsbuch sofort",
"Finds a view based on name (URL name)": "Findet eine Ansicht basierend auf Namen (URL-Name)",
"Finds a workbook based on ID or content URL": "Findet ein Arbeitsbuch basierend auf ID oder Inhalts-URL",
"View": "Ansicht",
"Format": "Format",
"Max Age (minutes)": "Max. Alter (Minuten)",
"Image Resolution": "Bildauflösung",
"Visualization Width": "Visualisierungsbreite",
"Visualization Height": "Visualisierungshöhe",
"Page Type": "Seitentyp",
"Orientation": "Ausrichtung",
"Extract Refresh Task": "Aktualisierungsaufgabe extrahieren",
"Workbook": "Arbeitsbuch",
"View Name": "Anzeigename",
"Search By": "Suche nach",
"Workbook ID": "Arbeitsbuch-ID",
"Content URL": "Inhalts-URL",
"Select the view to download": "Ansicht zum Download auswählen",
"The format to download the view in": "Das Format zum Herunterladen der Ansicht in",
"Maximum age of cached data in minutes (default: 60)": "Maximales Alter der zwischengespeicherten Daten in Minuten (Standard: 60)",
"Resolution for image format (high for maximum pixel density)": "Auflösung für Bildformat (hoch für maximale Pixeldichte)",
"Width of the rendered image/PDF in pixels": "Breite des gerenderten Bilds/PDFs in Pixeln",
"Height of the rendered image/PDF in pixels": "Höhe des gerenderten Bilds/PDFs in Pixeln",
"Page size for PDF format": "Seitengröße für PDF-Format",
"Page orientation for PDF format": "Seitenausrichtung für PDF-Format",
"Select the extract refresh task to run": "Wählen Sie die extrahierte Aktualisierung Aufgabe zum Ausführen",
"Select the workbook to refresh": "Arbeitsbuch zum Aktualisieren auswählen",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "Der URL-Name der zu findenden Ansicht (z.B. Blatt1 von /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Wählen Sie, ob Sie nach Workbook-ID oder Inhalts-URL suchen möchten",
"The ID of the workbook to find": "Die ID des zu findenden Arbeitsbuchs",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "Die URL des zu findenden Arbeitsbuchs (z.B. \"MyWorkbook\" von /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "Bild (PNG)",
"PDF": "PDF",
"Excel Crosstab": "Excel Crosstab",
"Letter": "Brief",
"Legal": "Rechtlich",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Exekutive",
"Folio": "Folio",
"Ledger": "Ledger",
"Note": "Notiz",
"Quarto": "Quarto",
"Tabloid": "Tabloid",
"Portrait": "Hochformat",
"Landscape": "Querformat",
"Workbook Event": "Arbeitsbuch-Event",
"Workbook Refresh Event": "Arbeitsbuch Aktualisiere Event",
"Datasource Event": "Datenquellen-Ereignis",
"Datasource Refresh Event": "Aktualisiere Datenquelle Ereignis",
"User Deleted": "Benutzer gelöscht",
"View Deleted": "Gelöschte Ansicht",
"Label Event": "Label Ereignis",
"New Job": "Neuer Job",
"List Extract Refresh Tasks": "Aktualisiere Aufgaben auflisten",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Wird ausgelöst, wenn ein Arbeitsbuchereignis auftritt (erstellt, aktualisiert oder gelöscht)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Wird ausgelöst, wenn ein Arbeitsbuch Aktualisierungsereignis auftritt (gestartet, erfolgreich oder fehlgeschlagen)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Wird ausgelöst, wenn ein Datenquellenereignis auftritt (erstellt, aktualisiert oder gelöscht)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Wird ausgelöst, wenn ein Datenquelle Aktualisierungsereignis auftritt (gestartet, erfolgreich oder fehlgeschlagen)",
"Triggers when a user is deleted": "Wird ausgelöst, wenn ein Benutzer gelöscht wird",
"Triggers when a workbook view is deleted": "Wird ausgelöst, wenn eine Arbeitsbuchansicht gelöscht wird",
"Triggers when a label event occurs (created, updated, or deleted)": "Wird ausgelöst, wenn ein Label-Ereignis auftritt (erstellt, aktualisiert oder gelöscht)",
"Triggers when a job matches the specified criteria": "Löst aus, wenn ein Job den angegebenen Kriterien entspricht",
"Lists extract refresh tasks for the site": "Extrahiert Aktualisierungsaufgaben für die Seite",
"Event Type": "Ereignistyp",
"Job Type": "Job Typ",
"Status": "Status",
"Select the workbook event to trigger on": "Wählen Sie das zu startende Arbeitsmakler-Ereignis",
"Select the workbook refresh event to trigger on": "Wählen Sie das zu startende Arbeitsbuch Aktualisierungsereignis",
"Select the datasource event to trigger on": "Wählen Sie das Datasource-Ereignis, das ausgelöst werden soll",
"Select the datasource refresh event to trigger on": "Wählen Sie das zu startende Datenquell-Aktualisierungsereignis aus",
"Select the label event to trigger on": "Wählen Sie das zu startende Label Event",
"Filter by job type (optional)": "Nach Job-Typ filtern (optional)",
"Filter by job status (optional)": "Nach Job-Status filtern (optional)",
"Created": "Erstellt",
"Updated": "Updated",
"Deleted": "Gelöscht",
"Refresh Started": "Aktualisierung gestartet",
"Refresh Succeeded": "Aktualisierung erfolgreich",
"Refresh Failed": "Aktualisierung fehlgeschlagen",
"All Job Types": "Alle Job-Typen",
"Refresh Extracts": "Extrakte aktualisieren",
"Increment Extracts": "Erhöhte Extrakte",
"Run Flow": "Flow ausführen",
"Refresh Datasource": "Datenquelle aktualisieren",
"All Statuses": "Alle Status",
"Success": "Erfolg",
"Failed": "Fehlgeschlagen",
"InProgress": "Eingehende Fortschritte",
"Pending": "Ausstehend",
"Cancelled": "Abgebrochen"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Plataforma de análisis e inteligencia de negocios para la visualización de datos",
"Server URL": "URL del servidor",
"API Version": "Versión de API",
"Site Content URL": "URL del contenido del sitio",
"Username": "Usuario",
"Password": "Contraseña",
"Personal Access Token Name": "Nombre del token de acceso personal",
"Personal Access Token Secret": "Clave personal de acceso secreto",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Tu servidor Tableau o Tableau Cloud URL (ej., https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Versión de la API Tableau REST (por ejemplo, 3.19, 3.20, 3.26). Revise la documentación de su servidor Tableau para ver las versiones soportadas. Use 3.26 para la mayoría de las instancias de Tableau Cloud.",
"Your Tableau site name (leave empty for default site)": "El nombre de su sitio Tableau (déjelo vacío para el sitio predeterminado)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Tu nombre de usuario de Tableau (email para Tableau Cloud, o dominio\\nombre de usuario para el servidor)",
"Your Tableau password": "Su contraseña de Tableau",
"Name of your Personal Access Token": "Nombre de su token de acceso personal",
"Secret value of your Personal Access Token": "Valor secreto de su token de acceso personal",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Access Token:\n\n#### Option 1: Username and Password\n- Enter your Tableau username and password\n- For Tableau Cloud, use your email address as username\n- For Tableau Server, use your domain\\username if using Active Directory\n\n#### Option 2: Personal Access Token (Recommended)\n- Go to your Tableau account settings\n- Generate a Personal Access Token\n- Enter the token name and secret\n\n**Security Note:** Personal Access Tokens are recommended for production use as they provide better security and can be revoked individually.\n",
"Download View": "Descargar vista",
"Run Extract Refresh Task": "Ejecutar Extracto Actualizar Tarea",
"Refresh Workbook": "Actualizar Libro de Trabajo",
"Find View": "Buscar vista",
"Find Workbook": "Buscar Libro de Trabajo",
"Download a view from a workbook in the specified format": "Descargar una vista de un libro en el formato especificado",
"Runs the specified extract refresh task and returns job information": "Ejecuta la tarea de actualización de extracto especificada y devuelve la información del trabajo",
"Refreshes the specified workbook immediately": "Actualiza inmediatamente el libro de trabajo especificado",
"Finds a view based on name (URL name)": "Encuentra una vista basada en el nombre (nombre URL)",
"Finds a workbook based on ID or content URL": "Encuentra un libro basado en el ID o la URL del contenido",
"View": "Ver",
"Format": "Formatear",
"Max Age (minutes)": "Edad Máxima (minutos)",
"Image Resolution": "Resolución de imagen",
"Visualization Width": "Ancho de visualización",
"Visualization Height": "Altura de visualización",
"Page Type": "Tipo de página",
"Orientation": "Orientación",
"Extract Refresh Task": "Extraer Tarea de Actualización",
"Workbook": "Libro de trabajo",
"View Name": "Ver nombre",
"Search By": "Buscar por",
"Workbook ID": "ID del Libro de Trabajo",
"Content URL": "URL de contenido",
"Select the view to download": "Seleccione la vista para descargar",
"The format to download the view in": "El formato para descargar la vista en",
"Maximum age of cached data in minutes (default: 60)": "Edad máxima de los datos en caché en minutos (por defecto: 60)",
"Resolution for image format (high for maximum pixel density)": "Resolución del formato de imagen (alto para la máxima densidad de píxeles)",
"Width of the rendered image/PDF in pixels": "Ancho de la imagen/PDF en píxeles",
"Height of the rendered image/PDF in pixels": "Altura de la imagen/PDF en píxeles",
"Page size for PDF format": "Tamaño de página para formato PDF",
"Page orientation for PDF format": "Orientación de la página para formato PDF",
"Select the extract refresh task to run": "Seleccione la tarea de actualizar extracto para ejecutar",
"Select the workbook to refresh": "Seleccione la libreta de trabajo para actualizar",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "El nombre de la URL de la vista a encontrar (por ejemplo, Hoja1 de /views/workbook/Hoja1)",
"Choose whether to search by workbook ID or content URL": "Elija si desea buscar por el ID del libro de trabajo o la URL del contenido",
"The ID of the workbook to find": "El ID del libro de trabajo a encontrar",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "La URL del contenido de la libreta de trabajo a encontrar (por ejemplo, \"MyWorkbook\" de /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "Imagen (PNG)",
"PDF": "DF",
"Excel Crosstab": "Crosstab de Excel",
"Letter": "Letra",
"Legal": "Legal",
"A4": "R4",
"A3": "R3",
"A5": "R5",
"B5": "B5",
"Executive": "Ejecutivo",
"Folio": "Folio",
"Ledger": "Libro",
"Note": "Nota",
"Quarto": "Quarto",
"Tabloid": "Tabloide",
"Portrait": "Retrato",
"Landscape": "Paisaje",
"Workbook Event": "Evento del Libro de Trabajo",
"Workbook Refresh Event": "Evento de actualización del Libro de Trabajo",
"Datasource Event": "Evento de datos",
"Datasource Refresh Event": "Evento de actualización de datos",
"User Deleted": "Usuario eliminado",
"View Deleted": "Vista eliminada",
"Label Event": "Evento de etiqueta",
"New Job": "Nuevo Job",
"List Extract Refresh Tasks": "Extraer Lista Tareas Actualizadas",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Dispara cuando ocurre un evento de la libreta de trabajo (creado, actualizado o eliminado)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Dispara cuando se produce un evento de actualización de una libreta de trabajo (iniciado, exitoso o fallado)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Dispara cuando ocurre un evento de referencia de datos (creado, actualizado o eliminado)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Dispara cuando se produce un evento de refresco de un datastro (iniciado, exitoso o fallado)",
"Triggers when a user is deleted": "Dispara cuando un usuario es eliminado",
"Triggers when a workbook view is deleted": "Dispara cuando se borra una vista de libro",
"Triggers when a label event occurs (created, updated, or deleted)": "Dispara cuando ocurre un evento de etiqueta (creado, actualizado o eliminado)",
"Triggers when a job matches the specified criteria": "Dispara cuando un trabajo coincide con los criterios especificados",
"Lists extract refresh tasks for the site": "Lista las tareas de actualización de extracción para el sitio",
"Event Type": "Tipo de evento",
"Job Type": "Tipo de trabajo",
"Status": "Estado",
"Select the workbook event to trigger on": "Seleccione el evento de la libreta de trabajo en el que activar",
"Select the workbook refresh event to trigger on": "Seleccione la libreta de trabajo actualizar el evento para activar",
"Select the datasource event to trigger on": "Seleccione el evento de almacenamiento en el que se activará",
"Select the datasource refresh event to trigger on": "Seleccione el evento de actualización de almacenamiento para activar",
"Select the label event to trigger on": "Selecciona el evento de la etiqueta en la que activar",
"Filter by job type (optional)": "Filtrar por tipo de trabajo (opcional)",
"Filter by job status (optional)": "Filtrar por estado de trabajo (opcional)",
"Created": "Creado",
"Updated": "Actualizado",
"Deleted": "Eliminado",
"Refresh Started": "Actualización iniciada",
"Refresh Succeeded": "Actualización exitosa",
"Refresh Failed": "Error al actualizar",
"All Job Types": "Todos los tipos de trabajo",
"Refresh Extracts": "Actualizar extractos",
"Increment Extracts": "Incrementar extractos",
"Run Flow": "Ejecutar Flow",
"Refresh Datasource": "Actualizar datos",
"All Statuses": "Todos los estados",
"Success": "Éxito",
"Failed": "Fallado",
"InProgress": "Progreso",
"Pending": "Pendiente",
"Cancelled": "Cancelado"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Plateforme d'intelligence d'entreprise et d'analyse pour la visualisation des données",
"Server URL": "URL du serveur",
"API Version": "Version de l'API",
"Site Content URL": "URL du contenu du site",
"Username": "Nom d'utilisateur",
"Password": "Password",
"Personal Access Token Name": "Nom du jeton d'accès personnel",
"Personal Access Token Secret": "Secret du jeton d'accès personnel",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "URL de votre serveur Tableau ou Tableau Cloud (par exemple, https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Version de l'API REST Tableau (ex: 3.19, 3.20, 3.26). Vérifiez la documentation de votre serveur Tableau pour les versions prises en charge. Utilisez la version 3.26 pour la plupart des instances du Cloud Tableau.",
"Your Tableau site name (leave empty for default site)": "Nom du site Tableau (laisser vide pour le site par défaut)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Votre nom d'utilisateur Tableau (e-mail pour Tableau Cloud, ou domaine\\username pour Server)",
"Your Tableau password": "Votre mot de passe Tableau",
"Name of your Personal Access Token": "Nom de votre jeton d'accès personnel",
"Secret value of your Personal Access Token": "Valeur secrète de votre jeton d'accès personnel",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Configuration d'authentification Tableau\n\n### Pour Tableau Cloud:\n- **URL du serveur** : Utilisez l'URL de votre Tableau Cloud (par exemple, https://10az.online.tableau.com ou https://us-east-1.online.tableau. om)\n- **URL du contenu** : le nom de votre site (laisser vide pour le site par défaut)\n\n### Pour Tableau Server :\n- **URL du serveur** : URL de votre serveur Tableau (e. ., https://tableau.yourcompany. om)\n- **URL du contenu du site** : le nom de votre site (laisser vide pour le site par défaut)\n\n### Méthodes d'authentification :\nChoisissez **soit** Nom d'utilisateur/mot de passe **ou** Jeton d'accès personnel :\n\n#### Option 1 : Nom d'utilisateur et mot de passe\n- Entrez votre nom d'utilisateur Tableau et votre mot de passe\n- Pour Tableau Cloud, utiliser votre adresse e-mail comme nom d'utilisateur\n- Pour le serveur Tableau, Utilisez votre domaine\\nom d'utilisateur si vous utilisez Active Directory\n\n#### Option 2: Jeton d'accès personnel (Recommandé)\n- Allez dans les paramètres de votre compte Tableau\n- Générez un jeton d'accès personnel\n- Entrez le nom du jeton et le secret\n\n**Note de sécurité :** Les jetons d'accès personnels sont recommandés pour une utilisation de production car ils fournissent une meilleure sécurité et peuvent être révoqués individuellement.\n",
"Download View": "Télécharger la vue",
"Run Extract Refresh Task": "Exécuter la tâche de rafraîchissement de l'extraction",
"Refresh Workbook": "Rafraîchir le classeur",
"Find View": "Rechercher une vue",
"Find Workbook": "Trouver le cahier de travail",
"Download a view from a workbook in the specified format": "Télécharger une vue depuis un classeur dans le format spécifié",
"Runs the specified extract refresh task and returns job information": "Exécute la tâche d'actualisation de l'extrait spécifié et retourne les informations de la tâche",
"Refreshes the specified workbook immediately": "Rafraîchit immédiatement le classeur spécifié",
"Finds a view based on name (URL name)": "Trouve une vue basée sur le nom (nom de l'URL)",
"Finds a workbook based on ID or content URL": "Trouve un cahier de travail basé sur l'ID ou l'URL du contenu",
"View": "Afficher",
"Format": "Formater",
"Max Age (minutes)": "Âge maximum (minutes)",
"Image Resolution": "Résolution de l'image",
"Visualization Width": "Largeur de la visualisation",
"Visualization Height": "Hauteur de la visualisation",
"Page Type": "Type de page",
"Orientation": "Orientation",
"Extract Refresh Task": "Extraire la tâche d'actualisation",
"Workbook": "Carnet de travail",
"View Name": "Nom de la vue",
"Search By": "Rechercher par",
"Workbook ID": "ID du cahier de travail",
"Content URL": "URL du contenu",
"Select the view to download": "Sélectionnez la vue à télécharger",
"The format to download the view in": "Le format pour télécharger la vue dans",
"Maximum age of cached data in minutes (default: 60)": "Âge maximum de données mises en cache en minutes (par défaut: 60)",
"Resolution for image format (high for maximum pixel density)": "Résolution pour le format d'image (haute pour la densité maximale de pixels)",
"Width of the rendered image/PDF in pixels": "Largeur du rendu de l'image/PDF en pixels",
"Height of the rendered image/PDF in pixels": "Hauteur du rendu de l'image/PDF en pixels",
"Page size for PDF format": "Taille de la page pour le format PDF",
"Page orientation for PDF format": "Orientation de la page pour le format PDF",
"Select the extract refresh task to run": "Sélectionnez la tâche d'actualisation d'extraction à exécuter",
"Select the workbook to refresh": "Sélectionnez le carnet de travail à actualiser",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "Le nom de l'URL de la vue à trouver (par exemple, la feuille 1 de /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Choisissez si vous souhaitez rechercher par ID du classeur de travail ou par URL de contenu",
"The ID of the workbook to find": "L'ID du classeur à trouver",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "L'URL du contenu du classeur à trouver (par exemple, \"MyWorkbook\" de /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "Image (PNG)",
"PDF": "PDF",
"Excel Crosstab": "Excel Crosstab",
"Letter": "Lettre",
"Legal": "Mentions légales",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Exécutif",
"Folio": "Folio",
"Ledger": "Ledger",
"Note": "Note",
"Quarto": "Quarto",
"Tabloid": "Tabloïde",
"Portrait": "Portrait",
"Landscape": "Paysage",
"Workbook Event": "Événement du cahier de travail",
"Workbook Refresh Event": "Événement d'actualisation du cahier de travail",
"Datasource Event": "Événement de la source de données",
"Datasource Refresh Event": "Rafraîchissement de la source de données",
"User Deleted": "Utilisateur supprimé",
"View Deleted": "Vue supprimée",
"Label Event": "Étiquette d'événement",
"New Job": "Nouveau poste",
"List Extract Refresh Tasks": "Extraire les tâches d'actualisation de la liste",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Déclenche lorsqu'un événement du classeur de travail se produit (créé, mis à jour ou supprimé)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Déclenche lorsqu'un événement d'actualisation du classeur se produit (démarré, réussi ou échoué)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Déclenche lorsqu'un événement de datasource se produit (créé, mis à jour ou supprimé)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Déclenche lorsqu'un événement de rafraichissement de datasource se produit (démarré, réussi ou échoué)",
"Triggers when a user is deleted": "Déclenche lorsqu'un utilisateur est supprimé",
"Triggers when a workbook view is deleted": "Déclenche quand une vue du classeur de travail est supprimée",
"Triggers when a label event occurs (created, updated, or deleted)": "Déclenche lorsqu'un événement d'étiquette se produit (créé, mis à jour ou supprimé)",
"Triggers when a job matches the specified criteria": "Déclenche lorsqu'un job correspond aux critères spécifiés",
"Lists extract refresh tasks for the site": "Liste d'extraire les tâches d'actualisation du site",
"Event Type": "Type d'événement",
"Job Type": "Type de tâche",
"Status": "Statut",
"Select the workbook event to trigger on": "Sélectionnez l'événement du classeur de travail à déclencher",
"Select the workbook refresh event to trigger on": "Sélectionnez l'évènement d'actualisation du classeur de travail à déclencher",
"Select the datasource event to trigger on": "Sélectionnez l'événement source de données à déclencher",
"Select the datasource refresh event to trigger on": "Sélectionnez l'événement de rafraichissement de la source de données à déclencher",
"Select the label event to trigger on": "Sélectionnez le libellé de l'événement sur lequel déclencher",
"Filter by job type (optional)": "Filtrer par type de tâche (facultatif)",
"Filter by job status (optional)": "Filtrer par statut de tâche (facultatif)",
"Created": "Créé",
"Updated": "Mis à jour",
"Deleted": "Supprimé",
"Refresh Started": "Rafraîchissement commencé",
"Refresh Succeeded": "Rafraîchissement réussi",
"Refresh Failed": "Rafraîchissement échoué",
"All Job Types": "Tous les types de Job",
"Refresh Extracts": "Rafraîchir les extraits",
"Increment Extracts": "Incrémenter les extraits",
"Run Flow": "Exécuter Flow",
"Refresh Datasource": "Rafraîchir la source de données",
"All Statuses": "Tous les statuts",
"Success": "Succès",
"Failed": "Échoué",
"InProgress": "En cours de progression",
"Pending": "En attente",
"Cancelled": "Annulé"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "データ可視化のためのビジネスインテリジェンスと分析プラットフォーム",
"Server URL": "サーバー URL",
"API Version": "API バージョン",
"Site Content URL": "サイトコンテンツURL",
"Username": "ユーザー名",
"Password": "Password",
"Personal Access Token Name": "パーソナルアクセストークン名",
"Personal Access Token Secret": "パーソナルアクセストークンシークレット",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Tableau Server または Tableau Cloud の URL (https://10az.online.tableau.comなど)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Tableau REST API バージョン (例: 3.19, 3.20, 3.26) サポートされているバージョンについては、Tableau サーバーのドキュメントを確認してください。ほとんどの Tableau Cloud インスタンスでは 3.26 を使用してください。",
"Your Tableau site name (leave empty for default site)": "Tableau サイト名 (デフォルトのサイトでは空白のまま)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "あなたの Tableau ユーザー名 (Tableau Cloud 用のメール、サーバー用のドメイン\\ユーザー名)",
"Your Tableau password": "Tableau のパスワード",
"Name of your Personal Access Token": "個人アクセストークンの名前",
"Secret value of your Personal Access Token": "パーソナルアクセストークンの秘密の値",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Access Token:\n\n#### Option 1: Username and Password\n- Enter your Tableau username and password\n- For Tableau Cloud, use your email address as username\n- For Tableau Server, use your domain\\username if using Active Directory\n\n#### Option 2: Personal Access Token (Recommended)\n- Go to your Tableau account settings\n- Generate a Personal Access Token\n- Enter the token name and secret\n\n**Security Note:** Personal Access Tokens are recommended for production use as they provide better security and can be revoked individually.\n",
"Download View": "ダウンロードビュー",
"Run Extract Refresh Task": "タスクのリフレッシュを実行",
"Refresh Workbook": "ワークブックを更新",
"Find View": "ビューを検索",
"Find Workbook": "ワークブックを検索",
"Download a view from a workbook in the specified format": "指定された形式のワークブックからビューをダウンロード",
"Runs the specified extract refresh task and returns job information": "指定した抽出リフレッシュタスクを実行し、ジョブ情報を返します。",
"Refreshes the specified workbook immediately": "指定されたワークブックをすぐに更新",
"Finds a view based on name (URL name)": "名前URL名に基づいてビューを検索します",
"Finds a workbook based on ID or content URL": "ID またはコンテンツ URL に基づいてブックを検索します。",
"View": "表示",
"Format": "書式",
"Max Age (minutes)": "最大年齢 (分)",
"Image Resolution": "画像解像度",
"Visualization Width": "視覚化幅",
"Visualization Height": "視覚化の高さ",
"Page Type": "ページタイプ",
"Orientation": "方向",
"Extract Refresh Task": "リフレッシュタスクを抽出",
"Workbook": "ワークブック",
"View Name": "表示名",
"Search By": "検索",
"Workbook ID": "ワークブックID",
"Content URL": "コンテンツ URL",
"Select the view to download": "ダウンロードするビューを選択します",
"The format to download the view in": "ビューをダウンロードするフォーマット",
"Maximum age of cached data in minutes (default: 60)": "キャッシュされたデータの最大年齢 (デフォルト: 60)",
"Resolution for image format (high for maximum pixel density)": "画像フォーマットの解像度(最大画素密度の高さ)",
"Width of the rendered image/PDF in pixels": "レンダリングされた画像/PDFの幅",
"Height of the rendered image/PDF in pixels": "レンダリングされた画像/PDFのピクセル単位の高さ",
"Page size for PDF format": "PDF形式のページサイズ",
"Page orientation for PDF format": "PDF形式のページ方向",
"Select the extract refresh task to run": "実行する抽出更新タスクを選択します",
"Select the workbook to refresh": "更新するワークブックを選択してください",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "検索するビューの URL 名 (例: /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "ワークブックIDまたはコンテンツURLで検索するかどうかを選択",
"The ID of the workbook to find": "見つけるワークブックのID",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "見つけるワークブックのコンテンツ URL (例: /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "画像 (PNG)",
"PDF": "PDF",
"Excel Crosstab": "Excel Crossab",
"Letter": "手紙",
"Legal": "Legal",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "地下5",
"Executive": "Executive",
"Folio": "フォリオ",
"Ledger": "Ledger",
"Note": "メモ",
"Quarto": "Quarto",
"Tabloid": "タブロイド",
"Portrait": "縦向き",
"Landscape": "ランドスケープ",
"Workbook Event": "ワークブックイベント",
"Workbook Refresh Event": "ワークブックの更新イベント",
"Datasource Event": "データ ソース イベント",
"Datasource Refresh Event": "データソースの更新イベント",
"User Deleted": "ユーザーが削除されました",
"View Deleted": "削除されたものを表示",
"Label Event": "ラベルイベント",
"New Job": "新規ジョブ",
"List Extract Refresh Tasks": "リストの更新タスクの抽出",
"Triggers when a workbook event occurs (created, updated, or deleted)": "ワークブックイベントが発生したときにトリガーします (作成、更新、または削除)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "ワークブックの更新イベントが発生したときに発生します (開始、成功、または失敗)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "データソースイベントが発生したとき(作成、更新、または削除)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "データソース更新イベントが発生したときに発生します (開始、成功、失敗)",
"Triggers when a user is deleted": "ユーザーが削除されたときにトリガー",
"Triggers when a workbook view is deleted": "ワークブックビューが削除されたときにトリガーします",
"Triggers when a label event occurs (created, updated, or deleted)": "ラベル イベントが発生したときにトリガーします(作成、更新、または削除)",
"Triggers when a job matches the specified criteria": "ジョブが指定された条件に一致したときにトリガーします",
"Lists extract refresh tasks for the site": "サイトの抽出更新タスクを一覧表示します",
"Event Type": "イベントタイプ",
"Job Type": "ジョブの種類",
"Status": "Status",
"Select the workbook event to trigger on": "トリガーするワークブックイベントを選択してください",
"Select the workbook refresh event to trigger on": "起動するワークブックの更新イベントを選択してください",
"Select the datasource event to trigger on": "トリガーするデータソースイベントを選択してください",
"Select the datasource refresh event to trigger on": "トリガーするデータソースの更新イベントを選択します",
"Select the label event to trigger on": "起動するラベル イベントを選択してください",
"Filter by job type (optional)": "ジョブの種類でフィルター (任意)",
"Filter by job status (optional)": "ジョブステータスでフィルター (オプション)",
"Created": "Created",
"Updated": "更新日時",
"Deleted": "削除しました",
"Refresh Started": "更新を開始しました",
"Refresh Succeeded": "更新に成功しました",
"Refresh Failed": "更新に失敗しました",
"All Job Types": "すべてのジョブタイプ",
"Refresh Extracts": "抽出を更新",
"Increment Extracts": "増分抽出",
"Run Flow": "フローを実行",
"Refresh Datasource": "データソースを更新",
"All Statuses": "すべてのステータス",
"Success": "成功",
"Failed": "失敗しました",
"InProgress": "InProgress",
"Pending": "処理待ち",
"Cancelled": "キャンセルしました"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Zakelijke intelligentie en analytics platform voor gegevensvisualisatie",
"Server URL": "Server URL",
"API Version": "API versie",
"Site Content URL": "Website inhouds-URL",
"Username": "Gebruikersnaam",
"Password": "Wachtwoord",
"Personal Access Token Name": "Naam persoonlijke toegangstoken",
"Personal Access Token Secret": "Persoonlijke toegangstoken geheim",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Uw Tableau Server of Tableau Cloud URL (bijv. https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Tableau REST API versie (bijv. 3.19, 3.20, 3.26). Controleer je Tableau server documentatie voor ondersteunde versies. Gebruik 3.26 voor de meeste Tableau Cloud instanties.",
"Your Tableau site name (leave empty for default site)": "De naam van uw Tableau site (laat leeg voor de standaard website)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Uw Tableau gebruikersnaam (e-mail voor Tableau Cloud, of domeingebruikersnaam voor server)",
"Your Tableau password": "Uw Tableau wachtwoord",
"Name of your Personal Access Token": "Naam van uw persoonlijke toegangstoken",
"Secret value of your Personal Access Token": "Geheime waarde van uw persoonlijke toegangstoken",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Gebruik je Tableau Cloud URL (bijv. https://10az.tableau.com of https://us-east-1.online.tabletableau. om)\n- **Site Content URL**: Uw site naam (laat leeg voor de standaard website)\n\n### Voor Tableau Server:\n- **Server URL**: Uw Tableau Server URL (e. ., https://tableau.yourcompany.\n- **Site Content URL**: Uw site naam (laat leeg voor de standaard site)\n\n### Authenticatie Methoden:\nKies **either** Gebruikersnaam/Wachtwoord **of** Persoonlijke Toegang:\n\n#### Optie 1: Gebruikersnaam en Wachtwoord\n- Voer je Tableau gebruikersnaam en wachtwoord in\n- voor Tableau Cloud, voor Tableau Cloud, gebruik uw e-mailadres als gebruikersnaam\n- voor Tableau Server, uw domeinnaam gebruiken\\gebruikersnaam als u gebruik maakt van Active Directory\n\n#### Optie 2: Persoonlijke toegangstoken (aanbevolen)\n- Ga naar uw Tableau account instellingen\n- Genereer een persoonlijke toegangstoken\n- Voer de token naam en geheim in\n\n**Security Note:** Persoonlijke Toegangstokens worden aanbevolen voor productie gebruik omdat ze meer veiligheid bieden en individueel kunnen worden ingetrokken.\n",
"Download View": "Weergave downloaden",
"Run Extract Refresh Task": "Taak vernieuwen uitvoeren",
"Refresh Workbook": "Werkboek vernieuwen",
"Find View": "Weergave zoeken",
"Find Workbook": "Werkboek vinden",
"Download a view from a workbook in the specified format": "Download een weergave vanuit een werkboek in het opgegeven formaat",
"Runs the specified extract refresh task and returns job information": "Voert de gespecificeerde extract refresh taak en retourneert job informatie",
"Refreshes the specified workbook immediately": "Vernieuwt het opgegeven werkboek onmiddellijk",
"Finds a view based on name (URL name)": "Vondst een weergave gebaseerd op naam (URL-naam)",
"Finds a workbook based on ID or content URL": "Vindt een werkboek gebaseerd op ID of URL van de inhoud",
"View": "Weergave",
"Format": "Formatteren",
"Max Age (minutes)": "Max Leeftijd (minuten)",
"Image Resolution": "Afbeelding resolutie",
"Visualization Width": "Visualisatie breedte",
"Visualization Height": "Visualisatiegraad",
"Page Type": "Pagina type",
"Orientation": "Oriëntatie",
"Extract Refresh Task": "Uitpakken taak vernieuwen",
"Workbook": "Werkboek",
"View Name": "Bekijk Naam",
"Search By": "Zoeken op",
"Workbook ID": "Werkboek ID",
"Content URL": "Content URL",
"Select the view to download": "Selecteer de weergave om te downloaden",
"The format to download the view in": "Het formaat om de weergave te downloaden in",
"Maximum age of cached data in minutes (default: 60)": "Maximale leeftijd van opgeslagen gegevens in minuten (standaard: 60)",
"Resolution for image format (high for maximum pixel density)": "Resolutie voor afbeeldingsformaat (hoog voor maximale pixeldichtheid)",
"Width of the rendered image/PDF in pixels": "Breedte van de weergegeven afbeelding/PDF in pixels",
"Height of the rendered image/PDF in pixels": "Hoogte van de weergegeven afbeelding/PDF in pixels",
"Page size for PDF format": "Pagina grootte voor PDF formaat",
"Page orientation for PDF format": "Pagina oriëntatie voor PDF formaat",
"Select the extract refresh task to run": "Selecteer de extract refresh taak om uit te voeren",
"Select the workbook to refresh": "Selecteer het werkboek om te verversen",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "De URL-naam van de weergave om te vinden (b.v. Sheet1 uit /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Kies of u wilt zoeken op workbook ID of inhouds-URL",
"The ID of the workbook to find": "Het ID van het werkboek om te vinden",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "De URL van de inhoud van het werkboek om te vinden (bijv. \"MyWorkbook\" uit /workbooks/MyWorkbook)",
"CSV": "csv",
"Image (PNG)": "Afbeelding (PNG)",
"PDF": "PDF-bestand",
"Excel Crosstab": "Excel kruis",
"Letter": "Brief",
"Legal": "Juridisch",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Uitvoerend",
"Folio": "Folio",
"Ledger": "Grootboek",
"Note": "Notitie",
"Quarto": "Quarto",
"Tabloid": "Tabloïd",
"Portrait": "Staand",
"Landscape": "Liggend",
"Workbook Event": "Werkboek Evenement",
"Workbook Refresh Event": "Werkboek verversen Event",
"Datasource Event": "Gegevensbron gebeurtenis",
"Datasource Refresh Event": "Gegevensbron vernieuwen gebeurtenis",
"User Deleted": "Gebruiker verwijderd",
"View Deleted": "Weergave verwijderd",
"Label Event": "Label gebeurtenis",
"New Job": "Taak toevoegen",
"List Extract Refresh Tasks": "Lijst uitpakken vernieuwende taken",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Triggert wanneer een werkboek gebeurtenis optreedt (aangemaakt, bijgewerkt of verwijderd)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Triggert wanneer een werkboek verversingsgebeurtenis optreedt (begonnen, geslaagd, of mislukt)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Triggers wanneer een gegevensbron gebeurtenis optreedt (aangemaakt, bijgewerkt of verwijderd)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Triggert wanneer een datasource verversingsgebeurtenis optreedt (gestart, geslaagd, of mislukt)",
"Triggers when a user is deleted": "Triggert wanneer een gebruiker wordt verwijderd",
"Triggers when a workbook view is deleted": "Triggert wanneer een werkboekweergave wordt verwijderd",
"Triggers when a label event occurs (created, updated, or deleted)": "Triggert wanneer een label gebeurtenis optreedt (aangemaakt, bijgewerkt of verwijderd)",
"Triggers when a job matches the specified criteria": "Triggert wanneer een baan overeenkomt met de opgegeven criteria",
"Lists extract refresh tasks for the site": "Lijst van uitpakken van taken voor de site",
"Event Type": "Gebeurtenis type",
"Job Type": "Type Job",
"Status": "status",
"Select the workbook event to trigger on": "Selecteer de werkboekgebeurtenis waarop u wilt starten",
"Select the workbook refresh event to trigger on": "Selecteer de vernieuwde werkboek gebeurtenis om te activeren op",
"Select the datasource event to trigger on": "Selecteer de gegevensbron gebeurtenis om te activeren op",
"Select the datasource refresh event to trigger on": "Selecteer de vernieuwingsgebeurtenis op datasource om op te starten",
"Select the label event to trigger on": "Selecteer de label-gebeurtenis op",
"Filter by job type (optional)": "Filter op jobtype (optioneel)",
"Filter by job status (optional)": "Filter op taakstatus (optioneel)",
"Created": "Aangemaakt",
"Updated": "Gewijzigd",
"Deleted": "Verwijderd",
"Refresh Started": "Vernieuwen gestart",
"Refresh Succeeded": "Vernieuwen Geslaagd",
"Refresh Failed": "Vernieuwen mislukt",
"All Job Types": "Alle vacaturetypes",
"Refresh Extracts": "Uitpakken vernieuwen",
"Increment Extracts": "Erhöhe Extracts",
"Run Flow": "Start Flow",
"Refresh Datasource": "Gegevensbron vernieuwen",
"All Statuses": "Alle statussen",
"Success": "Gelukt",
"Failed": "Mislukt",
"InProgress": "Invoortgang",
"Pending": "In behandeling",
"Cancelled": "Geannuleerd"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Plataforma de análise e inteligência de negócios para visualização de dados",
"Server URL": "URL do servidor",
"API Version": "Versão da API",
"Site Content URL": "URL do conteúdo",
"Username": "Usuário:",
"Password": "Senha",
"Personal Access Token Name": "Nome do Token de Acesso Pessoal",
"Personal Access Token Secret": "Segredo do Token de Acesso Pessoal",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Seu servidor Tableau ou Tableau Cloud URL (por exemplo, https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Versão da API Tableau REST (por exemplo, 3.19, 3.20, 3.26). Verifique a documentação do seu servidor Tableau para versões suportadas. Use 3.26 para a maioria das instâncias Tableau Cloud.",
"Your Tableau site name (leave empty for default site)": "Nome do site Tableau (deixe em branco para site padrão)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Seu nome de usuário Tableau (email para Tableau Cloud, ou domínio\\username para servidor)",
"Your Tableau password": "Sua senha Tableau",
"Name of your Personal Access Token": "Nome do seu Token de Acesso Pessoal",
"Secret value of your Personal Access Token": "Valor secreto de seu Token de Acesso Pessoal",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Configuração de autenticação Tableau\n\n### Para Tableau Cloud:\n- **URL do servidor**: Use seu URL Tableau Cloud (p. ex., https://10az.online.tableau.com ou https://us-east-1.online.tableau. om)\n- **URL do conteúdo do site**: Nome do seu site (deixe em branco para site padrão)\n\n### Para Tableau Server:\n- **URL do servidor**: Sua URL do servidor Tableau (e. ., https://tableau.yourempresa. om)\n- **URL do conteúdo do site**: Nome do seu site (deixe em branco para site padrão)\n\n### Métodos de autenticação:\nEscolha **ou** Nome de usuário/senha **ou** Token de Acesso Pessoal:\n\n#### Opção 1: Nome de usuário e senha\n- Digite seu nome de usuário e senha\n- Para Tableau Cloud, usar seu endereço de e-mail como nome de usuário\n- Para servidor Tableau, Use seu nome-de-domínio\\username usando Active Directory\n\n#### Opção 2: Token de Acesso Pessoal (Recomendado)\n- Vá para suas configurações de conta Tableau\n- Gerar um Token de Acesso Pessoal\n- Insira o nome do token e o nome secreto\n\n**Nota de Segurança:** Tokens de Acesso Pessoal são recomendados para uso da produção, pois fornecem melhor segurança e podem ser revogados individualmente.\n",
"Download View": "Visualização do Download",
"Run Extract Refresh Task": "Executar Extrair Tarefa Atualizar",
"Refresh Workbook": "Atualizar pasta de trabalho",
"Find View": "Buscar Visualização",
"Find Workbook": "Encontrar pasta de atividade",
"Download a view from a workbook in the specified format": "Baixar uma visualização de uma pasta de trabalho no formato especificado",
"Runs the specified extract refresh task and returns job information": "Executa a tarefa de atualização de extração especificada e retorna informações do trabalho",
"Refreshes the specified workbook immediately": "Atualiza a pasta de trabalho especificada imediatamente",
"Finds a view based on name (URL name)": "Localiza uma visualização com base no nome (nome da URL)",
"Finds a workbook based on ID or content URL": "Encontra uma pasta de trabalho com base no ID ou URL de conteúdo",
"View": "Visualizar",
"Format": "Formato",
"Max Age (minutes)": "Idade máxima (minutos)",
"Image Resolution": "Resolução da imagem",
"Visualization Width": "Largura de visualização",
"Visualization Height": "Altura de visualização",
"Page Type": "Tipo de Página",
"Orientation": "Orientação",
"Extract Refresh Task": "Extrair tarefa de atualização",
"Workbook": "Workbook",
"View Name": "Nome da Visualização",
"Search By": "Pesquisar por",
"Workbook ID": "ID da pasta de trabalho",
"Content URL": "URL do conteúdo",
"Select the view to download": "Selecione a visualização para baixar",
"The format to download the view in": "Formato para baixar a visualização em",
"Maximum age of cached data in minutes (default: 60)": "Tempo máximo de dados em cache em minutos (padrão: 60)",
"Resolution for image format (high for maximum pixel density)": "Resolução para o formato de imagem (alta para densidade máxima de pixels)",
"Width of the rendered image/PDF in pixels": "Largura da imagem/PDF renderizada em pixels",
"Height of the rendered image/PDF in pixels": "Altura da imagem/PDF renderizada em pixels",
"Page size for PDF format": "Tamanho da página para formato PDF",
"Page orientation for PDF format": "Orientação da página para formato PDF",
"Select the extract refresh task to run": "Selecione a tarefa de atualização de extração para executar",
"Select the workbook to refresh": "Selecione a pasta de trabalho para atualizar",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "O nome URL da visualização a ser encontrada (por exemplo, Folha1 de /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Escolher se deseja pesquisar pelo ID da pasta de trabalho ou pelo URL do conteúdo",
"The ID of the workbook to find": "O ID da pasta de trabalho para encontrar",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "Conteúdo URL da pasta de trabalho (exemplo: \"MyWorkbook\" de /workbooks/MyWorkbook)",
"CSV": "Csv",
"Image (PNG)": "Imagem (PNG)",
"PDF": "Pdf",
"Excel Crosstab": "Crosstb Excel",
"Letter": "Letra",
"Legal": "Informações",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Executivo",
"Folio": "Folio",
"Ledger": "Contabilidade",
"Note": "Observação",
"Quarto": "Quarto",
"Tabloid": "Tablóide",
"Portrait": "Retrato",
"Landscape": "Paisagem",
"Workbook Event": "Evento do Workbook",
"Workbook Refresh Event": "Evento de atualizar Workbook",
"Datasource Event": "Evento de código-fonte",
"Datasource Refresh Event": "Evento de atualização da fonte de dados",
"User Deleted": "Usuário Excluído",
"View Deleted": "Ver Excluídos",
"Label Event": "Evento Etiqueta",
"New Job": "Novo Trabalho",
"List Extract Refresh Tasks": "Lista Extrair Tarefas de Atualização",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Dispara quando ocorrer um evento do workbook (criado, atualizado ou excluído)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Dispara quando ocorrer um evento de atualização da pasta de trabalho (iniciado, bem-sucedido ou falhou)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Dispara quando ocorrer um evento de código de dados (criado, atualizado ou excluído)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Dispara quando ocorrer um evento de atualização de fonte de dados (iniciado, bem-sucedido ou falhado)",
"Triggers when a user is deleted": "Dispara quando um usuário é excluído",
"Triggers when a workbook view is deleted": "Dispara quando uma visualização de pasta de trabalho é excluída",
"Triggers when a label event occurs (created, updated, or deleted)": "Dispara quando ocorrer um evento de rótulo (criado, atualizado ou excluído)",
"Triggers when a job matches the specified criteria": "Dispara quando um trabalho corresponde aos critérios especificados",
"Lists extract refresh tasks for the site": "Lista de tarefas de atualização de lista do site",
"Event Type": "Tipo de Evento",
"Job Type": "Tipo de trabalho",
"Status": "Estado",
"Select the workbook event to trigger on": "Selecione o evento da pasta de trabalho para disparar",
"Select the workbook refresh event to trigger on": "Selecione o evento de atualização de pasta de trabalho para disparar",
"Select the datasource event to trigger on": "Selecione o evento de código de dados em que ativar",
"Select the datasource refresh event to trigger on": "Selecione o evento de atualização de código de dados em que ativar",
"Select the label event to trigger on": "Selecione o evento label para acionar",
"Filter by job type (optional)": "Filtrar por tipo de trabalho (opcional)",
"Filter by job status (optional)": "Filtrar por status de trabalho (opcional)",
"Created": "Criado",
"Updated": "Atualizado",
"Deleted": "Excluído",
"Refresh Started": "Atualização Iniciada",
"Refresh Succeeded": "Atualização bem-sucedida",
"Refresh Failed": "Atualização falhou",
"All Job Types": "Todas as Tipos de Trabalho",
"Refresh Extracts": "Atualizar extractos",
"Increment Extracts": "Extrações de incremento",
"Run Flow": "Executar Flow",
"Refresh Datasource": "Atualizar fonte de dados",
"All Statuses": "Todos os Status",
"Success": "Bem-sucedido",
"Failed": "Falhou",
"InProgress": "EmProgresso",
"Pending": "Pendente",
"Cancelled": "Cancelado"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Business intelligence and analytics platform for data visualization",
"Server URL": "Server URL",
"API Version": "API Version",
"Site Content URL": "Site Content URL",
"Username": "Username",
"Password": "Password",
"Personal Access Token Name": "Personal Access Token Name",
"Personal Access Token Secret": "Personal Access Token Secret",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.",
"Your Tableau site name (leave empty for default site)": "Your Tableau site name (leave empty for default site)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Your Tableau username (email for Tableau Cloud, or domain\\username for Server)",
"Your Tableau password": "Your Tableau password",
"Name of your Personal Access Token": "Name of your Personal Access Token",
"Secret value of your Personal Access Token": "Secret value of your Personal Access Token",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Access Token:\n\n#### Option 1: Username and Password\n- Enter your Tableau username and password\n- For Tableau Cloud, use your email address as username\n- For Tableau Server, use your domain\\username if using Active Directory\n\n#### Option 2: Personal Access Token (Recommended)\n- Go to your Tableau account settings\n- Generate a Personal Access Token\n- Enter the token name and secret\n\n**Security Note:** Personal Access Tokens are recommended for production use as they provide better security and can be revoked individually.\n",
"Download View": "Download View",
"Run Extract Refresh Task": "Run Extract Refresh Task",
"Refresh Workbook": "Refresh Workbook",
"Find View": "Find View",
"Find Workbook": "Find Workbook",
"Download a view from a workbook in the specified format": "Download a view from a workbook in the specified format",
"Runs the specified extract refresh task and returns job information": "Runs the specified extract refresh task and returns job information",
"Refreshes the specified workbook immediately": "Refreshes the specified workbook immediately",
"Finds a view based on name (URL name)": "Finds a view based on name (URL name)",
"Finds a workbook based on ID or content URL": "Finds a workbook based on ID or content URL",
"View": "View",
"Format": "Format",
"Max Age (minutes)": "Max Age (minutes)",
"Image Resolution": "Image Resolution",
"Visualization Width": "Visualization Width",
"Visualization Height": "Visualization Height",
"Page Type": "Page Type",
"Orientation": "Orientation",
"Extract Refresh Task": "Extract Refresh Task",
"Workbook": "Workbook",
"View Name": "View Name",
"Search By": "Search By",
"Workbook ID": "Workbook ID",
"Content URL": "Content URL",
"Select the view to download": "Select the view to download",
"The format to download the view in": "The format to download the view in",
"Maximum age of cached data in minutes (default: 60)": "Maximum age of cached data in minutes (default: 60)",
"Resolution for image format (high for maximum pixel density)": "Resolution for image format (high for maximum pixel density)",
"Width of the rendered image/PDF in pixels": "Width of the rendered image/PDF in pixels",
"Height of the rendered image/PDF in pixels": "Height of the rendered image/PDF in pixels",
"Page size for PDF format": "Page size for PDF format",
"Page orientation for PDF format": "Page orientation for PDF format",
"Select the extract refresh task to run": "Select the extract refresh task to run",
"Select the workbook to refresh": "Select the workbook to refresh",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Choose whether to search by workbook ID or content URL",
"The ID of the workbook to find": "The ID of the workbook to find",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "Image (PNG)",
"PDF": "PDF",
"Excel Crosstab": "Excel Crosstab",
"Letter": "Letter",
"Legal": "Legal",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Executive",
"Folio": "Folio",
"Ledger": "Ledger",
"Note": "Note",
"Quarto": "Quarto",
"Tabloid": "Tabloid",
"Portrait": "Portrait",
"Landscape": "Landscape",
"Workbook Event": "Workbook Event",
"Workbook Refresh Event": "Workbook Refresh Event",
"Datasource Event": "Datasource Event",
"Datasource Refresh Event": "Datasource Refresh Event",
"User Deleted": "User Deleted",
"View Deleted": "View Deleted",
"Label Event": "Label Event",
"New Job": "New Job",
"List Extract Refresh Tasks": "List Extract Refresh Tasks",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Triggers when a workbook event occurs (created, updated, or deleted)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Triggers when a workbook refresh event occurs (started, succeeded, or failed)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Triggers when a datasource event occurs (created, updated, or deleted)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Triggers when a datasource refresh event occurs (started, succeeded, or failed)",
"Triggers when a user is deleted": "Triggers when a user is deleted",
"Triggers when a workbook view is deleted": "Triggers when a workbook view is deleted",
"Triggers when a label event occurs (created, updated, or deleted)": "Triggers when a label event occurs (created, updated, or deleted)",
"Triggers when a job matches the specified criteria": "Triggers when a job matches the specified criteria",
"Lists extract refresh tasks for the site": "Lists extract refresh tasks for the site",
"Event Type": "Event Type",
"Job Type": "Job Type",
"Status": "Status",
"Select the workbook event to trigger on": "Select the workbook event to trigger on",
"Select the workbook refresh event to trigger on": "Select the workbook refresh event to trigger on",
"Select the datasource event to trigger on": "Select the datasource event to trigger on",
"Select the datasource refresh event to trigger on": "Select the datasource refresh event to trigger on",
"Select the label event to trigger on": "Select the label event to trigger on",
"Filter by job type (optional)": "Filter by job type (optional)",
"Filter by job status (optional)": "Filter by job status (optional)",
"Created": "Created",
"Updated": "Updated",
"Deleted": "Deleted",
"Refresh Started": "Refresh Started",
"Refresh Succeeded": "Refresh Succeeded",
"Refresh Failed": "Refresh Failed",
"All Job Types": "All Job Types",
"Refresh Extracts": "Refresh Extracts",
"Increment Extracts": "Increment Extracts",
"Run Flow": "Run Flow",
"Refresh Datasource": "Refresh Datasource",
"All Statuses": "All Statuses",
"Success": "Success",
"Failed": "Failed",
"InProgress": "InProgress",
"Pending": "Pending",
"Cancelled": "Cancelled"
}

View File

@@ -0,0 +1,119 @@
{
"Business intelligence and analytics platform for data visualization": "Business intelligence and analytics platform for data visualization",
"Server URL": "服务器 URL",
"API Version": "API Version",
"Site Content URL": "Site Content URL",
"Username": "用户名",
"Password": "Password",
"Personal Access Token Name": "Personal Access Token Name",
"Personal Access Token Secret": "Personal Access Token Secret",
"Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)": "Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)",
"Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.": "Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.",
"Your Tableau site name (leave empty for default site)": "Your Tableau site name (leave empty for default site)",
"Your Tableau username (email for Tableau Cloud, or domain\\username for Server)": "Your Tableau username (email for Tableau Cloud, or domain\\username for Server)",
"Your Tableau password": "Your Tableau password",
"Name of your Personal Access Token": "Name of your Personal Access Token",
"Secret value of your Personal Access Token": "Secret value of your Personal Access Token",
"\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Ac": "\n## Tableau Authentication Setup\n\n### For Tableau Cloud:\n- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### For Tableau Server:\n- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)\n- **Site Content URL**: Your site name (leave empty for default site)\n\n### Authentication Methods:\nChoose **either** Username/Password **or** Personal Access Token:\n\n#### Option 1: Username and Password\n- Enter your Tableau username and password\n- For Tableau Cloud, use your email address as username\n- For Tableau Server, use your domain\\username if using Active Directory\n\n#### Option 2: Personal Access Token (Recommended)\n- Go to your Tableau account settings\n- Generate a Personal Access Token\n- Enter the token name and secret\n\n**Security Note:** Personal Access Tokens are recommended for production use as they provide better security and can be revoked individually.\n",
"Download View": "Download View",
"Run Extract Refresh Task": "Run Extract Refresh Task",
"Refresh Workbook": "Refresh Workbook",
"Find View": "Find View",
"Find Workbook": "Find Workbook",
"Download a view from a workbook in the specified format": "Download a view from a workbook in the specified format",
"Runs the specified extract refresh task and returns job information": "Runs the specified extract refresh task and returns job information",
"Refreshes the specified workbook immediately": "Refreshes the specified workbook immediately",
"Finds a view based on name (URL name)": "Finds a view based on name (URL name)",
"Finds a workbook based on ID or content URL": "Finds a workbook based on ID or content URL",
"View": "查看",
"Format": "Format",
"Max Age (minutes)": "Max Age (minutes)",
"Image Resolution": "Image Resolution",
"Visualization Width": "Visualization Width",
"Visualization Height": "Visualization Height",
"Page Type": "Page Type",
"Orientation": "Orientation",
"Extract Refresh Task": "Extract Refresh Task",
"Workbook": "Workbook",
"View Name": "View Name",
"Search By": "Search By",
"Workbook ID": "Workbook ID",
"Content URL": "Content URL",
"Select the view to download": "Select the view to download",
"The format to download the view in": "The format to download the view in",
"Maximum age of cached data in minutes (default: 60)": "Maximum age of cached data in minutes (default: 60)",
"Resolution for image format (high for maximum pixel density)": "Resolution for image format (high for maximum pixel density)",
"Width of the rendered image/PDF in pixels": "Width of the rendered image/PDF in pixels",
"Height of the rendered image/PDF in pixels": "Height of the rendered image/PDF in pixels",
"Page size for PDF format": "Page size for PDF format",
"Page orientation for PDF format": "Page orientation for PDF format",
"Select the extract refresh task to run": "Select the extract refresh task to run",
"Select the workbook to refresh": "Select the workbook to refresh",
"The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)": "The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)",
"Choose whether to search by workbook ID or content URL": "Choose whether to search by workbook ID or content URL",
"The ID of the workbook to find": "The ID of the workbook to find",
"The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)": "The content URL of the workbook to find (e.g., \"MyWorkbook\" from /workbooks/MyWorkbook)",
"CSV": "CSV",
"Image (PNG)": "Image (PNG)",
"PDF": "PDF",
"Excel Crosstab": "Excel Crosstab",
"Letter": "Letter",
"Legal": "Legal",
"A4": "A4",
"A3": "A3",
"A5": "A5",
"B5": "B5",
"Executive": "Executive",
"Folio": "Folio",
"Ledger": "Ledger",
"Note": "说明",
"Quarto": "Quarto",
"Tabloid": "Tabloid",
"Portrait": "Portrait",
"Landscape": "Landscape",
"Workbook Event": "Workbook Event",
"Workbook Refresh Event": "Workbook Refresh Event",
"Datasource Event": "Datasource Event",
"Datasource Refresh Event": "Datasource Refresh Event",
"User Deleted": "User Deleted",
"View Deleted": "View Deleted",
"Label Event": "Label Event",
"New Job": "New Job",
"List Extract Refresh Tasks": "List Extract Refresh Tasks",
"Triggers when a workbook event occurs (created, updated, or deleted)": "Triggers when a workbook event occurs (created, updated, or deleted)",
"Triggers when a workbook refresh event occurs (started, succeeded, or failed)": "Triggers when a workbook refresh event occurs (started, succeeded, or failed)",
"Triggers when a datasource event occurs (created, updated, or deleted)": "Triggers when a datasource event occurs (created, updated, or deleted)",
"Triggers when a datasource refresh event occurs (started, succeeded, or failed)": "Triggers when a datasource refresh event occurs (started, succeeded, or failed)",
"Triggers when a user is deleted": "Triggers when a user is deleted",
"Triggers when a workbook view is deleted": "Triggers when a workbook view is deleted",
"Triggers when a label event occurs (created, updated, or deleted)": "Triggers when a label event occurs (created, updated, or deleted)",
"Triggers when a job matches the specified criteria": "Triggers when a job matches the specified criteria",
"Lists extract refresh tasks for the site": "Lists extract refresh tasks for the site",
"Event Type": "Event Type",
"Job Type": "Job Type",
"Status": "状态",
"Select the workbook event to trigger on": "Select the workbook event to trigger on",
"Select the workbook refresh event to trigger on": "Select the workbook refresh event to trigger on",
"Select the datasource event to trigger on": "Select the datasource event to trigger on",
"Select the datasource refresh event to trigger on": "Select the datasource refresh event to trigger on",
"Select the label event to trigger on": "Select the label event to trigger on",
"Filter by job type (optional)": "Filter by job type (optional)",
"Filter by job status (optional)": "Filter by job status (optional)",
"Created": "Created",
"Updated": "Updated",
"Deleted": "Deleted",
"Refresh Started": "Refresh Started",
"Refresh Succeeded": "Refresh Succeeded",
"Refresh Failed": "Refresh Failed",
"All Job Types": "All Job Types",
"Refresh Extracts": "Refresh Extracts",
"Increment Extracts": "Increment Extracts",
"Run Flow": "Run Flow",
"Refresh Datasource": "Refresh Datasource",
"All Statuses": "All Statuses",
"Success": "成功",
"Failed": "失败",
"InProgress": "InProgress",
"Pending": "待處理",
"Cancelled": "Cancelled"
}

View File

@@ -0,0 +1,133 @@
import { createPiece, PieceAuth, Property } from "@activepieces/pieces-framework";
import { PieceCategory } from '@activepieces/shared';
import { downloadView } from './lib/actions/download-view';
import { runExtractRefreshTask } from './lib/actions/run-extract-refresh-task';
import { refreshWorkbook } from './lib/actions/refresh-workbook';
import { findView } from './lib/actions/find-view';
import { findWorkbook } from './lib/actions/find-workbook';
import { workbookEventTrigger } from './lib/triggers/workbook-events';
import { workbookRefreshEventTrigger } from './lib/triggers/workbook-refresh-events';
import { datasourceEventTrigger } from './lib/triggers/datasource-events';
import { datasourceRefreshEventTrigger } from './lib/triggers/datasource-refresh-events';
import { userDeletedTrigger } from './lib/triggers/user-deleted';
import { viewDeletedTrigger } from './lib/triggers/view-deleted';
import { labelEventTrigger } from './lib/triggers/label-events';
import { newJobTrigger } from './lib/triggers/new-job';
import { listExtractRefreshTasksTrigger } from './lib/triggers/list-extract-refresh-tasks';
const markdown = `
## Tableau Authentication Setup
### For Tableau Cloud:
- **Server URL**: Use your Tableau Cloud URL (e.g., https://10az.online.tableau.com or https://us-east-1.online.tableau.com)
- **Site Content URL**: Your site name (leave empty for default site)
### For Tableau Server:
- **Server URL**: Your Tableau Server URL (e.g., https://tableau.yourcompany.com)
- **Site Content URL**: Your site name (leave empty for default site)
### Authentication Methods:
Choose **either** Username/Password **or** Personal Access Token:
#### Option 1: Username and Password
- Enter your Tableau username and password
- For Tableau Cloud, use your email address as username
- For Tableau Server, use your domain\\username if using Active Directory
#### Option 2: Personal Access Token (Recommended)
- Go to your Tableau account settings
- Generate a Personal Access Token
- Enter the token name and secret
**Security Note:** Personal Access Tokens are recommended for production use as they provide better security and can be revoked individually.
`;
export const tableauAuth = PieceAuth.CustomAuth({
description: markdown,
required: true,
props: {
serverUrl: Property.ShortText({
displayName: 'Server URL',
description: 'Your Tableau Server or Tableau Cloud URL (e.g., https://10az.online.tableau.com)',
required: true,
}),
apiVersion: Property.ShortText({
displayName: 'API Version',
description: 'Tableau REST API version (e.g., 3.19, 3.20, 3.26). Check your Tableau server documentation for supported versions. Use 3.26 for most Tableau Cloud instances.',
required: true,
defaultValue: '3.26',
}),
siteContentUrl: Property.ShortText({
displayName: 'Site Content URL',
description: 'Your Tableau site name (leave empty for default site)',
required: false,
}),
// Username/Password authentication
username: Property.ShortText({
displayName: 'Username',
description: 'Your Tableau username (email for Tableau Cloud, or domain\\username for Server)',
required: false,
}),
password: PieceAuth.SecretText({
displayName: 'Password',
description: 'Your Tableau password',
required: false,
}),
// PAT authentication
personalAccessTokenName: Property.ShortText({
displayName: 'Personal Access Token Name',
description: 'Name of your Personal Access Token',
required: false,
}),
personalAccessTokenSecret: PieceAuth.SecretText({
displayName: 'Personal Access Token Secret',
description: 'Secret value of your Personal Access Token',
required: false,
}),
},
validate: async ({ auth }) => {
const hasUsernamePassword = auth.username && auth.password;
const hasPersonalAccessToken = auth.personalAccessTokenName && auth.personalAccessTokenSecret;
if (!hasUsernamePassword && !hasPersonalAccessToken) {
return {
valid: false,
error: 'Either Username/Password or Personal Access Token must be provided.',
};
}
if (hasUsernamePassword && hasPersonalAccessToken) {
return {
valid: false,
error: 'Please provide either Username/Password OR Personal Access Token, not both.',
};
}
return {
valid: true,
};
},
});
export const tableau = createPiece({
displayName: "Tableau",
description: "Business intelligence and analytics platform for data visualization",
auth: tableauAuth,
minimumSupportedRelease: '0.36.1',
logoUrl: "https://cdn.activepieces.com/pieces/tableau.png",
categories: [PieceCategory.BUSINESS_INTELLIGENCE],
authors: ["onyedikachi-david"],
actions: [downloadView, runExtractRefreshTask, refreshWorkbook, findView, findWorkbook],
triggers: [
workbookEventTrigger,
workbookRefreshEventTrigger,
datasourceEventTrigger,
datasourceRefreshEventTrigger,
userDeletedTrigger,
viewDeletedTrigger,
labelEventTrigger,
newJobTrigger,
listExtractRefreshTasksTrigger,
],
});

View File

@@ -0,0 +1,221 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders, queryViews } from '../common';
export const downloadView = createAction({
name: 'download_view',
displayName: 'Download View',
description: 'Download a view from a workbook in the specified format',
auth: tableauAuth,
props: {
viewId: Property.Dropdown({
auth: tableauAuth,
displayName: 'View',
description: 'Select the view to download',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your Tableau account first',
};
}
try {
const views = await queryViews(auth);
return {
disabled: false,
options: views.map((view) => ({
label: view.name,
value: view.id,
})),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Failed to load views. Please check your authentication.',
};
}
},
}),
format: Property.StaticDropdown({
displayName: 'Format',
description: 'The format to download the view in',
required: true,
options: {
options: [
{ label: 'CSV', value: 'csv' },
{ label: 'Image (PNG)', value: 'image' },
{ label: 'PDF', value: 'pdf' },
{ label: 'Excel Crosstab', value: 'excel' },
],
},
}),
maxAge: Property.Number({
displayName: 'Max Age (minutes)',
description: 'Maximum age of cached data in minutes (default: 60)',
required: false,
defaultValue: 60,
}),
resolution: Property.ShortText({
displayName: 'Image Resolution',
description: 'Resolution for image format (high for maximum pixel density)',
required: false,
}),
vizWidth: Property.Number({
displayName: 'Visualization Width',
description: 'Width of the rendered image/PDF in pixels',
required: false,
}),
vizHeight: Property.Number({
displayName: 'Visualization Height',
description: 'Height of the rendered image/PDF in pixels',
required: false,
}),
pageType: Property.StaticDropdown({
displayName: 'Page Type',
description: 'Page size for PDF format',
required: false,
options: {
options: [
{ label: 'Letter', value: 'Letter' },
{ label: 'Legal', value: 'Legal' },
{ label: 'A4', value: 'A4' },
{ label: 'A3', value: 'A3' },
{ label: 'A5', value: 'A5' },
{ label: 'B5', value: 'B5' },
{ label: 'Executive', value: 'Executive' },
{ label: 'Folio', value: 'Folio' },
{ label: 'Ledger', value: 'Ledger' },
{ label: 'Note', value: 'Note' },
{ label: 'Quarto', value: 'Quarto' },
{ label: 'Tabloid', value: 'Tabloid' },
],
},
}),
orientation: Property.StaticDropdown({
displayName: 'Orientation',
description: 'Page orientation for PDF format',
required: false,
options: {
options: [
{ label: 'Portrait', value: 'Portrait' },
{ label: 'Landscape', value: 'Landscape' },
],
},
}),
},
async run({ auth, propsValue, files }) {
const { viewId, format, maxAge = 60, resolution, vizWidth, vizHeight, pageType, orientation } = propsValue;
const tableauAuth = auth as any;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
let downloadUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `views/${viewId}`);
const queryParams = new URLSearchParams();
if (maxAge && maxAge > 0) {
queryParams.append('maxAge', maxAge.toString());
}
switch (format) {
case 'csv':
downloadUrl += '/data';
break;
case 'image':
downloadUrl += '/image';
if (resolution) {
queryParams.append('resolution', resolution);
}
if (vizWidth && vizHeight) {
queryParams.append('vizWidth', vizWidth.toString());
queryParams.append('vizHeight', vizHeight.toString());
}
break;
case 'pdf':
downloadUrl += '/pdf';
if (vizWidth && vizHeight) {
queryParams.append('vizWidth', vizWidth.toString());
queryParams.append('vizHeight', vizHeight.toString());
}
if (pageType) {
queryParams.append('type', pageType);
}
if (orientation) {
queryParams.append('orientation', orientation);
}
break;
case 'excel':
downloadUrl += '/crosstab/excel';
break;
default:
throw new Error(`Unsupported format: ${format}`);
}
const queryString = queryParams.toString();
if (queryString) {
downloadUrl += `?${queryString}`;
}
const downloadResponse = await httpClient.sendRequest({
method: HttpMethod.GET,
url: downloadUrl,
headers: {
'X-Tableau-Auth': authToken,
},
});
if (downloadResponse.status !== 200) {
throw new Error(`Download failed: ${downloadResponse.status} - ${downloadResponse.body}`);
}
let fileExtension: string;
switch (format) {
case 'csv':
fileExtension = 'csv';
break;
case 'image':
fileExtension = 'png';
break;
case 'pdf':
fileExtension = 'pdf';
break;
case 'excel':
fileExtension = 'xlsx';
break;
default:
fileExtension = 'bin';
}
const fileName = `tableau_view_${viewId}.${fileExtension}`;
let fileData: Buffer;
if (Buffer.isBuffer(downloadResponse.body)) {
fileData = downloadResponse.body;
} else if (typeof downloadResponse.body === 'string') {
fileData = Buffer.from(downloadResponse.body);
} else {
fileData = Buffer.from(JSON.stringify(downloadResponse.body));
}
const fileUrl = await files.write({
fileName: fileName,
data: fileData,
});
return {
success: true,
fileName: fileName,
fileUrl: fileUrl,
format: format,
size: fileData.length,
};
},
});

View File

@@ -0,0 +1,94 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders } from '../common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
export const findView = createAction({
name: 'find_view',
displayName: 'Find View',
description: 'Finds a view based on name (URL name)',
auth: tableauAuth,
props: {
viewName: Property.ShortText({
displayName: 'View Name',
description: 'The URL name of the view to find (e.g., Sheet1 from /views/workbook/Sheet1)',
required: true,
}),
},
async run({ auth, propsValue }) {
const { viewName } = propsValue;
const tableauAuth = auth as any;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
const findViewUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `views?filter=viewUrlName:eq:${encodeURIComponent(viewName)}`);
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: findViewUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to find view: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const viewIdMatch = responseBody.match(/<view[^>]*id="([^"]+)"/);
const viewId = viewIdMatch ? viewIdMatch[1] : null;
const nameMatch = responseBody.match(/name="([^"]+)"/);
const name = nameMatch ? nameMatch[1] : null;
const contentUrlMatch = responseBody.match(/contentUrl="([^"]+)"/);
const contentUrl = contentUrlMatch ? contentUrlMatch[1] : null;
const createdAtMatch = responseBody.match(/createdAt="([^"]+)"/);
const createdAt = createdAtMatch ? createdAtMatch[1] : null;
const updatedAtMatch = responseBody.match(/updatedAt="([^"]+)"/);
const updatedAt = updatedAtMatch ? updatedAtMatch[1] : null;
const viewUrlNameMatch = responseBody.match(/viewUrlName="([^"]+)"/);
const viewUrlName = viewUrlNameMatch ? viewUrlNameMatch[1] : null;
const workbookIdMatch = responseBody.match(/<workbook[^>]*id="([^"]+)"/);
const workbookId = workbookIdMatch ? workbookIdMatch[1] : null;
const ownerIdMatch = responseBody.match(/<owner[^>]*id="([^"]+)"/);
const ownerId = ownerIdMatch ? ownerIdMatch[1] : null;
const projectIdMatch = responseBody.match(/<project[^>]*id="([^"]+)"/);
const projectId = projectIdMatch ? projectIdMatch[1] : null;
if (!viewId) {
throw new Error(`View with name "${viewName}" not found`);
}
return {
success: true,
view: {
id: viewId,
name,
contentUrl,
createdAt,
updatedAt,
viewUrlName,
workbook: workbookId ? { id: workbookId } : null,
owner: ownerId ? { id: ownerId } : null,
project: projectId ? { id: projectId } : null,
tags: [],
},
message: `View "${viewName}" found successfully`,
};
},
});

View File

@@ -0,0 +1,159 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders } from '../common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
export const findWorkbook = createAction({
name: 'find_workbook',
displayName: 'Find Workbook',
description: 'Finds a workbook based on ID or content URL',
auth: tableauAuth,
props: {
searchType: Property.StaticDropdown({
displayName: 'Search By',
description: 'Choose whether to search by workbook ID or content URL',
required: true,
options: {
options: [
{ label: 'Workbook ID', value: 'id' },
{ label: 'Content URL', value: 'contentUrl' },
],
},
}),
workbookId: Property.ShortText({
displayName: 'Workbook ID',
description: 'The ID of the workbook to find',
required: false,
}),
contentUrl: Property.ShortText({
displayName: 'Content URL',
description: 'The content URL of the workbook to find (e.g., "MyWorkbook" from /workbooks/MyWorkbook)',
required: false,
}),
},
async run({ auth, propsValue }) {
const { searchType, workbookId, contentUrl } = propsValue;
const tableauAuth = auth as any;
if (searchType === 'id' && !workbookId) {
throw new Error('Workbook ID is required when searching by ID');
}
if (searchType === 'contentUrl' && !contentUrl) {
throw new Error('Content URL is required when searching by content URL');
}
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
let findWorkbookUrl: string;
if (searchType === 'id') {
findWorkbookUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `workbooks/${workbookId}`);
} else {
findWorkbookUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `workbooks/${encodeURIComponent(contentUrl!)}?key=contentUrl`);
}
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: findWorkbookUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to find workbook: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const workbookIdMatch = responseBody.match(/<workbook[^>]*id="([^"]+)"/);
const foundWorkbookId = workbookIdMatch ? workbookIdMatch[1] : null;
const nameMatch = responseBody.match(/name="([^"]+)"/);
const name = nameMatch ? nameMatch[1] : null;
const descriptionMatch = responseBody.match(/description="([^"]*)"/);
const description = descriptionMatch ? descriptionMatch[1] : '';
const workbookContentUrlMatch = responseBody.match(/contentUrl="([^"]+)"/);
const workbookContentUrl = workbookContentUrlMatch ? workbookContentUrlMatch[1] : null;
const webpageUrlMatch = responseBody.match(/webpageUrl="([^"]+)"/);
const webpageUrl = webpageUrlMatch ? webpageUrlMatch[1] : null;
const showTabsMatch = responseBody.match(/showTabs="([^"]+)"/);
const showTabs = showTabsMatch ? showTabsMatch[1] : null;
const sizeMatch = responseBody.match(/size="([^"]+)"/);
const size = sizeMatch ? sizeMatch[1] : null;
const createdAtMatch = responseBody.match(/createdAt="([^"]+)"/);
const createdAt = createdAtMatch ? createdAtMatch[1] : null;
const updatedAtMatch = responseBody.match(/updatedAt="([^"]+)"/);
const updatedAt = updatedAtMatch ? updatedAtMatch[1] : null;
const encryptExtractsMatch = responseBody.match(/encryptExtracts="([^"]+)"/);
const encryptExtracts = encryptExtractsMatch ? encryptExtractsMatch[1] : null;
const defaultViewIdMatch = responseBody.match(/defaultViewId="([^"]+)"/);
const defaultViewId = defaultViewIdMatch ? defaultViewIdMatch[1] : null;
const projectIdMatch = responseBody.match(/<project[^>]*id="([^"]+)"/);
const projectId = projectIdMatch ? projectIdMatch[1] : null;
const projectNameMatch = responseBody.match(/<project[^>]*>[\s\S]*?<name[^>]*>([^<]+)<\/name>/);
const projectName = projectNameMatch ? projectNameMatch[1] : null;
const ownerIdMatch = responseBody.match(/<owner[^>]*id="([^"]+)"/);
const ownerId = ownerIdMatch ? ownerIdMatch[1] : null;
const ownerNameMatch = responseBody.match(/<owner[^>]*>[\s\S]*?<name[^>]*>([^<]+)<\/name>/);
const ownerName = ownerNameMatch ? ownerNameMatch[1] : null;
const views: any[] = [];
const viewMatches = responseBody.matchAll(/<view[^>]*id="([^"]+)"[^>]*name="([^"]+)"[^>]*contentUrl="([^"]+)"/g);
for (const match of viewMatches) {
const [, viewId, viewName, viewContentUrl] = match;
views.push({
id: viewId,
name: viewName,
contentUrl: viewContentUrl,
});
}
if (!foundWorkbookId) {
const searchValue = searchType === 'id' ? workbookId : contentUrl;
throw new Error(`Workbook with ${searchType} "${searchValue}" not found`);
}
return {
success: true,
workbook: {
id: foundWorkbookId,
name,
description,
contentUrl: workbookContentUrl,
webpageUrl,
showTabs: showTabs === 'true',
size: size ? parseInt(size) : null,
createdAt,
updatedAt,
encryptExtracts: encryptExtracts === 'true',
defaultViewId,
project: projectId ? { id: projectId, name: projectName } : null,
owner: ownerId ? { id: ownerId, name: ownerName } : null,
views,
tags: [],
},
searchType,
searchValue: searchType === 'id' ? workbookId : contentUrl,
message: `Workbook found successfully`,
};
},
});

View File

@@ -0,0 +1,110 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders, queryWorkbooks } from '../common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
export const refreshWorkbook = createAction({
name: 'refresh_workbook',
displayName: 'Refresh Workbook',
description: 'Refreshes the specified workbook immediately',
auth: tableauAuth,
props: {
workbookId: Property.Dropdown({
auth: tableauAuth, displayName: 'Workbook',
description: 'Select the workbook to refresh',
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
}
try {
const workbooks = await queryWorkbooks(auth as any);
const options = workbooks.map((workbook: any) => ({
label: workbook.name || `Workbook ${workbook.id}`,
value: workbook.id,
}));
return {
disabled: false,
options,
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Failed to load workbooks. Please check your authentication.',
};
}
},
}),
},
async run({ auth, propsValue }) {
const { workbookId } = propsValue;
const tableauAuth = auth as any;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
const refreshUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `workbooks/${workbookId}/refresh`);
const requestBody = '<?xml version="1.0" encoding="UTF-8"?><tsRequest></tsRequest>';
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: refreshUrl,
headers: {
...getTableauHeaders(authToken),
'Content-Type': 'application/xml',
},
body: requestBody,
});
if (response.status !== 202) {
throw new Error(`Failed to refresh workbook: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const jobIdMatch = responseBody.match(/<job[^>]*id="([^"]+)"/);
const jobId = jobIdMatch ? jobIdMatch[1] : null;
const modeMatch = responseBody.match(/mode="([^"]+)"/);
const mode = modeMatch ? modeMatch[1] : null;
const typeMatch = responseBody.match(/type="([^"]+)"/);
const type = typeMatch ? typeMatch[1] : null;
const createdAtMatch = responseBody.match(/createdAt="([^"]+)"/);
const createdAt = createdAtMatch ? createdAtMatch[1] : null;
const workbookNameMatch = responseBody.match(/<workbook[^>]*name="([^"]+)"/);
const workbookName = workbookNameMatch ? workbookNameMatch[1] : null;
return {
success: true,
workbookId,
workbookName,
job: {
id: jobId,
mode,
type,
createdAt,
},
message: 'Workbook refresh has been queued successfully',
};
},
});

View File

@@ -0,0 +1,113 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders, listExtractRefreshTasks } from '../common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
export const runExtractRefreshTask = createAction({
name: 'run_extract_refresh_task',
displayName: 'Run Extract Refresh Task',
description: 'Runs the specified extract refresh task and returns job information',
auth: tableauAuth,
props: {
taskId: Property.Dropdown({
auth: tableauAuth, displayName: 'Extract Refresh Task',
description: 'Select the extract refresh task to run',
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first',
};
}
try {
const tasks = await listExtractRefreshTasks(auth as any);
const options = tasks.map((task: any) => {
let label = `Task ${task.id}`;
if (task.workbookId) {
label += ` (Workbook: ${task.workbookId})`;
} else if (task.datasourceId) {
label += ` (Datasource: ${task.datasourceId})`;
}
if (task.schedule?.frequency) {
label += ` - ${task.schedule.frequency}`;
}
return {
label,
value: task.id,
};
});
return {
disabled: false,
options,
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Failed to load tasks. Please check your authentication.',
};
}
},
}),
},
async run({ auth, propsValue }) {
const { taskId } = propsValue;
const tableauAuth = auth as any;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
const runTaskUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, `tasks/extractRefreshes/${taskId}/runNow`);
const requestBody = '<?xml version="1.0" encoding="UTF-8"?><tsRequest></tsRequest>';
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: runTaskUrl,
headers: {
...getTableauHeaders(authToken),
'Content-Type': 'application/xml',
},
body: requestBody,
});
if (response.status !== 200 && response.status !== 202) {
throw new Error(`Failed to run extract refresh task: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const jobIdMatch = responseBody.match(/<job[^>]*id="([^"]+)"/);
const jobId = jobIdMatch ? jobIdMatch[1] : null;
const modeMatch = responseBody.match(/mode="([^"]+)"/);
const mode = modeMatch ? modeMatch[1] : null;
const typeMatch = responseBody.match(/type="([^"]+)"/);
const type = typeMatch ? typeMatch[1] : null;
return {
success: true,
taskId,
job: {
id: jobId,
mode,
type,
},
message: 'Extract refresh task has been queued successfully',
};
},
});

View File

@@ -0,0 +1,380 @@
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
function ensureString(body: any): string {
if (typeof body === 'string') {
return body;
}
if (typeof body === 'object') {
return JSON.stringify(body);
}
return String(body);
}
export function getTableauHeaders(authToken: string) {
return {
'X-Tableau-Auth': authToken,
'Accept': 'application/xml',
'Content-Type': 'application/xml',
};
}
export function buildTableauUrl(serverUrl: string, apiVersion: string, siteId: string, endpoint: string): string {
return `${serverUrl}/api/${apiVersion}/sites/${siteId}/${endpoint}`;
}
interface AuthCache {
token: string;
siteId: string;
expiresAt: number;
}
const authCache = new Map<string, AuthCache>();
function getCacheKey(auth: any): string {
return `${auth.serverUrl}-${auth.siteContentUrl || 'default'}-${auth.username || auth.personalAccessTokenName}`;
}
export async function getAuthToken(auth: any): Promise<{ token: string; siteId: string }> {
const cacheKey = getCacheKey(auth);
const now = Date.now();
const cached = authCache.get(cacheKey);
if (cached && cached.expiresAt > now + 300000) {
return { token: cached.token, siteId: cached.siteId };
}
let credentialsXml: string;
if (auth.username && auth.password) {
credentialsXml = `<credentials name="${auth.username}" password="${auth.password}">`;
} else if (auth.personalAccessTokenName && auth.personalAccessTokenSecret) {
credentialsXml = `<credentials personalAccessTokenName="${auth.personalAccessTokenName}" personalAccessTokenSecret="${auth.personalAccessTokenSecret}">`;
} else {
throw new Error('Authentication credentials are missing');
}
const siteXml = auth.siteContentUrl ? `<site contentUrl="${auth.siteContentUrl}" />` : '<site />';
const signinXml = `<?xml version="1.0" encoding="UTF-8"?>
<tsRequest>
${credentialsXml}
${siteXml}
</credentials>
</tsRequest>`;
const apiVersion = auth.apiVersion || '3.26';
const signinResponse = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${auth.serverUrl}/api/${apiVersion}/auth/signin`,
headers: {
'Content-Type': 'application/xml',
'Accept': 'application/xml',
},
body: signinXml,
});
if (signinResponse.status !== 200) {
throw new Error(`Authentication failed: ${signinResponse.status} - ${JSON.stringify(signinResponse.body)}`);
}
let authToken: string | null = null;
let siteId: string | null = null;
if (typeof signinResponse.body === 'object' && signinResponse.body !== null) {
const body = signinResponse.body as any;
if (body.tsResponse?.credentials) {
authToken = body.tsResponse.credentials.token || body.tsResponse.credentials['@token'];
siteId = body.tsResponse.credentials.site?.id || body.tsResponse.credentials.site?.['@id'];
} else if (body.credentials) {
authToken = body.credentials.token || body.credentials['@token'];
siteId = body.credentials.site?.id || body.credentials.site?.['@id'];
}
if (!authToken || !siteId) {
const responseXml = JSON.stringify(signinResponse.body);
const tokenMatch = responseXml.match(/token["']?\s*:\s*["']?([^"',}\s]+)/);
const siteIdMatch = responseXml.match(/id["']?\s*:\s*["']?([^"',}\s]+)/);
authToken = tokenMatch ? tokenMatch[1] : null;
siteId = siteIdMatch ? siteIdMatch[1] : null;
}
} else {
const responseXml = ensureString(signinResponse.body);
const tokenMatch = responseXml.match(/token="([^"]+)"/);
authToken = tokenMatch ? tokenMatch[1] : null;
const siteIdMatch = responseXml.match(/<site[^>]*id="([^"]+)"/);
siteId = siteIdMatch ? siteIdMatch[1] : null;
}
if (!authToken || !siteId) {
throw new Error(`Failed to obtain authentication token or site ID from response. Response type: ${typeof signinResponse.body}. Response: ${JSON.stringify(signinResponse.body).substring(0, 500)}`);
}
const isCloud = auth.serverUrl.includes('.online.tableau.com');
const tokenLifetime = isCloud ? 120 * 60 * 1000 : 240 * 60 * 1000;
authCache.set(cacheKey, {
token: authToken,
siteId,
expiresAt: now + tokenLifetime,
});
return { token: authToken, siteId };
}
export async function listExtractRefreshTasks(auth: any): Promise<any[]> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const listTasksUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, 'tasks/extractRefreshes');
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: listTasksUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to list extract refresh tasks: ${response.status}`);
}
const responseBody = ensureString(response.body);
const tasks: any[] = [];
const taskMatches = responseBody.matchAll(/<extractRefresh[^>]*id="([^"]+)"[^>]*priority="([^"]*)"[^>]*consecutiveFailedCount="([^"]*)"[^>]*type="([^"]*)"/g);
for (const match of taskMatches) {
const [, taskId, priority, consecutiveFailedCount, type] = match;
const scheduleMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<schedule[^>]*frequency="([^"]*)"[^>]*nextRunAt="([^"]*)"[^>]*>`));
const frequency = scheduleMatch ? scheduleMatch[1] : null;
const nextRunAt = scheduleMatch ? scheduleMatch[2] : null;
const workbookMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<workbook[^>]*id="([^"]+)"`));
const datasourceMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<datasource[^>]*id="([^"]+)"`));
const workbookId = workbookMatch ? workbookMatch[1] : null;
const datasourceId = datasourceMatch ? datasourceMatch[1] : null;
tasks.push({
id: taskId,
priority: parseInt(priority),
consecutiveFailedCount: parseInt(consecutiveFailedCount),
type,
schedule: {
frequency,
nextRunAt,
},
workbookId,
datasourceId,
});
}
return tasks;
}
export async function querySites(auth: any): Promise<any[]> {
const { token: authToken } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const querySitesUrl = `${auth.serverUrl}/api/${apiVersion}/sites`;
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: querySitesUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to query sites: ${response.status}`);
}
const responseBody = ensureString(response.body);
const sites: any[] = [];
const siteMatches = responseBody.matchAll(/<site[^>]*id="([^"]+)"[^>]*name="([^"]+)"[^>]*contentUrl="([^"]*)"[^>]*>/g);
for (const match of siteMatches) {
const [, siteId, name, contentUrl] = match;
sites.push({
id: siteId,
name,
contentUrl,
});
}
return sites;
}
export async function queryWorkbooks(auth: any): Promise<any[]> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const queryWorkbooksUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, 'workbooks');
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: queryWorkbooksUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to query workbooks: ${response.status}`);
}
const responseBody = ensureString(response.body);
const workbooks: any[] = [];
const workbookMatches = responseBody.matchAll(/<workbook[^>]*id="([^"]+)"[^>]*name="([^"]+)"[^>]*contentUrl="([^"]*)"[^>]*>/g);
for (const match of workbookMatches) {
const [, workbookId, name, contentUrl] = match;
workbooks.push({
id: workbookId,
name,
contentUrl,
});
}
return workbooks;
}
export async function queryViews(auth: any): Promise<any[]> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const queryViewsUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, 'views');
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: queryViewsUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to query views: ${response.status}`);
}
const responseBody = ensureString(response.body);
const views: any[] = [];
const viewMatches = responseBody.matchAll(/<view[^>]*id="([^"]+)"[^>]*name="([^"]+)"[^>]*contentUrl="([^"]*)"[^>]*viewUrlName="([^"]*)"/g);
for (const match of viewMatches) {
const [, viewId, name, contentUrl, viewUrlName] = match;
views.push({
id: viewId,
name,
contentUrl,
viewUrlName,
});
}
return views;
}
export interface WebhookData {
id?: string;
name: string;
event: string;
destinationUrl: string;
}
export async function createWebhook(auth: any, webhookData: WebhookData): Promise<string> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const createWebhookUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, 'webhooks');
const requestBody = `<?xml version="1.0" encoding="UTF-8"?>
<tsRequest>
<webhook name="${webhookData.name}" event="${webhookData.event}">
<webhook-destination>
<webhook-destination-http method="POST" url="${webhookData.destinationUrl}" />
</webhook-destination>
</webhook>
</tsRequest>`;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: createWebhookUrl,
headers: {
...getTableauHeaders(authToken),
'Content-Type': 'application/xml',
},
body: requestBody,
});
if (response.status !== 201) {
throw new Error(`Failed to create webhook: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const webhookIdMatch = responseBody.match(/<webhook[^>]*id="([^"]+)"/);
const webhookId = webhookIdMatch ? webhookIdMatch[1] : null;
if (!webhookId) {
throw new Error('Failed to extract webhook ID from response');
}
return webhookId;
}
export async function deleteWebhook(auth: any, webhookId: string): Promise<void> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const deleteWebhookUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, `webhooks/${webhookId}`);
const response = await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: deleteWebhookUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 204) {
throw new Error(`Failed to delete webhook: ${response.status} - ${response.body}`);
}
}
export async function listWebhooks(auth: any): Promise<any[]> {
const { token: authToken, siteId } = await getAuthToken(auth);
const apiVersion = auth.apiVersion || '3.26';
const listWebhooksUrl = buildTableauUrl(auth.serverUrl, apiVersion, siteId, 'webhooks');
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: listWebhooksUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to list webhooks: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const webhooks: any[] = [];
const webhookMatches = responseBody.matchAll(/<webhook[^>]*id="([^"]+)"[^>]*name="([^"]+)"[^>]*event="([^"]+)"/g);
for (const match of webhookMatches) {
const [, webhookId, name, event] = match;
webhooks.push({
id: webhookId,
name,
event,
});
}
return webhooks;
}

View File

@@ -0,0 +1,60 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const datasourceEventTrigger = createTrigger({
name: 'datasource_event',
displayName: 'Datasource Event',
description: 'Triggers when a datasource event occurs (created, updated, or deleted)',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {
eventType: Property.StaticDropdown({
displayName: 'Event Type',
description: 'Select the datasource event to trigger on',
required: true,
options: {
disabled: false,
options: [
{ label: 'Created', value: 'DatasourceCreated' },
{ label: 'Updated', value: 'DatasourceUpdated' },
{ label: 'Deleted', value: 'DatasourceDeleted' },
],
},
defaultValue: 'DatasourceCreated',
}),
},
sampleData: {
resource: 'DATASOURCE',
event_type: 'DatasourceCreated',
resource_name: 'Sample Datasource',
site_luid: 'site-uuid',
resource_luid: 'datasource-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const eventType = context.propsValue.eventType;
const webhookData: WebhookData = {
name: `ActivePieces_Datasource_${eventType}_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: eventType,
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,60 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const datasourceRefreshEventTrigger = createTrigger({
name: 'datasource_refresh_event',
displayName: 'Datasource Refresh Event',
description: 'Triggers when a datasource refresh event occurs (started, succeeded, or failed)',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {
eventType: Property.StaticDropdown({
displayName: 'Event Type',
description: 'Select the datasource refresh event to trigger on',
required: true,
options: {
disabled: false,
options: [
{ label: 'Refresh Started', value: 'DatasourceRefreshStarted' },
{ label: 'Refresh Succeeded', value: 'DatasourceRefreshSucceeded' },
{ label: 'Refresh Failed', value: 'DatasourceRefreshFailed' },
],
},
defaultValue: 'DatasourceRefreshStarted',
}),
},
sampleData: {
resource: 'EXTRACTS',
event_type: 'DatasourceRefreshStarted',
resource_name: 'Sample Datasource',
site_luid: 'site-uuid',
resource_luid: 'datasource-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const eventType = context.propsValue.eventType;
const webhookData: WebhookData = {
name: `ActivePieces_Datasource_Refresh_${eventType}_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: eventType,
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,59 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const labelEventTrigger = createTrigger({
name: 'label_event',
displayName: 'Label Event',
description: 'Triggers when a label event occurs (created, updated, or deleted)',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {
eventType: Property.StaticDropdown({
displayName: 'Event Type',
description: 'Select the label event to trigger on',
required: true,
options: {
disabled: false,
options: [
{ label: 'Created', value: 'LabelCreated' },
{ label: 'Updated', value: 'LabelUpdated' },
{ label: 'Deleted', value: 'LabelDeleted' },
],
},
defaultValue: 'LabelCreated',
}),
},
sampleData: {
resource: 'DATASOURCE',
event_type: 'LabelCreated',
resource_name: 'Sample Asset',
site_luid: 'site-uuid',
resource_luid: 'asset-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const eventType = context.propsValue.eventType;
const webhookData: WebhookData = {
name: `ActivePieces_Label_${eventType}_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: eventType,
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,150 @@
import { createTrigger, TriggerStrategy, PiecePropValueSchema, AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders } from '../common';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
const polling: Polling<AppConnectionValueForAuthProperty<typeof tableauAuth>, Record<string, never>> = {
strategy: DedupeStrategy.LAST_ITEM,
items: async ({ auth }) => {
const tableauAuth = auth.props;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
const listTasksUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, 'tasks/extractRefreshes');
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: listTasksUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to list extract refresh tasks: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const tasks: any[] = [];
const taskMatches = responseBody.matchAll(/<extractRefresh[^>]*id="([^"]+)"[^>]*priority="([^"]*)"[^>]*consecutiveFailedCount="([^"]*)"[^>]*type="([^"]*)"/g);
for (const match of taskMatches) {
const [, taskId, priority, consecutiveFailedCount, type] = match;
const scheduleMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<schedule[^>]*id="([^"]*)"[^>]*name="([^"]*)"[^>]*state="([^"]*)"[^>]*priority="([^"]*)"[^>]*createdAt="([^"]*)"[^>]*updatedAt="([^"]*)"[^>]*type="([^"]*)"[^>]*frequency="([^"]*)"[^>]*nextRunAt="([^"]*)"`));
let schedule = null;
if (scheduleMatch) {
const [, scheduleId, scheduleName, state, schedulePriority, createdAt, updatedAt, scheduleType, frequency, nextRunAt] = scheduleMatch;
schedule = {
id: scheduleId,
name: scheduleName,
state,
priority: parseInt(schedulePriority),
createdAt,
updatedAt,
type: scheduleType,
frequency,
nextRunAt,
};
} else {
const cloudScheduleMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<schedule[^>]*frequency="([^"]*)"[^>]*nextRunAt="([^"]*)"`));
if (cloudScheduleMatch) {
const [, frequency, nextRunAt] = cloudScheduleMatch;
schedule = {
frequency,
nextRunAt,
} as any;
const frequencyDetailsMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<frequencyDetails[^>]*start="([^"]*)"`));
if (frequencyDetailsMatch) {
const [, start] = frequencyDetailsMatch;
(schedule as any).frequencyDetails = {
start,
};
const intervalMatches = [...responseBody.matchAll(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>.*?<interval[^>]*>.*?<weekDay>([^<]+)</weekDay>`, 'gs'))];
if (intervalMatches.length > 0) {
(schedule as any).frequencyDetails.intervals = intervalMatches.map((m: RegExpMatchArray) => ({ weekDay: m[1] }));
}
}
}
}
const workbookMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<workbook[^>]*id="([^"]+)"`));
const datasourceMatch = responseBody.match(new RegExp(`<extractRefresh[^>]*id="${taskId}"[^>]*>[\\s\\S]*?<datasource[^>]*id="([^"]+)"`));
const workbookId = workbookMatch ? workbookMatch[1] : null;
const datasourceId = datasourceMatch ? datasourceMatch[1] : null;
tasks.push({
id: taskId,
priority: parseInt(priority),
consecutiveFailedCount: parseInt(consecutiveFailedCount),
type,
schedule,
workbookId,
datasourceId,
});
}
return tasks.map((task) => ({
id: task.id,
data: task,
}));
},
};
export const listExtractRefreshTasksTrigger = createTrigger({
name: 'list_extract_refresh_tasks',
displayName: 'List Extract Refresh Tasks',
description: 'Lists extract refresh tasks for the site',
auth: tableauAuth,
type: TriggerStrategy.POLLING,
props: {},
sampleData: {
id: '0ece2369-c4eb-4382-be0f-961039d708a0',
priority: 50,
consecutiveFailedCount: 5,
type: 'RefreshExtractTask',
schedule: {
frequency: 'Weekly',
nextRunAt: '2023-06-08T04:50:00Z',
frequencyDetails: {
start: '21:50:00',
intervals: [
{ weekDay: 'Thursday' }
],
},
},
workbookId: '7e766949-7166-4b3d-90ba-784f7575743b',
datasourceId: null,
},
onEnable: async (context) => {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
onDisable: async (context) => {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
run: async (context) => {
return await pollingHelper.poll(polling, context);
},
test: async (context) => {
return await pollingHelper.test(polling, context);
},
});

View File

@@ -0,0 +1,149 @@
import { createTrigger, TriggerStrategy, Property, PiecePropValueSchema, AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
import { tableauAuth } from '../../index';
import { getAuthToken, buildTableauUrl, getTableauHeaders } from '../common';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
function ensureString(body: any): string {
if (typeof body === 'string') return body;
if (typeof body === 'object') return JSON.stringify(body);
return String(body);
}
const polling: Polling<AppConnectionValueForAuthProperty<typeof tableauAuth>, { jobType?: string; status?: string }> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
const tableauAuth = auth.props;
const { token: authToken, siteId } = await getAuthToken(tableauAuth);
const apiVersion = tableauAuth.apiVersion || '3.26';
let queryJobsUrl = buildTableauUrl(tableauAuth.serverUrl, apiVersion, siteId, 'jobs');
const filters: string[] = [];
if (propsValue.jobType) {
filters.push(`jobType:eq:${propsValue.jobType}`);
}
if (propsValue.status) {
filters.push(`status:eq:${propsValue.status}`);
}
if (lastFetchEpochMS) {
const lastFetchDate = new Date(lastFetchEpochMS);
const isoDate = lastFetchDate.toISOString();
filters.push(`createdAt:gt:${isoDate}`);
}
if (filters.length > 0) {
queryJobsUrl += `?filter=${filters.join(',')}`;
}
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: queryJobsUrl,
headers: getTableauHeaders(authToken),
});
if (response.status !== 200) {
throw new Error(`Failed to query jobs: ${response.status} - ${response.body}`);
}
const responseBody = ensureString(response.body);
const jobs: any[] = [];
const jobMatches = responseBody.matchAll(/<backgroundJob[^>]*id="([^"]+)"[^>]*status="([^"]*)"[^>]*createdAt="([^"]*)"[^>]*startedAt="([^"]*)"[^>]*endedAt="([^"]*)"[^>]*priority="([^"]*)"[^>]*jobType="([^"]*)"/g);
for (const match of jobMatches) {
const [, jobId, status, createdAt, startedAt, endedAt, priority, jobType] = match;
jobs.push({
id: jobId,
status,
createdAt,
startedAt,
endedAt,
priority: parseInt(priority),
jobType,
});
}
return jobs.map((job) => ({
epochMilliSeconds: new Date(job.createdAt).getTime(),
data: job,
}));
},
};
export const newJobTrigger = createTrigger({
name: 'new_job',
displayName: 'New Job',
description: 'Triggers when a job matches the specified criteria',
auth: tableauAuth,
type: TriggerStrategy.POLLING,
props: {
jobType: Property.StaticDropdown({
displayName: 'Job Type',
description: 'Filter by job type (optional)',
required: false,
options: {
disabled: false,
options: [
{ label: 'All Job Types', value: '' },
{ label: 'Refresh Extracts', value: 'refresh_extracts' },
{ label: 'Increment Extracts', value: 'increment_extracts' },
{ label: 'Run Flow', value: 'run_flow' },
{ label: 'Refresh Workbook', value: 'refresh_workbook' },
{ label: 'Refresh Datasource', value: 'refresh_datasource' },
],
},
defaultValue: '',
}),
status: Property.StaticDropdown({
displayName: 'Status',
description: 'Filter by job status (optional)',
required: false,
options: {
disabled: false,
options: [
{ label: 'All Statuses', value: '' },
{ label: 'Success', value: 'Success' },
{ label: 'Failed', value: 'Failed' },
{ label: 'InProgress', value: 'InProgress' },
{ label: 'Pending', value: 'Pending' },
{ label: 'Cancelled', value: 'Cancelled' },
],
},
defaultValue: '',
}),
},
sampleData: {
id: '919055e5-25db-4a2b-9611-1408dd06632d',
status: 'Success',
createdAt: '2023-12-01T10:00:00Z',
startedAt: '2023-12-01T10:00:15Z',
endedAt: '2023-12-01T10:01:00Z',
priority: 50,
jobType: 'refresh_extracts',
},
onEnable: async (context) => {
await pollingHelper.onEnable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
onDisable: async (context) => {
await pollingHelper.onDisable(polling, {
auth: context.auth,
store: context.store,
propsValue: context.propsValue,
});
},
run: async (context) => {
return await pollingHelper.poll(polling, context);
},
test: async (context) => {
return await pollingHelper.test(polling, context);
},
});

View File

@@ -0,0 +1,45 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const userDeletedTrigger = createTrigger({
name: 'user_deleted',
displayName: 'User Deleted',
description: 'Triggers when a user is deleted',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {},
sampleData: {
resource: 'USER',
event_type: 'UserDeleted',
resource_name: 'Deleted User',
site_luid: 'site-uuid',
resource_luid: 'user-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const webhookData: WebhookData = {
name: `ActivePieces_User_Deleted_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: 'UserDeleted',
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,45 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const viewDeletedTrigger = createTrigger({
name: 'view_deleted',
displayName: 'View Deleted',
description: 'Triggers when a workbook view is deleted',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {},
sampleData: {
resource: 'VIEW',
event_type: 'ViewDeleted',
resource_name: 'Deleted View',
site_luid: 'site-uuid',
resource_luid: 'view-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const webhookData: WebhookData = {
name: `ActivePieces_View_Deleted_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: 'ViewDeleted',
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,60 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const workbookEventTrigger = createTrigger({
name: 'workbook_event',
displayName: 'Workbook Event',
description: 'Triggers when a workbook event occurs (created, updated, or deleted)',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {
eventType: Property.StaticDropdown({
displayName: 'Event Type',
description: 'Select the workbook event to trigger on',
required: true,
options: {
disabled: false,
options: [
{ label: 'Created', value: 'WorkbookCreated' },
{ label: 'Updated', value: 'WorkbookUpdated' },
{ label: 'Deleted', value: 'WorkbookDeleted' },
],
},
defaultValue: 'WorkbookCreated',
}),
},
sampleData: {
resource: 'WORKBOOK',
event_type: 'WorkbookCreated',
resource_name: 'Sample Workbook',
site_luid: 'site-uuid',
resource_luid: 'workbook-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const eventType = context.propsValue.eventType;
const webhookData: WebhookData = {
name: `ActivePieces_Workbook_${eventType}_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: eventType,
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});

View File

@@ -0,0 +1,60 @@
import { createTrigger, TriggerStrategy, Property } from '@activepieces/pieces-framework';
import { tableauAuth } from '../../index';
import { createWebhook, deleteWebhook, WebhookData } from '../common';
export const workbookRefreshEventTrigger = createTrigger({
name: 'workbook_refresh_event',
displayName: 'Workbook Refresh Event',
description: 'Triggers when a workbook refresh event occurs (started, succeeded, or failed)',
auth: tableauAuth,
type: TriggerStrategy.WEBHOOK,
props: {
eventType: Property.StaticDropdown({
displayName: 'Event Type',
description: 'Select the workbook refresh event to trigger on',
required: true,
options: {
disabled: false,
options: [
{ label: 'Refresh Started', value: 'WorkbookRefreshStarted' },
{ label: 'Refresh Succeeded', value: 'WorkbookRefreshSucceeded' },
{ label: 'Refresh Failed', value: 'WorkbookRefreshFailed' },
],
},
defaultValue: 'WorkbookRefreshStarted',
}),
},
sampleData: {
resource: 'EXTRACTS',
event_type: 'WorkbookRefreshStarted',
resource_name: 'Sample Workbook',
site_luid: 'site-uuid',
resource_luid: 'workbook-uuid',
created_at: '2023-12-01T10:00:00Z',
},
async onEnable(context) {
const eventType = context.propsValue.eventType;
const webhookData: WebhookData = {
name: `ActivePieces_Workbook_Refresh_${eventType}_${context.webhookUrl.substring(context.webhookUrl.lastIndexOf('/') + 1)}`,
event: eventType,
destinationUrl: context.webhookUrl,
};
const webhookId = await createWebhook(context.auth, webhookData);
await context.store?.put('webhook_id', webhookId);
},
async onDisable(context) {
const webhookId = await context.store?.get('webhook_id');
if (webhookId) {
await deleteWebhook(context.auth, webhookId as string);
}
},
async run(context) {
const payload = context.payload.body as any;
return [payload];
},
});