Creating a Azure Devops web extension from a React application - azure-devops

I am looking to create a web extension in Azure Devops from a React application.
As in seen in this tutorial, there is a file called my-hub.html, which is the start page of the extension.
By following the steps in the above link, I was able to create a web extension that prints the logged in user, as per my-hub.html, which does document.getElementById("name").innerText = VSS.getWebContext().user.name;.
However, I have written my application in React using Typescript and the start file is App.tsx. Could someone advise how I can instruct the vss-extension.json file to load the extension from App.tsx file?
{
"manifestVersion": 1,
"id": "my-first-extension",
"publisher": "",
"version": "1.0.0",
"name": "My First Extension",
"description": "A sample Visual Studio Services extension",
"public": false,
"categories": ["Azure Repos"],
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"contributions": [
{
"id": "my-hub",
"type": "ms.vss-web.hub",
"targets": [
"ms.vss-code-web.code-hub-group"
],
"properties": {
"name": "My Hub",
"uri": "my-hub.html"
}
}
],
"files": [
{
"path": "my-hub.html",
"addressable": true
},
{
"path": "node_modules/vss-web-extension-sdk/lib",
"addressable": true,
"packagePath": "lib"
}
]
}
Would I need to convert the React application to an html page?

you can deploy the React App first, then add the app/website link in html file. Something like this :
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">;
<head>
<script src="lib/VSS.SDK.min.js"></script>
<style>
body {
background-color: rgb(100, 100, 100);
color: white;
margin: 10px;
font-family: "Segoe UI VSS (Regular)","-apple-system",BlinkMacSystemFont,"Segoe UI",sans-serif;
}
</style>
<script type="text/javascript">
VSS.init();
VSS.ready(function() {
document.getElementById("name").innerText = VSS.getWebContext().user.name;
});
</script>
</head>
<body>
<h1>Hello, <span id="name"></span></h1>
<p>Hello. This is a link to React App?<br />
Just click to navigate to it</p>
</body>
</html>
Please reference this example if you want to integrate the React app directly with the extension.

Related

Email template | Insert custom HTML block above the subject

Im trying to add gmail markups to the top of the order confirmation email like showed in the picture
I tried using the gmail provided markup code:
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "Order",
"merchant": {
"#type": "Organization",
"name": "Amazon.com"
},
"orderNumber": "123-4567890-1234567",
"priceCurrency": "USD",
"price": "29.99",
"acceptedOffer": {
"#type": "Offer",
"itemOffered": {
"#type": "Product",
"name": "Google Chromecast"
},
"price": "29.99",
"priceCurrency": "USD",
"eligibleQuantity": {
"#type": "QuantitativeValue",
"value": "1"
}
}
}
</script>
But with no luck.
Im using a docker with magento 2 and mailhog (locally). Mailhog recieves the order mail. The script exists in the <head> part (with inspect element) but does not get rendeded.
Also tried to sned that exact code using gmail.com to myself - it does not get rendered either.
What im missing?

Adding booking meta data to Google Search

I can't for the life of me figure out how this company adding this meta data to their Google search.
Does anyone know how to add the data and booking links like the below image?
Thanks
What you are seeing in these search results is what Google defines as "Rich Results" more information can be viewed in Google's Structured Data documentation. Specifically Edgewater Medical center is taking advantage of the event functionality to define times and dates.
This can be verified by pasting the page's source in the Rich Results Test tool, results for this page can be viewed at
https://search.google.com/test/rich-results?utm_campaign=devsite&utm_medium=jsonld&utm_source=event&id=m1ZrUywePCZ_NglFJIjZfg
According to google documentation in order to make this happen you have to follow a few steps:
Ensure that Googlebot can crawl your event pages (meaning, your pages
aren't protected by a robots.txt file or robots meta tag).
Ensure that your server can handle increased crawl rate.
Make sure you follow the Google guidelines.
Add structured data to your event pages. Currently, the event experience on Google only supports pages that focus on a single event. We recommend focusing on adding markup to your event posting pages instead of pages that list schedules or multiple events.
An example of such "structured data" for a standard event is shown below:
<html>
<head>
<title>The Adventures of Kira and Morrison</title>
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "Event",
"name": "The Adventures of Kira and Morrison",
"startDate": "2025-07-21T19:00-05:00",
"endDate": "2025-07-21T23:00-05:00",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"eventStatus": "https://schema.org/EventScheduled",
"location": {
"#type": "Place",
"name": "Snickerpark Stadium",
"address": {
"#type": "PostalAddress",
"streetAddress": "100 West Snickerpark Dr",
"addressLocality": "Snickertown",
"postalCode": "19019",
"addressRegion": "PA",
"addressCountry": "US"
}
},
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg",
"https://example.com/photos/16x9/photo.jpg"
],
"description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
"offers": {
"#type": "Offer",
"url": "https://www.example.com/event_offer/12345_201803180430",
"price": "30",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"validFrom": "2024-05-21T12:00"
},
"performer": {
"#type": "PerformingGroup",
"name": "Kira and Morrison"
},
"organizer": {
"#type": "Organization",
"name": "Kira and Morrison Music",
"url": "https://kiraandmorrisonmusic.com"
}
}
</script>
</head>
<body>
</body>
</html>

Vega Vega-lite streaming

