miroapp / app-examples Goto Github PK
View Code? Open in Web Editor NEWMiro Developer Platform App Examples
Home Page: https://developers.miro.com/
License: MIT License
Miro Developer Platform App Examples
Home Page: https://developers.miro.com/
License: MIT License
Hello,
Is this function working as it should? I can't get token from the promise - seems it never actually ends. Moreover once user is authorized the miro plugin doesnt recognize this - I mean getScopes() returns new scopes, however things like creation or reading from board print errors in console that addon was not actually authorized. Should I maybe somehow force miro to recognize that authentication was finished? After board reload everything works.
Hi everyone,
My question if this uses a backend component or if it runs completely in frontend because it could bypassed, since it is all js.
Does it uses a backend in Typescript that communicates with stripe for the payment and also the manage of user's Miro board? If there is indeed a backend component does it communicates with Miro after OAuth authentication, access token, etc?
Thanks
In sample-app, I tried to run 'npm run ngrok' on both windows 10 and WSL2 Ubuntu 20.04, but all failed. I confirmed that the package was installed and not broken, but there were always some problems with ngrok.
It seems better for windows developers to download .exe file from the official site of ngrok. I suggest to add this tip to readme.md.
Hi, I like the idea behind the nextjs-oauth app example but at the moment, the repository is missing much of the content that's shown in the Readme file. The Components
folder is missing completely as well as all Pages
that are not responsible for the authentication. The constants.js
file is also missing.
All of the above makes the example a lot less helpful.
Hi,
We added miro.d.ts as an npm dependency in our package.json which helps us quite a bit with developing our plugin with Typescript.
However, we are currently in the process of migrating from authorize to requestAuthorization as described here to prepare for the change coming up in July 1.
But so far that miro.d.ts hasn't been updated, and it does not have a definition for the requestAuthorization method.
Is that going to be added soon?
Thank you!
contributing guide makes no mention of using prettier but it looks like the linter runs prettier. We should probably update our contributing guide to tell folks that we are using prettier and they would need to install it and run it prior to submitting a PR otherwise they will just get errors and it's not a good developer experience.
Otherwise, if we are not really using prettier, maybe we should change the GitHub actions to stop running yarn prettier --check ./examples
When screen size is changed to 200 px, then when opening a modal it will be scaled down to fit into 200 px even when the value requested is higher ie 600.
This method from SDK seem to work differently to plugins like Jira plugin where it somehow enforces to not be scaled down [ie its modal is not affected by screen size].
Expected behaviour is to have modal set to the size that is provided or allow for scrolling.
the minimum task is to understand the basis of logic and conduct a test. the task for the evening is to find the right libraries and make a project God vs Evil
Hi team.
I'm truly grateful to you so much for providing such a great app and its SDK.
First of all, please forgive me for not understanding whether it is appropriate to write this here.
Now, I want to implement Miro's Web-plugin using Typescript.
Do you have any plans to create type definitions for Typescript?
Currently, I need to silence the transpiler, because the boilerplate that you have prepared does not have a type definition for the miro object which is defined globally.
Even if I implement it with typescript, I feel that I do not receive the benefits of typescript.
I would be very happy if you could get the type definition as follows.
npm install -D @type/miro-sdk
How about this idea?
Thank you so much in advance.
It seems this creates promises that might bever be resolved. If this is called from main iframe may it lead to memory leak? May it lead to creating multiple Promises?
First of all, I'm sorry to bother you by asking this question and no matter the result is, I will really appreciate it.
In MacOS, I can use the touchpad two-fingers swipe to forward / backward the browser history navigation. I can prevent this event in Chrome by using below codes:
html, body {
overscroll-behavior-x: none;
}
But it can't work in Safari, I noticed Miro drawing page prevents this event in Safari. I really wonder how to do it. Thank you a lot anyway. :)
I see my app is working fine when I deploy it on http://localhost:3000
, and the app icon in the appears in the toolbar and the app opens on Miro Whiteboard. To share and expose the app, when I ran ngrok http 3000
and pasted the resulting https://
URL in the App URL heading in Profile Settings -> Your Apps
.
But, on doing this, the app stopped showing in the toolbar. What could be the reason for this? What am I missing?
I could be missing something very obvious, but this has been troubling me for quite some time now. Any help is appreciated. Thank you.
Hi Team Miro 👋🏼
I've been looking into spinning up the GitHub AppCards example, and am currently a touch confused as to what I need to do to get this up and running. The instructions say:
add a .env file with the required environment variables (See section at bottom)
and the section has a list of required environment variables, but no indication of what I need to do to obtain them.
I'm not familiar with Vite or Supabase - is there a guide or similar that I can follow to set these things up and obtain the relevant values to populate the env vars with?
Hello,
Can you provide a small example on how to use prototyping example? Whatever I do I just end up with black frame without a way out of it. I understand this is an example and doesn't need to be perfect so I would like to know what is the intended flow? What to click and do in order to see the functionality of this example.
Thanks
Hello,
Really interested in trying out Prototyping in my miro board. I managed to follow the instructions to the letter save the last one:
"Get https url from ngrok and paste it in iframe url in your app settings."
I am not sure what this means. Do you think it could be explained better? I apologise if it is too basic. Also, I am on the free miro plan. Could it be I need to upgrade to be able to use your plugin?
Thanks.
I am trying to create this feature: I just want to drag and drop an image and insert a text inside the image, like in shapes. Is it possible to do? Could U help me pls? Thanks
I've been trying to make a connection between 2 notes using the Miro node js client but I am running into some error when trying to push the connection to the board.
The code I am trying to run.
const { MiroApi, Connector, StickyNoteItem } = require("@mirohq/miro-api")
require("dotenv").config()
const miroApi = new MiroApi(process.env.ACCESS_TOKEN)
//Removed my boardID for this issue
const boardID = ""
async function postStickyNote(x, y, id) {
const board = await miroApi.getBoard(boardID)
console.log(board)
const stickyNote = new StickyNoteItem(miroApi, boardID, id, {
type: "string",
data: {
content: "Hello World",
shape: "rectangle",
},
style: {
fillColor: "light_green",
textAlign: "center",
textAlignVertical: "bottom"
},
position: {
x: x,
y: y,
relativeTo: "Anything can go in here & it posts to the board anyways"
}
})
await board.createStickyNoteItem(stickyNote)
return stickyNote.id
}
async function start() {
const board = await miroApi.getBoard(boardID)
console.log(board)
let id1 = await postStickyNote(-1000, 0, 1)
let id2 = await postStickyNote(1000, 0, 2)
const connection = new Connector(
miroApi,
boardID,
"Connector-1",
{
id: 3,
startItem: {
id: id1
},
endItem: {
id: id2
}
}
)
await board.createConnector(connection)
}
start()
The error I am getting
C:\Users\Admin\OneDrive\Desktop\jonny code\MiroTest\node_modules@mirohq\miro-api\dist\api\apis.js:2292
throw new HttpError(response, bodyAsJson, response.status);
^
HttpError: HTTP request failed
at makeJsonRequest (C:\Users\Admin\OneDrive\Desktop\jonny code\MiroTest\node_modules@mirohq\miro-api\dist\api\apis.js:2292:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async MiroApi.createConnector (C:\Users\Admin\OneDrive\Desktop\jonny code\MiroTest\node_modules@mirohq\miro-api\dist\api\apis.js:627:42)
at async Board.createConnector (C:\Users\Admin\OneDrive\Desktop\jonny code\MiroTest\node_modules@mirohq\miro-api\dist\highlevel\index.js:317:25)
at async start (C:\Users\Admin\OneDrive\Desktop\jonny code\MiroTest\MakeConnection.js:58:5) {
response: Response {
size: 0,
timeout: 15000,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: true,
ended: true,
endEmitted: true,
reading: false,
constructed: true,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: true,
errored: null,
closed: true,
closeEmitted: true,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
dataEmitted: true,
decoder: null,
encoding: null,
[Symbol(kPaused)]: false
},
_events: [Object: null prototype] {
prefinish: [Function: prefinish],
error: [ [Function (anonymous)], [Function (anonymous)] ],
data: [Function (anonymous)],
end: [Function (anonymous)]
},
_eventsCount: 4,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
constructed: true,
prefinished: true,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: true,
closeEmitted: true,
[Symbol(kOnFinished)]: []
},
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
disturbed: true,
error: null
},
[Symbol(Response internals)]: {
url: 'https://api.miro.com/v2/boards//connectors',
status: 400,
statusText: 'Bad Request',
headers: Headers {
[Symbol(map)]: [Object: null prototype] {
'content-type': [ 'application/json' ],
'content-length': [ '376' ],
connection: [ 'close' ],
date: [ 'Sun, 30 Oct 2022 23:51:13 GMT' ],
server: [ 'nginx' ],
'set-cookie': [
'AWSALBTG=M/pMDthwegXAob8Jt2xkjrTkv+0w/dAOYiK6VTH7aduh25VmMVjRU1tmY4ERmjEPKGqmE97/a4ffmqnOipwegJZkekx6aHJa9ZsiP/CpNgwYUahE+dPWaPJUkxKMt/FeWSPKYoYz47GY7YkNB/h7G+ZO6Af+jHkPAwp04PJQNufy; Expires=Sun, 06 Nov 2022 23:51:12 GMT; Path=/',
'AWSALBTGCORS=M/pMDthwegXAob8Jt2xkjrTkv+0w/dAOYiK6VTH7aduh25VmMVjRU1tmY4ERmjEPKGqmE97/a4ffmqnOipwegJZkekx6aHJa9ZsiP/CpNgwYUahE+dPWaPJUkxKMt/FeWSPKYoYz47GY7YkNB/h7G+ZO6Af+jHkPAwp04PJQNufy; Expires=Sun, 06 Nov 2022 23:51:12 GMT; Path=/; SameSite=None; Secure'
],
vary: [
'Origin, Access-Control-Request-Method, Access-Control-Request-Headers'
],
'content-security-policy': [ "default-src 'self'" ],
'referrer-policy': [ 'no-referrer' ],
'x-ratelimit-limit': [ '100000' ],
'x-ratelimit-remaining': [ '99550' ],
'x-ratelimit-reset': [ '1667173931' ],
'x-request-id': [ '810eb201-42d7-431c-9762-759f9a6a91f7' ],
'x-content-type-options': [ 'nosniff' ],
'x-xss-protection': [ '1; mode=block' ],
'cache-control': [
'private, no-cache, no-store, no-transform, max-age=0, must-revalidate, proxy-revalidate'
],
pragma: [ 'no-cache' ],
expires: [ '0' ],
'x-frame-options': [ 'DENY' ],
'strict-transport-security': [ 'max-age=31536000' ],
'x-cache': [ 'Error from cloudfront' ],
via: [
'1.1 68126347056de2d05be3dd362ccba986.cloudfront.net (CloudFront)'
],
'x-amz-cf-pop': [ 'LHR50-C1' ],
'x-amz-cf-id': [
'PQ1cuhzi2ct27Ib3CUgC_UfkabQx2-3ICNQNyr73hpOPOsezJ3cTXA=='
]
}
},
counter: 0
}
},
body: {
type: 'error',
code: '3.0215',
context: {
boardId: '',
validationErrors: [
{ code: '3.0209', message: 'Value 1 is not allowed' },
{ code: '3.0209', message: 'Value 2 is not allowed' }
]
},
message: 'Unable to complete operation because of the validation errors.',
status: 400
},
statusCode: 400
}
Any help here would be appreciated, thankyou :)
I am trying out miro SDK in my browser console.
I have referred https://developers.miro.com/reference#line.
To create a connecting line between two widgets that are already present on the board. I used the following method.
await miro.board.widgets.create({
type:"line",
startWidget: {
id:"3074457347915794715"
},
endWidget: {
id:"3074457347915827854"
},
})
I am getting these warnings.
Field 'startWidget' is unsupported for 'LINE' widget
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
zt @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ VM14:228
(anonymous) @ VM14:228
(anonymous) @ VM14:228
c @ VM14:228
e.create @ BoardSdk.673da6559561343caec0.js:1
r.value @ BoardSdk.673da6559561343caec0.js:1
o.value @ BoardSdk.673da6559561343caec0.js:1
t.processCommand @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
setTimeout (async)
E.A.pluginId @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
t.sendCommand @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
e.<computed> @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ VM3248:1
Simillarly for 'endWidget'
BoardSdk.673da6559561343caec0.js:1 Field 'endWidget' is unsupported for 'LINE' widget
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
zt @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ VM14:228
(anonymous) @ VM14:228
(anonymous) @ VM14:228
c @ VM14:228
e.create @ BoardSdk.673da6559561343caec0.js:1
r.value @ BoardSdk.673da6559561343caec0.js:1
o.value @ BoardSdk.673da6559561343caec0.js:1
t.processCommand @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
setTimeout (async)
E.A.pluginId @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
t.sendCommand @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ BoardSdk.673da6559561343caec0.js:1
e.<computed> @ BoardSdk.673da6559561343caec0.js:1
(anonymous) @ VM3248:1
The line does get created, but it is not connecting these two widgets.
[{…}]
0:
bounds: {x: 0, y: 0, top: 0, left: 0, bottom: 0, …}
capabilities: {editable: true}
captions: []
clientVisible: true
createdUserId: "3074457347032502271"
endPosition: {x: 0, y: 0}
id: "3074457347915952126"
lastModifiedUserId: "3074457347032502271"
metadata: {}
startPosition: {x: 0, y: 0}
style: {lineColor: "#000000", lineStyle: 2, lineThickness: 1, lineType: 0, lineStartStyle: 0, …}
type: "LINE"
__proto__: Object
length: 1
__proto__: Array(0)
What am I doing wrong?
Thanks in advance.
I want use microphone for record audio:
miro.onReady(async () => {
await navigator.mediaDevices.getUserMedia({ audio: true, video: false })
});
but i get error:
Uncaught (in promise) DOMException: Permission denied
Can I somehow get permission from Mirro to receive usermedia?
In this video there is a demo of 2-way sync and GH sync. But the original repo does not exist now. Can I find it somewhere else?
Hello, I was trying to launch nextjs-full-stack app example, and I am getting this error after start yarn dev
When scope is provided as a query parametr for authentication, the redirect back is without "#" even when response_type is "token.
When application is installed under URL "www.example.com" and it tries to openModal with url specified as "samplePath" it will open in modal URL "www.example.com//samplePath". Expected is "www.example.com/samplePath".
When making a connector between two items you should be able to choose where the connector starts & ends on the items.
I've found that when making a connector between items it doesn't always place right so being able to choose would be a nice feature.
Thoughts?
Hi,
I'm using the sample app as the codebase and have included code from the drag and drop app to insert an image into the board. However, I'm getting the following error:
Uncaught (in promise) Error while command execution: Method 'create' requires scope 'boards:write'
In the app configuration, I've clicked these checkboxes and then the button.
I've also tried clicking on the Install app link from the app itself.
However, when I check the console, no scopes are included in the response.
How do I request scopes while getting an access token? Do I need to include additional query string parameters?
Any help will be much appreciated.
Thanks!
I've installed the 'layers' code as a web widget to my dev team board and the link to https://miro.com/app/static/miro.uikit.css is returning 404.
It's called in the sidebar.html file:
<link rel="stylesheet" type="text/css" href="https://miro.com/app/static/miro.uikit.css">
Thanks
I created one App Card in the developer console. It is the same as in the Miro SDK reference here
const appCard = await miro.board.createAppCard({
title: 'This is the title of the app card',
description:
'The custom preview fields are highlighted in different colors; the app card icon is displayed on the bottom-right.',
style: {
cardTheme: '#2d9bf0',
},
fields: [
{
value: 'Owner',
iconUrl: 'https://cdn-icons-png.flaticon.com/512/921/921124.png',
iconShape: 'round',
fillColor: '#FBE983',
textColor: '#F83A22',
tooltip: 'Caption text displayed in a tooltip when clicking or hovering over the preview field',
},
{
value: 'Timeline',
iconUrl: 'https://cdn-icons-png.flaticon.com/512/3094/3094861.png',
iconShape: 'square',
fillColor: '#F8D878',
textColor: '#503000',
tooltip: 'Caption text displayed in a tooltip when clicking or hovering over the preview field',
},
{
value: 'Tasks',
iconUrl: 'https://cdn-icons-png.flaticon.com/512/3176/3176366.png',
iconShape: 'square',
fillColor: '#bef2f2',
textColor: '#0713FF',
tooltip: 'Caption text displayed in a tooltip when clicking or hovering over the preview field',
},
{
value: 'Bug fix',
iconUrl: 'https://cdn-icons-png.flaticon.com/512/3867/3867669.png',
iconShape: 'square',
fillColor: '#E5E5E5',
textColor: '#000000',
tooltip: 'Caption text displayed in a tooltip when clicking or hovering over the preview field',
},
],
x: 2000,
y: 2000,
width: 320,
rotation: 0.0,
status: 'connected', // Default status of new app cards: 'disconnected'
});
// Listen to the 'app_card:open' event
miro.board.ui.on('app_card:open', (event) => {
console.log('Subscribed to app card open event', event);
const {appCard} = event;
// Fetch a specific app card by specifying its ID
const url = `https://my.app.example.com/modal.html?appCardId=${appCard.id}`;
// Open the modal to display the content of the fetched app card
miro.board.ui.openModal({
url,
});
});
// Output the created item to the developer console
console.log(appCard);
After this, on doing the following:
appCard.fields = [];
await appCard.sync();
none of the fields on the App Card get removed.
On doing:
appCard.fields.pop();
await appCard.sync();
repeatedly, I am able to remove all but the first field, i.e., the owner field.
Could someone explain the reason for this behavior?
I'm trying to run the sample-app code following the README instructions. However 'npm run start' fails with the following error:
> [email protected] start C:\Users\nro25\code\miro-examples\app-examples\sample-app
> ./node_modules/nodemon/bin/nodemon.js ./src/app.js -e js,html
'.' is not recognized as an internal or external command
In my package.json file
"scripts": {
"start": "./node_modules/nodemon/bin/nodemon.js ./src/app.js -e js,html",
"ngrok": "./node_modules/ngrok/bin/ngrok http 3000"
}
Any suggestions? Thanks
App was calling to GET __vite_ping every few seconds, and not optimized for production
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.