|
// ==UserScript== |
|
// @name GMI Cloud Billing Button |
|
// @namespace https://github.com/yourname |
|
// @version 1.0 |
|
// @description Adds a "Usage & Billing" button above the Deposit button that links to the usage-billing page |
|
// @author Dan Haiduc |
|
// @match https://console.gmicloud.ai/* |
|
// @icon https://www.google.com/s2/favicons?sz=64&domain=gmicloud.ai |
|
// @grant none |
|
// ==/UserScript== |
|
|
|
(function () { |
|
'use strict'; |
|
|
|
function addBillingButton() { |
|
// Find the Deposit button by text content |
|
const buttons = document.querySelectorAll('button'); |
|
const depositBtn = Array.from(buttons).find(b => b.textContent.trim() === 'Deposit'); |
|
if (!depositBtn) return false; |
|
|
|
// Avoid inserting our button more than once |
|
const parent = depositBtn.parentNode; |
|
if (parent.querySelector('[data-gmi-billing-btn]')) return true; |
|
|
|
// Create the billing link styled like a button |
|
const link = document.createElement('a'); |
|
link.setAttribute('data-gmi-billing-btn', ''); |
|
link.href = 'https://console.gmicloud.ai/user-setting/usage-billing'; |
|
link.target = '_self'; |
|
link.textContent = 'Usage & Billing'; |
|
|
|
// Match the Deposit button's classes and inline styles for consistency |
|
link.className = depositBtn.className; |
|
link.style.cssText = depositBtn.style.cssText; |
|
|
|
// Ensure it looks and behaves like a button |
|
link.style.textDecoration = 'none'; |
|
link.style.display = 'inline-flex'; |
|
link.style.alignItems = 'center'; |
|
link.style.justifyContent = 'center'; |
|
link.style.cursor = 'pointer'; |
|
|
|
// Add a subtle visual difference so the two buttons are distinguishable |
|
link.style.marginBottom = '6px'; |
|
|
|
// Insert above the Deposit button |
|
parent.insertBefore(link, depositBtn); |
|
|
|
return true; |
|
} |
|
|
|
// Helper to start observing for the Deposit button |
|
function watch() { |
|
if (!addBillingButton()) { |
|
const observer = new MutationObserver(() => { |
|
if (addBillingButton()) observer.disconnect(); |
|
}); |
|
observer.observe(document.body, { childList: true, subtree: true }); |
|
} |
|
} |
|
|
|
if (document.readyState === 'loading') { |
|
document.addEventListener('DOMContentLoaded', watch); |
|
} else { |
|
watch(); |
|
} |
|
})(); |