I am starting using Vega and I am now trying to stream my data to nicely refresh my graph. I followed this doc (https://vega.github.io/vega-lite/tutorials/streaming.html) with no success so far. The examples I found have values in arrays and mine are in a JSON file which is refreshed on a regular basis. I ended up with this code which properly shows my graph as I want but it does not refresh my data.
<html>
<head>
<title>A title</title>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vega#5.8.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#4.0.0-beta.12"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.1.0"></script>
<style media="screen">
/* Add space between Vega-Embed links */
.vega-actions a {
margin-right: 5px;
}
</style>
</head>
<body>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vega#5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#5"></script>
</head>
<body>
<div id="vis"></div>
<script>
var vlSpec = {
data: {"url": "http://localhost:8123/d.json", "name":"table"},
mark: "bar",
"width": 1240,
"encoding": {
"y": {"field": "task", "type": "ordinal", "sort":"x2"},
"x": {"field": "start", "type": "temporal", "aggregate":"sum"},
"x2": {"field": "end", "type": "temporal"},
"color": {"field": "status", "type": "nominal"}
}
};
// Embed visualization and save view as window.view:
vegaEmbed('#vis', vlSpec).then(function(res) {
window.setInterval(function() {
var changeSet = vega
.changeset()
.insert()
res.view.change('table', changeSet).run();
}, 1000);
});
</script>
</body>
</html>
My issue seems to be the insert() where in the example of the doc they insert the result of a function to generate data and I should insert here my JSON file -- I tried different variations with fetch but with no success.
Any help would be appreciated.
Thanks
Let me answer my own question as I figured it out.
First I used jquery:
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
I removed the url tag not to load the JSON file at first:
"data": {"name":'table'},
And the VEGA streaming data from my JSON file:
vegaEmbed('#vis', vlSpec).then(function(res) {
var newdata ;
window.setInterval(function() {
jQuery.getJSON("http://localhost:8123/d.json", function(data) {
newdata = data;
})
var changeSet = vega
.changeset()
.remove(vega.truthy)
.insert(newdata)
console.log (newdata)
res.view.change('table', changeSet).run();
}, 1000);
});
It works like a charm !

How to Start up external url chrome app with fullscreen

I'm publishing the chrome app.
I need to open up "http://kangwodnd.cafe24.com/" with fullscreen mode.
in my manifest.json
{
"manifest_version": 2,
"name": "배드민턴 코트 예약시스템",
"description": "Badminton Court Reservation System",
"version": "0.44",
"icons": {
"128": "128.png"
},
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": [
"fullscreen",
"alwaysOnTopWindows"
]
}
and
I don't know what I have to do in background.js
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create("http://kangwodnd.cafe24.com/",{
});
});
It looks like publishing normally, but when I run the app. It's not working no alert no warning.
What am I missing?
You can't open an external URL as a hosted app window.
To achieve what you want, you need to create your own local HTML file, and embed a <webview> into it to show your webapp.

Content script doesn't re-execute on page reload

I'm creating a content script Chrome extension that hides the newsfeed on the Facebook homepage.
This script loads when I first open facebook.com, but fails when navigating into Facebook and back to the main page (which is a URL that's defined in the extension correctly).
Here's my manifest.js file:
{
"name": "NewsBlock",
"description": "NewsBlock - Facebook Newsfeed Hider",
"version": "1.0.0",
"background": {
"scripts": ["background.js"]
},
"permissions": [
"tabs", "http://*/*", "https://*/*", "storage"
],
"browser_action": {
"default_title": "NewsBlock",
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["https://www.facebook.com/"],
"js": ["myscript.js"]
}
],
"manifest_version": 2
}
Here's my myscript.js file:
if (document.getElementById('home_stream'))
document.getElementById('home_stream').style.visibility = "hidden";
if (document.getElementById('pagelet_home_stream'))
document.getElementById('pagelet_home_stream').style.visibility = "hidden";
console.log("NewsBlock Activated...")
Any help in understanding why this isn't loaded when I navigate back to the homepage on Facebook will be amazing.
That's because on many occasions the Facebook page uses the history.pushstate method to navigate. This method can change the current url without causing a new page load. The navigation is simulated by replacing part of the page content with the result of ajax calls.
You can use the chrome.webNavigation.onHistoryStateUpdated event to detect that situation, as suggested in this answer https://stackoverflow.com/a/17584559/1507998.
Some links in facebook call ajax functions, so most of time clicking on a link in facebook doesn't change the page, just loads content via ajax. So your content script executes only once.
There are two possible solution,
You can also add a DOM change listener like DOMSubtreeModified, and run the code every time when content is changed.
You can add CSS code to page, so it doesn't need to be run every time even if page is changed via ajax.
Like this,
manifest.json
{
"name": "NewsBlock",
"description": "NewsBlock - Facebook Newsfeed Hider",
"version": "1.0.0",
"background": {
"scripts": ["background.js"]
},
"permissions": [
"tabs", "http://*/*", "https://*/*", "storage"
],
"browser_action": {
"default_title": "NewsBlock",
"default_icon": "icon.png"
},
"content_scripts": [
{
"matches": ["https://www.facebook.com/"],
"js": ["myscript.js"],
"css": ["mystyle.css"]
}
],
"manifest_version": 2
}
mystyle.css
#home_stream, #pagelet_home_stream {
visibility: hidden;
}