Chez AXOPEN, nous souhaitions se brancher sur GitLabGitLab, c’est une plateforme permettant d’héberger et de gérer des projets web de A à Z. pour récupérer la liste des issues pour un certain projet. On s’est donc lancé dans la création d’un connector Gitlab pour Google Data Studio.
Google Data Studio est un super outil de reporting de plus en plus utilisé qui possède de nombreux atouts. En particulier, il permet de créer des plugins / connectors pour se connecter à différentes sources de données.
En interne, nous souhaitions se brancher sur GitLabGitLab, c’est une plateforme permettant d’héberger et de gérer des projets web de A à Z. pour récupérer la liste des issues pour un certain projet. On s’est donc lancé dans la création d’un connector Gitlab pour Google Data Studio.
Bon on va pas se mentir la documentation de Google est plutôt faible et peu détaillée. Donc on a pas mal miséré pour trouver des exemples fiables. Mais on y est quand même arrivé et avons réussi à faire ce petit script qui permet de récupérer les issues d’un projet choisi au démarrage.
C’est pas hyper propre, surtout au niveau de la gestion des types de données mais ça marche et c’est déjà pas mal. Et concernant notre besoin c’était largement suffisant. Pour l’utiliser, il suffit de remplir l’APIUne API est un programme permettant à deux applications distinctes de communiquer entre elles et d’échanger des données. KEY (générée depuis l’interface de GitLab) et de modifier les url des endpoints.
En espérant que ça puisse aider des personnes qui ont le même besoin. On pourrait le publier en open source mais nous avons trop de souci avec la documentation pour en faire quelque chose de présentable !
{{< highlight javascript "linenos=table">}}
var API\_KEY = " API\_KEY ";
function isAdminUser(){
return true;
}
function getConfig(request) {
var url = [
’https://git.axopen.com/api/v4/projects?private_token=’,
API_KEY];
var response = JSON.parse(UrlFetchApp.fetch(url.join( ")));
var projects = [];
response.forEach(function(value) {
console.log(value.id);
projects.push({
" label ": value.path\_with\_namespace.toUpperCase(),
" value ": ’AB’+value.id
});
});
var config = {
configParams: [
{
" type ": " SELECT_SINGLE ",
" name ": " SELECT_SINGLE ",
" displayName ": " Select one project ",
" helpText ": " Pick only one project ",
" options ": projects
}
]
};
return config;
};
var fontDataSchema = [
{
name: ’id_issue’,
label: ’Issue ID’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’title’,
label: ’Issue title’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’created_at’,
label: ’Created at’,
dataType: ’STRING’
},
{
name: ’updated_at’,
label: ’Updated at’,
dataType: ’STRING’
},
{
name: ’closed_at’,
label: ’Closed at’,
dataType: ’STRING’
},
{
name: ’state’,
label: ’State’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’user\_notes\_count’,
label: ’User notes count’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’description’,
label: ’Description’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’time_estimate’,
label: ’Time estimate’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’total\_time\_spent’,
label: ’Total time spent’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’downvotes’,
label: ’Downvotes’,
dataType: ’NUMBER’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’upvotes’,
label: ’Upvotes’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
{
name: ’due_date’,
label: ’Due date’,
dataType: ’STRING’,
semantics: {
conceptType: ’DIMENSION’
}
},
];
function getSchema(request) {
return {schema: fontDataSchema};
};
function getData(request) {
var dataSchema = [];
request.fields.forEach(function(field) {
for (var i = 0; i < fontDataSchema.length; i++) {
if (fontDataSchema[i].name === field.name) {
dataSchema.push(fontDataSchema[i]);
break;
}
}
});
var url = [
’https://git.axopen.com/api/v4/projects/’+request.configParams.SELECT\_SINGLE.substring(2)+’/issues?private\_token=’,
API_KEY];
var response = JSON.parse(UrlFetchApp.fetch(url.join( ")));
var data = [];
response.forEach(function(value) {
var values = [];
dataSchema.forEach(function(field) {
switch(field.name) {
case ’id_issue’:
values.push(value.id);
break;
case ’title’:
values.push(value.title);
break;
case ’created_at’:
values.push(value.created_at.substring(0,10));
break;
case ’updated_at’:
values.push(value.updated\_at.created\_at.substring(0,10));
break;
case ’closed_at’:
values.push(value.closed\_at.created\_at.substring(0,10));
break;
case ’state’:
values.push(value.state);
break;
case ’upvotes’:
values.push(value.upvotes);
break;
case ’downvotes’:
values.push(value.downvotes);
break;
case ’due_date’:
values.push(value.due\_date.created\_at.substring(0,10));
break;
case ’time_estimate’:
values.push(value.time_estimate);
break;
case ’total\_time\_spent’:
values.push(value.total\_time\_spent);
break;
case ’user\_notes\_count’:
values.push(value.user\_notes\_count);
break;
case ’description’:
values.push(value.description);
break;
default:
values.push( ");
}
});
data.push({
values: values
});
});
return {
schema: dataSchema,
rows: data
};
};
function getAuthType() {
var response = {
" type ": " NONE "
};
return response;
}
{{< / highlight >}}
Découvrez comment créer un tableau de bord personnalisable sur Angular avec notre tutoriel détaillé. Suivez les étapes pour intégrer des widgets dynamiques facilement.
Dans le monde de la programmation web, ces dernières années ont donné lieu à une explosion pure et simple des frameworks ! Ils ont progressivement pris une place considérable dans nos vies de développeurs, et pourtant… faut-il vraiment les utiliser
Quelle est la syntaxe à utiliser pour appeler ou modifier un paramètre OPX2 ?