-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from tago-io/feat/newCmds
fixed export for tago run new fields
- Loading branch information
Showing
14 changed files
with
749 additions
and
394 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import kleur from "kleur"; | ||
import prompts from "prompts"; | ||
|
||
import { Account } from "@tago-io/sdk"; | ||
import { DashboardInfo } from "@tago-io/sdk/lib/types"; | ||
|
||
import { getEnvironmentConfig } from "../../lib/config-file"; | ||
import { errorHandler, infoMSG, successMSG } from "../../lib/messages"; | ||
import { confirmPrompt } from "../../prompt/confirm"; | ||
import { pickDashboardIDFromTagoIO } from "../../prompt/pick-dashboard-id-from-tagoio"; | ||
|
||
interface IOptions { | ||
to: string; | ||
from: string; | ||
environment: string; | ||
amount: number; | ||
} | ||
|
||
interface DashboardTabs { | ||
key: string; | ||
value: string; | ||
link: string; | ||
hidden: boolean; | ||
} | ||
|
||
/** | ||
* | ||
* @param account | ||
* @param dashID | ||
* @param arrangement | ||
* @param tabID | ||
* @returns | ||
*/ | ||
async function deleteWidgetsFromTab(account: Account, dashID: string, arrangement: DashboardInfo["arrangement"], tabID: string) { | ||
if (!arrangement) { | ||
return; | ||
} | ||
|
||
const myTabWidgets = arrangement.filter((x) => x.tab === tabID); | ||
for (const item of myTabWidgets) { | ||
await account.dashboards.widgets.delete(dashID, item.widget_id); | ||
} | ||
|
||
return arrangement.filter((x) => x.tab !== tabID); | ||
} | ||
|
||
/** | ||
* | ||
* @param account | ||
* @param dashID | ||
* @param arrangement | ||
* @param tabID | ||
* @param toTabID | ||
* @returns | ||
*/ | ||
async function copyWidgetsFromTab(account: Account, dashID: string, arrangement: DashboardInfo["arrangement"], tabID: string, toTabID: string) { | ||
if (!arrangement) { | ||
return; | ||
} | ||
|
||
const fromTabWidgets = arrangement.filter((x) => x.tab === tabID); | ||
for (const item of fromTabWidgets) { | ||
const widgetInfo = await account.dashboards.widgets.info(dashID, item.widget_id); | ||
const { widget: newWidgetID } = await account.dashboards.widgets.create(dashID, widgetInfo); | ||
arrangement.push({ | ||
widget_id: newWidgetID, | ||
tab: toTabID, | ||
x: item.x, | ||
y: item.y, | ||
width: item.width, | ||
height: item.height, | ||
}); | ||
} | ||
|
||
return arrangement; | ||
} | ||
|
||
/** | ||
* | ||
* @param list | ||
* @param message | ||
* @returns | ||
*/ | ||
async function pickTabFromDashboard(list: { title: string; value: string }[], message: string = "Which tab you want to pick?") { | ||
const { id } = await prompts({ | ||
message, | ||
name: "id", | ||
type: "autocomplete", | ||
choices: list, | ||
}); | ||
|
||
return id as string; | ||
} | ||
|
||
/** | ||
* | ||
* @param dashID | ||
* @param options | ||
* @returns | ||
*/ | ||
async function copyTabWidgets(dashID: string, options: IOptions) { | ||
const config = getEnvironmentConfig(options.environment); | ||
if (!config || !config.profileToken) { | ||
errorHandler("Environment not found"); | ||
return; | ||
} | ||
|
||
const account = new Account({ token: config.profileToken, region: "usa-1" }); | ||
if (!dashID) { | ||
dashID = await pickDashboardIDFromTagoIO(account); | ||
} | ||
|
||
const dashInfo = await account.dashboards.info(dashID); | ||
|
||
if (!options.from || !options.to) { | ||
let tabList = (dashInfo.tabs as DashboardTabs[]).map((x, i) => ({ title: `${i}. ${x.value} [${x.key}]`, value: x.key })); | ||
if (!options.from) { | ||
options.from = await pickTabFromDashboard(tabList, "Pick a source tab to copy the data from:"); | ||
} | ||
|
||
tabList = tabList.filter((x) => x.value !== options.from); | ||
if (!options.to) { | ||
options.to = await pickTabFromDashboard(tabList, "Pick a target tab to copy the data to: "); | ||
} | ||
} | ||
|
||
const { to, from } = options; | ||
if (to === from) { | ||
errorHandler("You can't copy data from and to the same tab"); | ||
return; | ||
} | ||
|
||
const toTabName = (dashInfo.tabs as DashboardTabs[]).find((x) => x.key === to)?.value as string; | ||
const fromTabName = (dashInfo.tabs as DashboardTabs[]).find((x) => x.key === from)?.value as string; | ||
|
||
infoMSG(`> Copying tab ${kleur.cyan(fromTabName)} to ${kleur.cyan(toTabName)}...`); | ||
const yesNo = await confirmPrompt(); | ||
if (!yesNo) { | ||
return; | ||
} | ||
|
||
let arrangement = await deleteWidgetsFromTab(account, dashID, dashInfo.arrangement, to); | ||
arrangement = await copyWidgetsFromTab(account, dashID, arrangement, from, to); | ||
|
||
await account.dashboards.edit(dashID, { arrangement }); | ||
|
||
successMSG(`> Tab ${fromTabName} [${kleur.cyan(from)}] copied to ${toTabName} [${kleur.cyan(to)}]`); | ||
} | ||
|
||
export { copyTabWidgets }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Command } from "commander"; | ||
|
||
import { copyTabWidgets } from "./copy-tab"; | ||
|
||
// function handleNumber(value: any, _previous: any) { | ||
// if (Number.isNaN(Number(value))) { | ||
// throw `${value} is not a number`; | ||
// } | ||
// return Number(value); | ||
// } | ||
|
||
function dashboardCommands(program: Command) { | ||
program.command("Devices Header"); | ||
program | ||
.command("copy-tab") | ||
.alias("inspect") | ||
.description("copy a tab of a dashboard to another tab") | ||
.argument("[dashboardID]", "ID of the dashboard") | ||
.option("-from, --from [tabID]", "ID of the Tab to copy") | ||
.option("-to, --to [tabID]", "ID of the Tab to paste") | ||
.option("--env [environment]", "environment from config.js") | ||
// .option("-g, --getOnly", "fiter logs to show GET content only") | ||
.action(copyTabWidgets) | ||
.addHelpText( | ||
"after", | ||
` | ||
Running this command will completely erase the target tab and replace it with a copy of the source tab. | ||
Example: | ||
$ tagoio copy-tab | ||
$ tagoio copy-tab 62151835435d540010b768c4 -from 1688653060637 -to 2688653060638 | ||
$ tagoio copy-tab 62151835435d540010b768c4 --env dev | ||
` | ||
); | ||
} | ||
|
||
export { dashboardCommands }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { Account, Device, Utils } from "@tago-io/sdk"; | ||
|
||
import { getEnvironmentConfig } from "../../lib/config-file"; | ||
import { errorHandler, highlightMSG, infoMSG, successMSG } from "../../lib/messages"; | ||
import { confirmPrompt } from "../../prompt/confirm"; | ||
import { pickDeviceIDFromTagoIO } from "../../prompt/pick-device-id-from-tagoio"; | ||
|
||
interface IOptions { | ||
to: string; | ||
from: string; | ||
environment: string; | ||
amount: number; | ||
} | ||
|
||
async function startCopy(deviceFrom: Device, deviceTo: Device, options: IOptions) { | ||
const { amount } = options; | ||
|
||
const dataStream = deviceFrom.getDataStreaming({}, { poolingRecordQty: 2000, poolingTime: 400, neverStop: false }); | ||
|
||
let total = 0; | ||
for await (let data of dataStream) { | ||
data = data.filter((x) => x.variable !== "payload"); | ||
total += data.length; | ||
await deviceTo.sendData(data); | ||
if (total >= amount) { | ||
break; | ||
} | ||
} | ||
|
||
successMSG(`> Data transfer completed. A total of ${total} registers were copied.`); | ||
} | ||
|
||
async function copyDeviceData(options: IOptions) { | ||
const config = getEnvironmentConfig(options.environment); | ||
if (!config || !config.profileToken) { | ||
errorHandler("Environment not found"); | ||
return; | ||
} | ||
|
||
if (!options.from || !options.to) { | ||
const account = new Account({ token: config.profileToken, region: "usa-1" }); | ||
options.from = await pickDeviceIDFromTagoIO(account, "Choose a device to copy the data from:"); | ||
options.to = await pickDeviceIDFromTagoIO(account, "Choose a device to copy the data to: "); | ||
} | ||
|
||
let deviceFrom: Device | undefined; | ||
let deviceTo: Device | undefined; | ||
if (options.from?.length === 24 || options.to?.length === 24) { | ||
const account = new Account({ token: config.profileToken, region: "usa-1" }); | ||
|
||
if (options.from.length === 24) { | ||
deviceFrom = await Utils.getDevice(account, options.from); | ||
} | ||
|
||
if (options.to.length === 24) { | ||
deviceTo = await Utils.getDevice(account, options.to); | ||
} | ||
} | ||
|
||
if (!deviceTo || !deviceFrom) { | ||
errorHandler("Device not found"); | ||
return; | ||
} | ||
|
||
if (!deviceFrom) { | ||
deviceFrom = new Device({ token: options.from }); | ||
} | ||
|
||
if (!deviceTo) { | ||
deviceTo = new Device({ token: options.to }); | ||
} | ||
|
||
const deviceToInfo = await deviceTo.info(); | ||
const deviceFromInfo = await deviceFrom.info(); | ||
|
||
infoMSG(`> Copying tab ${highlightMSG(deviceFromInfo.name)} to ${highlightMSG(deviceToInfo.name)}...`); | ||
const yesNo = await confirmPrompt(); | ||
if (!yesNo) { | ||
return; | ||
} | ||
|
||
await startCopy(deviceFrom, deviceTo, options); | ||
} | ||
|
||
export { copyDeviceData }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.