Dashboard Widget – trying to get a sample widget to work of work item feed
Hey,
due to there not being a native matrix-style report for work items, I decided to give it a shot myself, and am currently in the youtrack demo app project. I got so far that the widget gets displayed and I can fetch the workitems from the instance. However, iterating over them, they have no author etc. despite the docs stating they should have some. first I thought the missing query fields were the issue, but with them specified it's throwing heaps of errors.
The logs:
Upload id: 2026_09_27_WKwSXH68SEUeULwmkrjC1v (file: console-export-2026-9-27_20-58-4.log)
This is the code (sorry for my messy typescript. I only know JS so far):
import React, {memo, useCallback} from 'react';
import Button from '@jetbrains/ring-ui-built/components/button/button';
import Heading from "@jetbrains/ring-ui-built/components/heading/heading";
// Register widget in YouTrack. To learn more, see https://www.jetbrains.com/help/youtrack/devportal-apps/apps-host-api.html
const host = await YTApp.register();
// @ts-ignore
let workItems: unknown = []
const fetchWorkItems = async () => {
try {
const ytResponse = await host.fetchYouTrack(
'workItems',
{
query: {
fields: "author, text, duration"
}
}
);
console.log(ytResponse);
// @ts-ignore
workItems = ytResponse;
} catch (e) {
console.error(e);
}
}
await fetchWorkItems();
const AppComponent: React.FunctionComponent = () => {
return (
<div className="widget">
<Heading>Logged Time Entries</Heading>
<p>{
// @ts-ignore
workItems.length} items found</p>
{ // @ts-ignore
workItems.map((item, i) => {
return (
<div key={i}>
<p>{item.author} logged {item.duration} and left description: {item.text}</p>
</div>
)
}
)}
{/*<Button primary onClick={callBackend}>{'Make HTTP Request'}</Button>*/}
</div>
);
};
export const App = memo(AppComponent);
Please sign in to leave a comment.
Hi!
I'm Sergey from the YouTrack Team. Thanks for reaching out!
The REST API returns only IDs unless you request additional fields. In your request, remove the spaces after commas and specify the properties you need from the nested
authoranddurationobjects:fields: 'id,author(name,login),duration(minutes,presentation),text'.In the widget, render those properties rather than the objects themselves. For example, inside your
mapcallback:For a matrix report, use
duration.minuteswhen calculating totals. The Fields Syntax guide explains how to request nested fields, and the Host API reference shows how to pass them tofetchYouTrack().While we can't troubleshoot custom apps end to end, I hope these changes help. I couldn't access the uploaded console log, so if errors remain, please share the first error message in your reply. That will help us check whether the API request is failing.
Let me know how it goes!
Oh, thanks for the example! I wasn't aware I could nest in the query / field specification. That should get me started!
Hey, your tips were really helpful! I have another two questions, though:
- is there any way to test with a live server / socket mode or something? Or do I have to build & upload again and again?
- Would I need to fetch e.g. like that in the app component or would this be better written in backend / backend global?
I don't quite understand when I would resort to custom endpoints. I've seen the backend module in the worklog section; so I thought I could just write a module export that takes e.g. start date, end date?
In my mind this doesn't count as a custom endpoint as it uses the standard JS API. My goal is to get all work items in a certain timeframe and then be able to group them by their issue's custom field “location”.
If you could give me another pointer how to structure the code I'd be very grateful!
Hi!
If you're using the TypeScript Enhanced DX scaffold on YouTrack 2026.2.16593 or later,
npm run devgives you frontend hot reload and automatically rebuilds and uploads backend changes. See the Local Development guide for the setup.For your report, I'd start with the REST API from the widget. The Work Items REST resource lets you filter work items by date and request their related issue fields, so you can group the results by Location in the widget. The Host API reference shows how a widget makes these requests with
host.fetchYouTrack().A backend function on its own is not callable from a widget. You'd need an app HTTP handler exposed to the widget via
host.fetchApp(). I'd consider that only if you later need server-side aggregation or app-only data that the REST request can't provide.Thank you so much, I hadn't noticed that there's this Enhanced DX scaffold option (seems to be quite new, too). And also thanks to your help, I was able to get it up and running, very nice!
(to add to everything, I was doing visualisation with D3, which – even without YouTrack as host – is a lot of part that need to cooperate, so to say):
You are welcome! Glad to hear that it helped!
Feel free to reach out if there's anything else I can assist you with.