mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-02-23 12:05:56 +00:00
feat(public URL): Add a public URL field and use it for the status page
This commit is contained in:
parent
efdffca06c
commit
2488e6402e
8 changed files with 48 additions and 5 deletions
13
db/knex_migrations/2024-12-12-2255-add-public-url.js
Normal file
13
db/knex_migrations/2024-12-12-2255-add-public-url.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Add column publicUrl to monitor table
|
||||||
|
exports.up = function (knex) {
|
||||||
|
return knex.schema
|
||||||
|
.alterTable("monitor", function (table) {
|
||||||
|
table.text("publicUrl", "text");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (knex) {
|
||||||
|
return knex.schema.alterTable("monitor", function (table) {
|
||||||
|
table.dropColumn("publicUrl");
|
||||||
|
});
|
||||||
|
};
|
|
@ -53,7 +53,7 @@ class Monitor extends BeanModel {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.sendUrl) {
|
if (this.sendUrl) {
|
||||||
obj.url = this.url;
|
obj.url = this.publicUrl ?? this.url; // Use publicUrl if available, otherwise use url
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showTags) {
|
if (showTags) {
|
||||||
|
@ -91,6 +91,7 @@ class Monitor extends BeanModel {
|
||||||
id: this.id,
|
id: this.id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
|
publicUrl: this.publicUrl,
|
||||||
path,
|
path,
|
||||||
pathName,
|
pathName,
|
||||||
parent: this.parent,
|
parent: this.parent,
|
||||||
|
|
|
@ -790,6 +790,7 @@ let needSetup = false;
|
||||||
bean.parent = monitor.parent;
|
bean.parent = monitor.parent;
|
||||||
bean.type = monitor.type;
|
bean.type = monitor.type;
|
||||||
bean.url = monitor.url;
|
bean.url = monitor.url;
|
||||||
|
bean.publicUrl = monitor.publicUrl;
|
||||||
bean.method = monitor.method;
|
bean.method = monitor.method;
|
||||||
bean.body = monitor.body;
|
bean.body = monitor.body;
|
||||||
bean.headers = monitor.headers;
|
bean.headers = monitor.headers;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="my-3 form-check">
|
<div class="my-3 form-check">
|
||||||
<input id="show-clickable-link" v-model="monitor.isClickAble" class="form-check-input" type="checkbox" @click="toggleLink(monitor.group_index, monitor.monitor_index)" />
|
<input id="show-clickable-link" v-model="monitor.isClickAble" class="form-check-input" type="checkbox" @click="toggleLink(monitor.group_index, monitor.monitor_index)" data-testid="show-clickable-link" />
|
||||||
<label class="form-check-label" for="show-clickable-link">
|
<label class="form-check-label" for="show-clickable-link">
|
||||||
{{ $t("Show Clickable Link") }}
|
{{ $t("Show Clickable Link") }}
|
||||||
</label>
|
</label>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="submit" class="btn btn-danger" data-bs-dismiss="modal">
|
<button type="submit" class="btn btn-danger" data-bs-dismiss="modal" data-testid="monitor-settings-close">
|
||||||
{{ $t("Close") }}
|
{{ $t("Close") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
:class="{'link-active': true, 'btn-link': true}"
|
:class="{'link-active': true, 'btn-link': true}"
|
||||||
icon="cog" class="action me-3"
|
icon="cog" class="action me-3"
|
||||||
@click="$refs.monitorSettingDialog.show(group, monitor)"
|
@click="$refs.monitorSettingDialog.show(group, monitor)"
|
||||||
|
data-testid="monitor-setting"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1051,5 +1051,7 @@
|
||||||
"RabbitMQ Password": "RabbitMQ Password",
|
"RabbitMQ Password": "RabbitMQ Password",
|
||||||
"rabbitmqHelpText": "To use the monitor, you will need to enable the Management Plugin in your RabbitMQ setup. For more information, please consult the {rabitmq_documentation}.",
|
"rabbitmqHelpText": "To use the monitor, you will need to enable the Management Plugin in your RabbitMQ setup. For more information, please consult the {rabitmq_documentation}.",
|
||||||
"SendGrid API Key": "SendGrid API Key",
|
"SendGrid API Key": "SendGrid API Key",
|
||||||
"Separate multiple email addresses with commas": "Separate multiple email addresses with commas"
|
"Separate multiple email addresses with commas": "Separate multiple email addresses with commas",
|
||||||
|
"Public URL": "Public URL",
|
||||||
|
"publicUrlDescription": "The public URL of the monitor. Can be displayed on the status page as the monitor link."
|
||||||
}
|
}
|
||||||
|
|
|
@ -719,6 +719,16 @@
|
||||||
<input id="description" v-model="monitor.description" type="text" class="form-control">
|
<input id="description" v-model="monitor.description" type="text" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Public URL -->
|
||||||
|
<div class="my-3">
|
||||||
|
<label for="publicUrl" class="form-label">{{ $t("Public URL") }}</label>
|
||||||
|
<input id="publicUrl" v-model="monitor.publicUrl" type="url" class="form-control" data-testid="public-url-input">
|
||||||
|
|
||||||
|
<div class="form-text">
|
||||||
|
{{ $t("publicUrlDescription") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<tags-manager ref="tagsManager" :pre-selected-tags="monitor.tags"></tags-manager>
|
<tags-manager ref="tagsManager" :pre-selected-tags="monitor.tags"></tags-manager>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1727,6 +1737,10 @@ message HealthCheckResponse {
|
||||||
this.monitor.url = this.monitor.url.trim();
|
this.monitor.url = this.monitor.url.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.monitor.publicUrl) {
|
||||||
|
this.monitor.publicUrl = this.monitor.publicUrl.trim();
|
||||||
|
}
|
||||||
|
|
||||||
let createdNewParent = false;
|
let createdNewParent = false;
|
||||||
|
|
||||||
if (this.draftGroupName && this.monitor.parent === -1) {
|
if (this.draftGroupName && this.monitor.parent === -1) {
|
||||||
|
|
|
@ -12,6 +12,8 @@ test.describe("Status Page", () => {
|
||||||
const monitorName = "Monitor for Status Page";
|
const monitorName = "Monitor for Status Page";
|
||||||
const tagName = "Client";
|
const tagName = "Client";
|
||||||
const tagValue = "Acme Inc";
|
const tagValue = "Acme Inc";
|
||||||
|
const monitorUrl = "https://www.example.com/status";
|
||||||
|
const monitorPublicUrl = "https://www.example.com";
|
||||||
|
|
||||||
// Status Page
|
// Status Page
|
||||||
const footerText = "This is footer text.";
|
const footerText = "This is footer text.";
|
||||||
|
@ -30,13 +32,14 @@ test.describe("Status Page", () => {
|
||||||
await expect(page.getByTestId("monitor-type-select")).toBeVisible();
|
await expect(page.getByTestId("monitor-type-select")).toBeVisible();
|
||||||
await page.getByTestId("monitor-type-select").selectOption("http");
|
await page.getByTestId("monitor-type-select").selectOption("http");
|
||||||
await page.getByTestId("friendly-name-input").fill(monitorName);
|
await page.getByTestId("friendly-name-input").fill(monitorName);
|
||||||
await page.getByTestId("url-input").fill("https://www.example.com/");
|
await page.getByTestId("url-input").fill(monitorUrl);
|
||||||
await page.getByTestId("add-tag-button").click();
|
await page.getByTestId("add-tag-button").click();
|
||||||
await page.getByTestId("tag-name-input").fill(tagName);
|
await page.getByTestId("tag-name-input").fill(tagName);
|
||||||
await page.getByTestId("tag-value-input").fill(tagValue);
|
await page.getByTestId("tag-value-input").fill(tagValue);
|
||||||
await page.getByTestId("tag-color-select").click(); // Vue-Multiselect component
|
await page.getByTestId("tag-color-select").click(); // Vue-Multiselect component
|
||||||
await page.getByTestId("tag-color-select").getByRole("option", { name: "Orange" }).click();
|
await page.getByTestId("tag-color-select").getByRole("option", { name: "Orange" }).click();
|
||||||
await page.getByTestId("tag-submit-button").click();
|
await page.getByTestId("tag-submit-button").click();
|
||||||
|
await page.getByTestId("public-url-input").fill(monitorPublicUrl);
|
||||||
await page.getByTestId("save-button").click();
|
await page.getByTestId("save-button").click();
|
||||||
await page.waitForURL("/dashboard/*"); // wait for the monitor to be created
|
await page.waitForURL("/dashboard/*"); // wait for the monitor to be created
|
||||||
|
|
||||||
|
@ -79,6 +82,12 @@ test.describe("Status Page", () => {
|
||||||
await page.getByTestId("monitor-select").getByRole("option", { name: monitorName }).click();
|
await page.getByTestId("monitor-select").getByRole("option", { name: monitorName }).click();
|
||||||
await expect(page.getByTestId("monitor")).toHaveCount(1);
|
await expect(page.getByTestId("monitor")).toHaveCount(1);
|
||||||
await expect(page.getByTestId("monitor-name")).toContainText(monitorName);
|
await expect(page.getByTestId("monitor-name")).toContainText(monitorName);
|
||||||
|
await expect(page.getByTestId("monitor-name")).not.toHaveAttribute("href");
|
||||||
|
|
||||||
|
// Set public url on
|
||||||
|
await page.getByTestId("monitor-settings").click();
|
||||||
|
await page.getByTestId("show-clickable-link").check();
|
||||||
|
await page.getByTestId("monitor-settings-close").click();
|
||||||
|
|
||||||
// Save the changes
|
// Save the changes
|
||||||
await screenshot(testInfo, page);
|
await screenshot(testInfo, page);
|
||||||
|
@ -94,6 +103,8 @@ test.describe("Status Page", () => {
|
||||||
await expect(page.getByTestId("footer-text")).toContainText(footerText);
|
await expect(page.getByTestId("footer-text")).toContainText(footerText);
|
||||||
await expect(page.getByTestId("powered-by")).toHaveCount(0);
|
await expect(page.getByTestId("powered-by")).toHaveCount(0);
|
||||||
|
|
||||||
|
await expect(page.getByTestId("monitor-name")).toHaveAttribute("href", monitorPublicUrl);
|
||||||
|
|
||||||
await expect(page.getByTestId("update-countdown-text")).toContainText("00:");
|
await expect(page.getByTestId("update-countdown-text")).toContainText("00:");
|
||||||
const updateCountdown = Number((await page.getByTestId("update-countdown-text").textContent()).match(/(\d+):(\d+)/)[2]);
|
const updateCountdown = Number((await page.getByTestId("update-countdown-text").textContent()).match(/(\d+):(\d+)/)[2]);
|
||||||
expect(updateCountdown).toBeGreaterThanOrEqual(refreshInterval); // cant be certain when the timer will start, so ensure it's within expected range
|
expect(updateCountdown).toBeGreaterThanOrEqual(refreshInterval); // cant be certain when the timer will start, so ensure it's within expected range
|
||||||
|
|
Loading…
Add table
Reference in a new issue