mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-24 15:00:25 +02:00
321 lines
12 KiB
JavaScript
321 lines
12 KiB
JavaScript
import { defaultLogLevels } from "./defaultLogLevels";
|
|
|
|
window.app = window.app || {};
|
|
window.app.modals = window.app.modals || {};
|
|
|
|
window.app.modals.openLogsSettings = function(modalSettings = {
|
|
onbeforeopen: null,
|
|
onafteropen: null,
|
|
onbeforeclose: null,
|
|
onafterclose: null,
|
|
onsave: null,
|
|
ondelete: null,
|
|
}) {
|
|
const modal = logsSettingsModal(modalSettings);
|
|
if (!modal) {
|
|
return;
|
|
}
|
|
|
|
document.body.appendChild(modal);
|
|
|
|
app.modals.open(modal);
|
|
};
|
|
|
|
function logsSettingsModal(modalSettings) {
|
|
let modal;
|
|
|
|
const data = store({
|
|
isLoading: false,
|
|
isSaving: false,
|
|
isDeleting: false,
|
|
formSettings: {},
|
|
initFormSettingsHash: "",
|
|
get hasChanges() {
|
|
return data.initFormSettingsHash != JSON.stringify(data.formSettings);
|
|
},
|
|
});
|
|
|
|
function init(settings = {}) {
|
|
data.formSettings = {
|
|
logs: settings?.logs || {},
|
|
};
|
|
|
|
data.initFormSettingsHash = JSON.stringify(data.formSettings);
|
|
}
|
|
|
|
async function loadSettings() {
|
|
data.isLoading = true;
|
|
|
|
try {
|
|
const settings = await app.pb.settings.getAll({
|
|
requestKey: "logsSettings",
|
|
});
|
|
|
|
init(settings);
|
|
|
|
data.isLoading = false;
|
|
} catch (err) {
|
|
if (!err.isAbort) {
|
|
data.isLoading = false;
|
|
app.checkApiError(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function save() {
|
|
if (!data.hasChanges) {
|
|
return;
|
|
}
|
|
|
|
data.isSaving = true;
|
|
|
|
try {
|
|
const settings = await app.pb.settings.update(app.utils.filterRedactedProps(data.formSettings));
|
|
|
|
modalSettings.onsave?.(settings);
|
|
|
|
init(settings);
|
|
|
|
app.toasts.success("Successfully saved logs settings.");
|
|
|
|
data.isSaving = false;
|
|
|
|
app.modals.close(modal);
|
|
} catch (err) {
|
|
if (!err.isAbort) {
|
|
data.isSaving = false;
|
|
app.checkApiError(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function deleteLogs() {
|
|
data.isDeleting = true;
|
|
|
|
try {
|
|
await app.pb.logs.truncate();
|
|
|
|
modalSettings.ondelete?.();
|
|
|
|
app.toasts.success("Successfully deleted all logs.");
|
|
|
|
data.isDeleting = false;
|
|
|
|
if (!data.hasChanges) {
|
|
app.modals.close(modal);
|
|
}
|
|
} catch (err) {
|
|
if (!err.isAbort) {
|
|
data.isDeleting = false;
|
|
app.checkApiError(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
function confirmLogsDelete() {
|
|
app.modals.confirm(
|
|
"Do you really want to delete all logs?",
|
|
() => deleteLogs(),
|
|
null,
|
|
{ yesButton: "Yes, delete" },
|
|
);
|
|
}
|
|
|
|
modal = t.div(
|
|
{
|
|
pbEvent: "logsSettingsModal",
|
|
className: "modal popup sm logs-settings-modal",
|
|
onbeforeopen: (el) => {
|
|
loadSettings();
|
|
return modalSettings.onbeforeopen?.(el);
|
|
},
|
|
onafteropen: (el) => {
|
|
modalSettings.onafteropen?.(el);
|
|
},
|
|
onbeforeclose: (el) => {
|
|
return modalSettings.onbeforeclose?.(el);
|
|
},
|
|
onafterclose: (el) => {
|
|
modalSettings.onafterclose?.(el);
|
|
el?.remove();
|
|
},
|
|
},
|
|
t.header({ className: "modal-header" }, t.h5({ className: "m-auto" }, "Logs settings")),
|
|
() => {
|
|
if (data.isLoading) {
|
|
return t.div(
|
|
{ className: "modal-content flex", style: "min-height: 200px" },
|
|
t.span({ className: "loader m-auto" }),
|
|
);
|
|
}
|
|
|
|
return [
|
|
t.form(
|
|
{
|
|
pbEvent: "logsSettingsForm",
|
|
id: "logsSettingsForm",
|
|
className: "modal-content logs-settings-form",
|
|
onsubmit: (e) => {
|
|
e.preventDefault();
|
|
save();
|
|
},
|
|
},
|
|
t.div(
|
|
{ className: "grid" },
|
|
t.div(
|
|
{ className: "col-lg-12" },
|
|
t.field(
|
|
{ className: "field" },
|
|
t.label({ htmlFor: "logs.maxDays" }, "Max days retention"),
|
|
t.input({
|
|
type: "number",
|
|
id: "logs.maxDays",
|
|
name: "logs.maxDays",
|
|
min: 0,
|
|
required: true,
|
|
value: () => data.formSettings.logs.maxDays,
|
|
oninput: (e) => (data.formSettings.logs.maxDays = e.target.value << 0),
|
|
}),
|
|
),
|
|
t.div(
|
|
{ className: "field-help" },
|
|
"Set to ",
|
|
t.code(null, 0),
|
|
" to delete all logs and disable logs persistence.",
|
|
),
|
|
),
|
|
t.div(
|
|
{ className: "col-lg-12" },
|
|
t.field(
|
|
{ className: "field" },
|
|
t.label({ htmlFor: "logs.minLevel" }, "Min log level"),
|
|
t.input({
|
|
type: "number",
|
|
id: "logs.minLevel",
|
|
name: "logs.minLevel",
|
|
min: -100,
|
|
max: 100,
|
|
required: true,
|
|
value: () => data.formSettings.logs.minLevel,
|
|
oninput: (e) => (data.formSettings.logs.minLevel = e.target.value << 0),
|
|
}),
|
|
),
|
|
t.div(
|
|
{ className: "field-help" },
|
|
t.div(null, "Logs with level below the minimum will be ignored."),
|
|
defaultLogLevels(),
|
|
),
|
|
),
|
|
t.div(
|
|
{ className: "col-lg-12" },
|
|
t.field(
|
|
{ className: "field" },
|
|
t.label(
|
|
{ htmlFor: "logs.maxDataSize" },
|
|
t.span({ className: "txt" }, "Max data size"),
|
|
t.small(null, "(bytes)"),
|
|
t.i({
|
|
className: "ri-information-line link-hint",
|
|
ariaDescription: app.attrs.tooltip(
|
|
`The max size in bytes of the serialized log JSON data field (truncated on "best-effort" basis).`,
|
|
),
|
|
}),
|
|
),
|
|
t.input({
|
|
type: "number",
|
|
id: "logs.maxDataSize",
|
|
name: "logs.maxDataSize",
|
|
min: 0,
|
|
max: Number.MAX_SAFE_INTEGER,
|
|
placeholder: "Default to ~16KB",
|
|
value: () => data.formSettings.logs.maxDataSize || "",
|
|
oninput: (e) => {
|
|
if (e.target.value <= 0) {
|
|
data.formSettings.logs.maxDataSize = 0;
|
|
} else {
|
|
data.formSettings.logs.maxDataSize = Number(e.target.value);
|
|
}
|
|
},
|
|
onchange: () => {
|
|
// force placeholder rendering
|
|
if (!data.formSettings.logs.maxDataSize) {
|
|
data.formSettings.logs.maxDataSize = null;
|
|
data.formSettings.logs.maxDataSize = 0;
|
|
}
|
|
},
|
|
}),
|
|
),
|
|
),
|
|
t.div(
|
|
{ className: "col-lg-12" },
|
|
t.field(
|
|
{ className: "field" },
|
|
t.input({
|
|
type: "checkbox",
|
|
id: "logs.logIP",
|
|
name: "logs.logIP",
|
|
className: "switch",
|
|
checked: () => data.formSettings.logs.logIP,
|
|
onchange: (e) => (data.formSettings.logs.logIP = e.target.checked),
|
|
}),
|
|
t.label({ htmlFor: "logs.logIP" }, "Enable IP logging"),
|
|
),
|
|
),
|
|
t.div(
|
|
{ className: "col-lg-12" },
|
|
t.field(
|
|
{ className: "field" },
|
|
t.input({
|
|
type: "checkbox",
|
|
id: "logs.logAuthId",
|
|
name: "logs.logAuthId",
|
|
className: "switch",
|
|
checked: () => data.formSettings.logs.logAuthId,
|
|
onchange: (e) => (data.formSettings.logs.logAuthId = e.target.checked),
|
|
}),
|
|
t.label({ htmlFor: "logs.logAuthId" }, "Enable Auth Id logging"),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
t.footer(
|
|
{ className: "modal-footer" },
|
|
t.button(
|
|
{
|
|
type: "button",
|
|
className: "btn transparent m-r-auto",
|
|
onclick: () => app.modals.close(modal),
|
|
disabled: () => data.isSaving,
|
|
},
|
|
t.span({ className: "txt" }, "Close"),
|
|
),
|
|
t.button(
|
|
{
|
|
type: "button",
|
|
ariaLabel: app.attrs.tooltip("Delete all logs", "left"),
|
|
className: () =>
|
|
`btn circle sm secondary transparent link-faded ${data.isDeleting ? "loading" : ""}`,
|
|
disabled: () => data.isDeleting || data.isSaving,
|
|
onclick: () => {
|
|
confirmLogsDelete();
|
|
},
|
|
},
|
|
t.i({ className: "ri-delete-bin-7-line", ariaHidden: true }),
|
|
),
|
|
t.button(
|
|
{
|
|
type: "submit",
|
|
"html-form": "logsSettingsForm",
|
|
className: () => `btn ${data.isSaving ? "loading" : ""}`,
|
|
disabled: () => !data.hasChanges || data.isSaving,
|
|
},
|
|
t.span({ className: "txt" }, "Save changes"),
|
|
),
|
|
),
|
|
];
|
|
},
|
|
);
|
|
|
|
return modal;
|
|
}
|