Sakura UI - Adding a Build Result Tab (converting a ViewLogTab to Sakura)

Is it possible to add a tab to the Build Results using Sakura?  I have one implemented in the old way, but I'd like to convert it so that it uses RingUI Table instead of importing Datatables.js.

I'm using a similar structure to the SakuraUI Github project to add the other bits of UI in the Build Summary etc, so if it could live alongside that it would be great.

Thanks!

4 comments
Comment actions Permalink
Official comment

Hi James! 

It's Denis - TeamCity Frontend developer. 
Thank you for your interest in this topic. 

In general, every tab is just a piece of a Web application, so you need to build your frontend app first (for example, as a build step). To build it, you can consume "Create React App", import Ring UI there as a module, and then use RingUI Table. Then, in the tab entry point (index.html), you can call for the freshly generated bundle.js in <script src ...> (the same you do for the datatables.js)

Another option is to integrate your report not as a tab but as a plugin into a certain PlaceId. That allows you to put vital information not in a dedicated tab but somewhere in the first-view-reachable place. We provide an API for integration - I would recommend starting from these articles

I understand that it sounds not like the easiest approach, so if you have further questions, don't hesitate to ask. 

Comment actions Permalink

Hey Denis

Good to meet you - thanks for the reply.

I've gone with the first suggestion (it's a lot of data and it makes most sense to have its own tab).  I've landed on what I think is what you meant, but might be a slight variation?  I have a JSP file for the tab, and that includes a DIV and the bundle js script.  I ended up with that for an ugly reason: I needed the BuildId of the current view in the rect app so I added it as a Global variable via the JSP.  Is there a better way of getting what would be the 'location' parameter on a Plugin via some global context?  I had a look but couldn't find anything.

0
Comment actions Permalink

Hello James,

Speaking of a light variation: there is a task that aimed to provide an easy way to integrate plugins as tabs in Sakura. Please, vote for it. 

In your case, you should operate with Model objects in Controller/JSP files. 
You have to fill the model with the required data. That should look something like this:

@Override
protected void fillModel(@NotNull final Map<String, Object> model,
@NotNull final HttpServletRequest request,
@NotNull final SBuild build) {
 SBuildType bt = build.getBuildType();
String btId = bt.getBuildTypeId();
String buildId = build.getBuildId();

model.put("buildId", buildId);
model.put("buildTypeId", btId);
}


In JSP, you can consume the bean like:

<c:set var="buildId" value="${buildId}"/>


Let me know if it helps. 

0
Comment actions Permalink

Hi!

Sorry for all the dumb questions: this is my first TeamCity plugin, and also my first time using Kotlin and Spring (I'm a C++ & Python programmer at work, and have some JS/React experience as a hobby).  This is a half work, half hobby project - it's a Runner to simplify launching & parsing the output of UnrealEngine builds.  I'll be making it OSS (and maybe publishing it on the Marketplace) when I can - I just need to fill out some forms at work that I've not gotten round to yet.

Anyway, I probably wasn't very clear - that's actually very close to what I had, but I used the fillModel in my class derived from ViewLogTab as opposed to a separate controller?

I was meaning how to get that BuildId to my React App effectively, not using a Global JS variable.  For anyone reading this who's trying to do the same thing, I ended up doing it like this:

Results-tab.jsp (this is the one that the class derived from ViewLogTab uses)

<div id="uebg_results" data-buildid='<c:out value="${buildId}"/>'></div>
<script language="JavaScript" type="text/javascript" src="plugins/uebg/buildtab.bundle.js"></script>

Then in my bundle entry point, index.js:

const root = document.getElementById('uebg_results');
ReactDOM.render(
<UEBuildResults {...(root.dataset)} />,
root);

Which results in an attribute called "buildid" being passed to the component.

I've gone ahead and upvoted that task.

Thanks again for the help!

 

0

Please sign in to leave a comment.