@oktis-works/admin 0.4.13 → 0.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/_astro/{ActivityWidget.DeayROhc.js → ActivityWidget.C2ETg6u_.js} +2 -2
- package/dist/client/_astro/AdminBar.Dc_oT_my.js +234 -0
- package/dist/client/_astro/{AtGlanceWidget.CDFVi_eX.js → AtGlanceWidget.BVCJB3QT.js} +3 -3
- package/dist/client/_astro/BaseLayout.B3A9-IS6.css +1 -0
- package/dist/client/_astro/ContentEditor.CoCaseap.js +1 -0
- package/dist/client/_astro/ContentList.Qp90yZEx.js +1 -0
- package/dist/client/_astro/CustomFieldsManager.B2JEuxBb.js +3 -0
- package/dist/client/_astro/DashboardHome.CgDrZavo.js +1 -0
- package/dist/client/_astro/DashboardLayout.CEvRGr78.css +1 -0
- package/dist/client/_astro/DashboardLayout.astro_astro_type_script_index_0_lang.nXh9K0OY.js +1 -0
- package/dist/client/_astro/FieldTypePicker.BEuYPzV8.js +1 -0
- package/dist/client/_astro/{Footer.KkyZkNxH.js → Footer.BpxMjlJE.js} +3 -5
- package/dist/client/_astro/GeneralSettings.BVFwXCbR.js +1 -0
- package/dist/client/_astro/MediaLibrary.CGzXvUbD.js +1 -0
- package/dist/client/_astro/PluginManager.CQW7_Hl-.js +93 -0
- package/dist/client/_astro/PostTypesManager.CFX0sR5p.js +1 -0
- package/dist/client/_astro/{QuickDraftWidget.Drp_cL_D.js → QuickDraftWidget.DLaU-WiG.js} +2 -2
- package/dist/client/_astro/ResourceHubs.DasaSiMK.js +1 -0
- package/dist/client/_astro/TaxonomiesManager.CralM7Ne.js +1 -0
- package/dist/client/_astro/ThemeManager.C9mBa-po.js +129 -0
- package/dist/client/_astro/UserCreateForm.D6rRUn0J.js +1 -0
- package/dist/client/_astro/UsersManager.DdpgI0mN.js +1 -0
- package/dist/client/_astro/api.CDW61rqX.js +1 -0
- package/dist/client/_astro/ar.DsV0P0EN.js +1 -0
- package/dist/client/_astro/{client.C7p516_9.js → client.BY0Z100j.js} +1 -1
- package/dist/client/_astro/custom-fields.IjuRIdAC.css +1 -0
- package/dist/client/_astro/es-ES.etPSaiLd.js +1 -0
- package/dist/client/_astro/extensions.roNfOg-_.js +1 -0
- package/dist/client/_astro/he.U1Vtp3zT.js +1 -0
- package/dist/client/_astro/i18n.D0KNEGgP.js +1 -0
- package/dist/client/_astro/it.DJuI8oO_.js +1 -0
- package/dist/client/_astro/ja.Cw8I_NUV.js +1 -0
- package/dist/client/_astro/{login.astro_astro_type_script_index_0_lang.D6nHqYm6.js → login.astro_astro_type_script_index_0_lang.CdYoT76J.js} +1 -1
- package/dist/client/_astro/pl.Dsz-4G_z.js +1 -0
- package/dist/client/_astro/pt-BR.CyQAHnXs.js +1 -0
- package/dist/client/_astro/ru.CwIIcTdy.js +1 -0
- package/dist/client/_astro/src.DyLYQxi2.js +1 -0
- package/dist/client/_astro/sw.DwpL3sb6.js +1 -0
- package/dist/client/_astro/tr.CY2JWJ7Y.js +1 -0
- package/dist/client/_astro/uk.BudEWIU8.js +1 -0
- package/dist/client/_astro/{version.C0f0jrCn.js → version.CoiXQYz6.js} +1 -1
- package/dist/client/_astro/{web.D1H9RxZL.js → web.D_vCtCLj.js} +1 -1
- package/dist/client/_astro/yo.BmoZs0fO.js +1 -0
- package/dist/client/_astro/zh-CN.khaXV6fv.js +1 -0
- package/dist/server/chunks/{ContentEditor_BtclxOqH.mjs → ContentEditor_Dtmf4Zk6.mjs} +31 -101
- package/dist/server/chunks/{DashboardLayout_B9pE8ZBQ.mjs → DashboardLayout_DnE23ArY.mjs} +50 -563
- package/dist/server/chunks/FieldTypePicker_CXwpmcQ3.mjs +79 -0
- package/dist/server/chunks/{MediaLibrary_DLO2K_4d.mjs → MediaLibrary_CKvvgCI6.mjs} +2 -2
- package/dist/server/chunks/ResourceHubs_Aoy5L4qj.mjs +453 -0
- package/dist/server/chunks/{_slug__yqDK_Ow8.mjs → _slug__DtzYz9Uz.mjs} +1 -1
- package/dist/server/chunks/access_BNFcmbp2.mjs +34 -0
- package/dist/server/chunks/{ar_DBjdWIJ0.mjs → ar_DMC8HaoP.mjs} +3 -1
- package/dist/server/chunks/custom-fields_90Jyw521.mjs +488 -0
- package/dist/server/chunks/{edit_0bCUPzfW.mjs → edit_BmWxJDZa.mjs} +2 -2
- package/dist/server/chunks/{es-ES_TJ4oK1yi.mjs → es-ES_DZvHskAD.mjs} +3 -1
- package/dist/server/chunks/{general_D-MMl9p8.mjs → general_AGjbJVe-.mjs} +6 -6
- package/dist/server/chunks/{he_TWsuTphz.mjs → he_zy3stNhR.mjs} +3 -1
- package/dist/server/chunks/i18n_Csb4GGX2.mjs +1326 -0
- package/dist/server/chunks/{index_CTpEX5iK.mjs → index_BKm7s1bn.mjs} +2 -2
- package/dist/server/chunks/{index_CALAZTDB.mjs → index_C7yZO-zD.mjs} +2 -2
- package/dist/server/chunks/{index_Z7GukanS.mjs → index_CUsSNKEq.mjs} +8 -6
- package/dist/server/chunks/{index_DB6MLU0v.mjs → index_D5IP16pU.mjs} +3 -3
- package/dist/server/chunks/{index_Bq7o-ZHF.mjs → index_b00ttelz.mjs} +1 -1
- package/dist/server/chunks/{it_CEVFVWh1.mjs → it_BiUDLszZ.mjs} +3 -1
- package/dist/server/chunks/{ja_CqDirMqf.mjs → ja_DjFAG7hL.mjs} +3 -1
- package/dist/server/chunks/{login_BcWk_36h.mjs → login_lEEcbYs3.mjs} +1 -1
- package/dist/server/chunks/{new_BbKoexYG.mjs → new_BDjFzd-l.mjs} +2 -2
- package/dist/server/chunks/{new_DlqbYYA1.mjs → new_BjtzqhsE.mjs} +2 -2
- package/dist/server/chunks/operations_D7TMl0mB.mjs +34 -0
- package/dist/server/chunks/{pl_ChIKxfZG.mjs → pl_0Xe9Qom2.mjs} +3 -1
- package/dist/server/chunks/{plugins_BLJAzLX4.mjs → plugins_KhRV7kiu.mjs} +46 -17
- package/dist/server/chunks/{post-types_BvVl0hZs.mjs → post-types_DfXwkNIg.mjs} +6 -6
- package/dist/server/chunks/{pt-BR_4d4jZWL0.mjs → pt-BR_DIZpU2Mk.mjs} +206 -2
- package/dist/server/chunks/resources_BbhlUSXs.mjs +34 -0
- package/dist/server/chunks/{ru_CIc6O5Q7.mjs → ru_DFvIxd0Y.mjs} +3 -1
- package/dist/server/chunks/{sw_Bs3iYVDM.mjs → sw_CmaPgGYa.mjs} +3 -1
- package/dist/server/chunks/{taxonomies_Dkx7d-vc.mjs → taxonomies_CF7qpKG3.mjs} +2 -2
- package/dist/server/chunks/themes_RAw8tJmy.mjs +151 -0
- package/dist/server/chunks/{tr_C7JbXuoQ.mjs → tr_B_acwl2e.mjs} +3 -1
- package/dist/server/chunks/{uk_Dibs8Wkc.mjs → uk_DXnk4imL.mjs} +3 -1
- package/dist/server/chunks/{upload_CpGGKDEH.mjs → upload_BBZ9ttmU.mjs} +2 -2
- package/dist/server/chunks/{yo_B6MPvz_U.mjs → yo_DDQ8a-0v.mjs} +3 -1
- package/dist/server/chunks/{zh-CN_G1Dc2b28.mjs → zh-CN_763uzTMQ.mjs} +3 -1
- package/dist/server/entry.mjs +149 -25
- package/dist/server/virtual_astro_middleware.mjs +6 -3
- package/package.json +1 -1
- package/dist/client/_astro/AdminBar.DQilvzQe.js +0 -234
- package/dist/client/_astro/BaseLayout.B2MfKf6B.css +0 -1
- package/dist/client/_astro/ContentEditor.WyLHMY9o.js +0 -1
- package/dist/client/_astro/ContentList.BWtiYbDy.js +0 -1
- package/dist/client/_astro/DashboardHome.-0s3t1kG.js +0 -1
- package/dist/client/_astro/DashboardLayout.DWuCsemN.css +0 -1
- package/dist/client/_astro/DashboardLayout.astro_astro_type_script_index_0_lang.Bm7kqhGo.js +0 -1
- package/dist/client/_astro/GeneralSettings.CaEyAV2f.js +0 -1
- package/dist/client/_astro/HelpTabs.99giF0f1.js +0 -103
- package/dist/client/_astro/LanguageSelector.DPBYaSN4.js +0 -14
- package/dist/client/_astro/MediaLibrary.DBfw3BM0.js +0 -1
- package/dist/client/_astro/PluginManager.BFoAz05U.js +0 -93
- package/dist/client/_astro/PostTypesManager.y9aB2d3_.js +0 -1
- package/dist/client/_astro/ScreenOptions.C8K8Bufc.js +0 -70
- package/dist/client/_astro/TaxonomiesManager.Cj54HB7P.js +0 -1
- package/dist/client/_astro/ThemeManager.BuULAG8h.js +0 -124
- package/dist/client/_astro/UserCreateForm.BMWIRfb2.js +0 -1
- package/dist/client/_astro/UsersManager.BogkOfCQ.js +0 -1
- package/dist/client/_astro/api.PfLklAa1.js +0 -1
- package/dist/client/_astro/ar.CzsjUutD.js +0 -1
- package/dist/client/_astro/en.DmN7xy_a.js +0 -1
- package/dist/client/_astro/es-ES.p2TLEMlZ.js +0 -1
- package/dist/client/_astro/extensions.DfxrGzbo.js +0 -1
- package/dist/client/_astro/he.BnYHiYpn.js +0 -1
- package/dist/client/_astro/i18n.BMDVwjZM.js +0 -1
- package/dist/client/_astro/it.WrWKBEAD.js +0 -1
- package/dist/client/_astro/ja.DxnfhIdt.js +0 -1
- package/dist/client/_astro/pl.jUj-RfZS.js +0 -1
- package/dist/client/_astro/pt-BR.DtNwEO0i.js +0 -1
- package/dist/client/_astro/ru.KFSfdjWn.js +0 -1
- package/dist/client/_astro/src.Cgonpfb5.js +0 -1
- package/dist/client/_astro/sw.3jlAOLOv.js +0 -1
- package/dist/client/_astro/tr.tnLMnGPg.js +0 -1
- package/dist/client/_astro/uk.VquHY_xc.js +0 -1
- package/dist/client/_astro/yo.Cr8hCb5u.js +0 -1
- package/dist/client/_astro/zh-CN.E32QqP4v.js +0 -1
- package/dist/server/chunks/en_C750mYKk.mjs +0 -408
- package/dist/server/chunks/i18n_Dj2ieo-N.mjs +0 -548
- package/dist/server/chunks/themes_CCDPOhVZ.mjs +0 -127
- /package/dist/server/chunks/{BaseLayout_BsR68tOH.mjs → BaseLayout_4yJ0PQCS.mjs} +0 -0
|
@@ -2,22 +2,22 @@ import "./rolldown-runtime_BMI-E3GI.mjs";
|
|
|
2
2
|
import { S as createAstro, d as maybeRenderHead, i as renderComponent, p as addAttribute, s as renderSlot, u as renderTemplate } from "./server_B5N27szj.mjs";
|
|
3
3
|
import { t as createComponent$1 } from "./compiler_O7J1rlsi.mjs";
|
|
4
4
|
import { t as renderScript } from "./script_CPGt5jAh.mjs";
|
|
5
|
-
import { a as LOCALE_LABELS, i as LOCALE_FLAGS, n as useTranslation, o as SUPPORTED_LOCALES, r as apiClient } from "./
|
|
6
|
-
import { t as $$BaseLayout } from "./
|
|
5
|
+
import { a as LOCALE_LABELS, i as LOCALE_FLAGS, n as useTranslation, o as SUPPORTED_LOCALES, r as apiClient } from "./i18n_Csb4GGX2.mjs";
|
|
6
|
+
import { t as $$BaseLayout } from "./BaseLayout_4yJ0PQCS.mjs";
|
|
7
7
|
import { t as require_semver } from "./semver_WbqCUY_o.mjs";
|
|
8
|
-
import { createComponent, escape,
|
|
9
|
-
import { For, For as For2, Show, Show as Show2, createMemo as createMemo$1, createSignal, createSignal as createSignal$1,
|
|
8
|
+
import { createComponent, escape, ssr, ssrAttribute, ssrHydrationKey, ssrStyle } from "solid-js/web";
|
|
9
|
+
import { For, For as For2, Show, Show as Show2, createMemo as createMemo$1, createSignal, createSignal as createSignal$1, onMount, onMount as onMount$1 } from "solid-js";
|
|
10
10
|
require_semver();
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region ../../packages/ui/dist/server.js
|
|
13
|
-
var _tmpl$$
|
|
14
|
-
var _tmpl$2$
|
|
13
|
+
var _tmpl$$7 = ["<span", " class=\"spinner\" aria-label=\"Carregando\"></span>"];
|
|
14
|
+
var _tmpl$2$6 = [
|
|
15
15
|
"<button",
|
|
16
16
|
"",
|
|
17
17
|
">",
|
|
18
18
|
"</button>"
|
|
19
19
|
];
|
|
20
|
-
var _tmpl$3$
|
|
20
|
+
var _tmpl$3$4 = [
|
|
21
21
|
"<label",
|
|
22
22
|
" class=\"field__label\"><!--$-->",
|
|
23
23
|
"<!--/--><!--$-->",
|
|
@@ -26,7 +26,7 @@ var _tmpl$3$7 = [
|
|
|
26
26
|
"",
|
|
27
27
|
"></label>"
|
|
28
28
|
];
|
|
29
|
-
var _tmpl$4$
|
|
29
|
+
var _tmpl$4$4 = [
|
|
30
30
|
"<input",
|
|
31
31
|
" class=\"input\"",
|
|
32
32
|
"",
|
|
@@ -140,7 +140,7 @@ function Button(props) {
|
|
|
140
140
|
props.size === "sm" ? "btn-sm" : "",
|
|
141
141
|
props.class ?? ""
|
|
142
142
|
].filter(Boolean).join(" ");
|
|
143
|
-
return ssr(_tmpl$2$
|
|
143
|
+
return ssr(_tmpl$2$6, ssrHydrationKey() + ssrAttribute("type", escape(props.type ?? "button", true), false) + ssrAttribute("class", escape(classes(), true), false), ssrAttribute("disabled", props.disabled || props.loading, true), escape(createComponent(Show, {
|
|
144
144
|
get when() {
|
|
145
145
|
return props.loading;
|
|
146
146
|
},
|
|
@@ -148,7 +148,7 @@ function Button(props) {
|
|
|
148
148
|
return props.children;
|
|
149
149
|
},
|
|
150
150
|
get children() {
|
|
151
|
-
return ssr(_tmpl$$
|
|
151
|
+
return ssr(_tmpl$$7, ssrHydrationKey());
|
|
152
152
|
}
|
|
153
153
|
})));
|
|
154
154
|
}
|
|
@@ -158,14 +158,14 @@ function Input(props) {
|
|
|
158
158
|
return props.label;
|
|
159
159
|
},
|
|
160
160
|
get children() {
|
|
161
|
-
return ssr(_tmpl$3$
|
|
161
|
+
return ssr(_tmpl$3$4, ssrHydrationKey(), escape(props.label), props.required ? _tmpl$7$2[0] + ssrHydrationKey() + _tmpl$7$2[1] : escape(null), ssrAttribute("type", escape(props.type ?? "text", true), false) + ssrAttribute("name", escape(props.name, true), false) + ssrAttribute("value", escape(props.value ?? "", true), false) + ssrAttribute("placeholder", escape(props.placeholder, true), false), ssrAttribute("disabled", props.disabled, true), ssrAttribute("required", props.required, true));
|
|
162
162
|
}
|
|
163
163
|
})), escape(createComponent(Show, {
|
|
164
164
|
get when() {
|
|
165
165
|
return !props.label;
|
|
166
166
|
},
|
|
167
167
|
get children() {
|
|
168
|
-
return ssr(_tmpl$4$
|
|
168
|
+
return ssr(_tmpl$4$4, ssrHydrationKey(), ssrAttribute("type", escape(props.type ?? "text", true), false) + ssrAttribute("name", escape(props.name, true), false) + ssrAttribute("value", escape(props.value ?? "", true), false) + ssrAttribute("placeholder", escape(props.placeholder, true), false), ssrAttribute("disabled", props.disabled, true), ssrAttribute("required", props.required, true));
|
|
169
169
|
}
|
|
170
170
|
})), escape(createComponent(Show, {
|
|
171
171
|
get when() {
|
|
@@ -287,14 +287,14 @@ function Pagination(props) {
|
|
|
287
287
|
}
|
|
288
288
|
//#endregion
|
|
289
289
|
//#region src/ext/slots.tsx
|
|
290
|
-
var _tmpl$$
|
|
290
|
+
var _tmpl$$6 = [
|
|
291
291
|
"<a",
|
|
292
292
|
" href=\"",
|
|
293
293
|
"\" class=\"sidebar__link\"><!--$-->",
|
|
294
294
|
"<!--/--> <!--$-->",
|
|
295
295
|
"<!--/--></a>"
|
|
296
296
|
];
|
|
297
|
-
var _tmpl$2$
|
|
297
|
+
var _tmpl$2$5 = [
|
|
298
298
|
"<span",
|
|
299
299
|
" aria-hidden=\"true\">",
|
|
300
300
|
"</span>"
|
|
@@ -310,18 +310,18 @@ function AdminSidebarSlot(props) {
|
|
|
310
310
|
get each() {
|
|
311
311
|
return allowedPages();
|
|
312
312
|
},
|
|
313
|
-
children: (page) => ssr(_tmpl$$
|
|
313
|
+
children: (page) => ssr(_tmpl$$6, ssrHydrationKey(), `/plugins/${escape(page.slug, true)}`, page.icon ? ssr(_tmpl$2$5, ssrHydrationKey(), escape(page.icon)) : escape(null), escape(page.label))
|
|
314
314
|
});
|
|
315
315
|
}
|
|
316
316
|
//#endregion
|
|
317
317
|
//#region src/ext/extensions.tsx
|
|
318
|
-
var _tmpl$$
|
|
318
|
+
var _tmpl$$5 = [
|
|
319
319
|
"<div",
|
|
320
320
|
" class=\"sidebar-plugins\" data-extensions=\"sidebar\"><!--$-->",
|
|
321
321
|
"<!--/--><!--$-->",
|
|
322
322
|
"<!--/--></div>"
|
|
323
323
|
];
|
|
324
|
-
var _tmpl$2$
|
|
324
|
+
var _tmpl$2$4 = [
|
|
325
325
|
"<div",
|
|
326
326
|
" class=\"",
|
|
327
327
|
"\"",
|
|
@@ -344,7 +344,7 @@ function emptyExtensionsState() {
|
|
|
344
344
|
function extensionsFromPlugins(plugins) {
|
|
345
345
|
const state = emptyExtensionsState();
|
|
346
346
|
for (const plugin of plugins) {
|
|
347
|
-
if (plugin.status !== "ACTIVE") continue;
|
|
347
|
+
if (plugin.status !== "ACTIVE" && plugin.status !== "ACTIVATED") continue;
|
|
348
348
|
const admin = plugin.manifest?.admin;
|
|
349
349
|
if (!admin) continue;
|
|
350
350
|
const pluginSlug = plugin.slug ?? plugin.name;
|
|
@@ -369,9 +369,7 @@ function PluginExtensionsSlot() {
|
|
|
369
369
|
const [extensions, setExtensions] = createSignal$1(emptyExtensionsState());
|
|
370
370
|
onMount$1(async () => {
|
|
371
371
|
try {
|
|
372
|
-
const
|
|
373
|
-
if (!response.ok) return;
|
|
374
|
-
const plugins = await response.json();
|
|
372
|
+
const plugins = await apiClient.getPlugins();
|
|
375
373
|
setExtensions(extensionsFromPlugins(plugins));
|
|
376
374
|
} catch {}
|
|
377
375
|
});
|
|
@@ -381,11 +379,11 @@ function PluginExtensionsSlot() {
|
|
|
381
379
|
return extensions().menuPages.length > 0;
|
|
382
380
|
},
|
|
383
381
|
get children() {
|
|
384
|
-
return ssr(_tmpl$$
|
|
382
|
+
return ssr(_tmpl$$5, ssrHydrationKey(), escape(createComponent(For2, {
|
|
385
383
|
get each() {
|
|
386
384
|
return extensions().notices;
|
|
387
385
|
},
|
|
388
|
-
children: (notice) => ssr(_tmpl$2$
|
|
386
|
+
children: (notice) => ssr(_tmpl$2$4, ssrHydrationKey(), `notice notice--${escape(notice.level, true)}`, ssrAttribute("data-plugin", escape(notice.id.split(":")[0], true), false), escape(notice.message))
|
|
389
387
|
})), escape(createComponent(AdminSidebarSlot, {
|
|
390
388
|
get extensions() {
|
|
391
389
|
return extensions();
|
|
@@ -396,69 +394,21 @@ function PluginExtensionsSlot() {
|
|
|
396
394
|
});
|
|
397
395
|
}
|
|
398
396
|
//#endregion
|
|
399
|
-
//#region src/components/LanguageSelector.tsx
|
|
400
|
-
var _tmpl$$7 = [
|
|
401
|
-
"<ul",
|
|
402
|
-
" class=\"language-dropdown\" role=\"menu\"",
|
|
403
|
-
">",
|
|
404
|
-
"</ul>"
|
|
405
|
-
];
|
|
406
|
-
var _tmpl$2$6 = [
|
|
407
|
-
"<div",
|
|
408
|
-
" class=\"language-selector\"><button class=\"btn btn-secondary btn-sm language-trigger\"",
|
|
409
|
-
" type=\"button\"><span class=\"flag\">",
|
|
410
|
-
"</span><span>",
|
|
411
|
-
"</span><svg class=\"chevron\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\"></path></svg></button><!--$-->",
|
|
412
|
-
"<!--/--><style>\n .language-selector { position: relative; }\n .language-trigger { display: flex; align-items: center; gap: 0.5rem; padding: 0.375rem 0.75rem; min-width: 140px; justify-content: space-between; }\n .language-trigger .flag { font-size: 1rem; }\n .language-trigger .chevron { flex-shrink: 0; transition: transform 0.15s; }\n .language-trigger[aria-expanded=\"true\"] .chevron { transform: rotate(180deg); }\n .language-dropdown { position: absolute; top: calc(100% + 0.25rem); right: 0; z-index: 100; background: var(--color-bg-secondary); border: 1px solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); min-width: 160px; overflow: hidden; animation: dropdown-in 0.1s ease-out; }\n @keyframes dropdown-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }\n .language-dropdown li { list-style: none; }\n .language-dropdown button { width: 100%; display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; background: none; border: none; text-align: left; color: var(--color-text); cursor: pointer; }\n .language-dropdown button:hover { background: var(--color-bg-tertiary); }\n .language-dropdown button.active { background: var(--color-primary); color: var(--color-primary-contrast); font-weight: 500; }\n .language-dropdown .flag { font-size: 1rem; }\n </style></div>"
|
|
413
|
-
];
|
|
414
|
-
var _tmpl$3$6 = [
|
|
415
|
-
"<li",
|
|
416
|
-
" role=\"menuitem\"><button",
|
|
417
|
-
" type=\"button\"><span class=\"flag\">",
|
|
418
|
-
"</span><!--$-->",
|
|
419
|
-
"<!--/--></button></li>"
|
|
420
|
-
];
|
|
421
|
-
function LanguageSelector() {
|
|
422
|
-
const { locale, changeLocale, t } = useTranslation();
|
|
423
|
-
const [open, setOpen] = createSignal(false);
|
|
424
|
-
const handleClickOutside = (e) => {
|
|
425
|
-
if (!e.target.closest(".language-selector")) setOpen(false);
|
|
426
|
-
};
|
|
427
|
-
onMount(() => {
|
|
428
|
-
if (isServer) return;
|
|
429
|
-
document.addEventListener("click", handleClickOutside);
|
|
430
|
-
});
|
|
431
|
-
onCleanup(() => {
|
|
432
|
-
if (isServer) return;
|
|
433
|
-
document.removeEventListener("click", handleClickOutside);
|
|
434
|
-
});
|
|
435
|
-
const currentLocale = locale;
|
|
436
|
-
const translate = t;
|
|
437
|
-
return ssr(_tmpl$2$6, ssrHydrationKey(), ssrAttribute("aria-expanded", escape(open(), true), false) + ssrAttribute("aria-label", escape(translate("common.language") ?? "Language", true), false), escape(LOCALE_FLAGS[currentLocale] ?? "🌐"), escape(LOCALE_LABELS[currentLocale] ?? currentLocale), escape(createComponent(Show, {
|
|
438
|
-
get when() {
|
|
439
|
-
return open();
|
|
440
|
-
},
|
|
441
|
-
get children() {
|
|
442
|
-
return ssr(_tmpl$$7, ssrHydrationKey(), ssrAttribute("aria-label", escape(translate("common.language") ?? "Language", true), false), escape(SUPPORTED_LOCALES.map((loc) => ssr(_tmpl$3$6, ssrHydrationKey(), ssrAttribute("class", currentLocale === loc ? "active" : "", false), escape(LOCALE_FLAGS[loc] ?? "🌐"), escape(LOCALE_LABELS[loc] ?? loc)))));
|
|
443
|
-
}
|
|
444
|
-
})));
|
|
445
|
-
}
|
|
446
|
-
//#endregion
|
|
447
397
|
//#region src/components/admin-bar/AdminBar.tsx
|
|
448
|
-
var _tmpl$$
|
|
449
|
-
var _tmpl$2$
|
|
398
|
+
var _tmpl$$4 = ["<style", ">\n #admin-bar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 46px;\n background: #0A0A0A;\n border-bottom: 1px solid #333;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 1rem;\n z-index: 2000;\n font-family: inherit;\n }\n #admin-bar * { box-sizing: border-box; }\n .admin-bar-left, .admin-bar-right {\n display: flex;\n align-items: center;\n gap: 1rem;\n }\n .admin-bar-brand {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #FAF5E8;\n font-weight: 600;\n font-size: 1.125rem;\n text-decoration: none;\n padding: 0.375rem 0.75rem;\n border-radius: 0.375rem;\n transition: background 0.15s;\n }\n .admin-bar-brand:hover {\n background: rgba(255,255,255,0.08);\n }\n .admin-bar-brand svg { width: 28px; height: 28px; }\n .admin-bar-separator { width: 1px; height: 24px; background: #333; }\n .admin-bar-menu { display: flex; gap: 0.25rem; }\n .admin-bar-menu-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.375rem 0.75rem;\n color: rgba(255,255,255,0.7);\n font-size: 0.8125rem;\n font-weight: 500;\n border-radius: 0.375rem;\n text-decoration: none;\n transition: all 0.15s;\n }\n .admin-bar-menu-item:hover {\n background: rgba(255,255,255,0.1);\n color: #fff;\n }\n .admin-bar-menu-item svg { width: 18px; height: 18px; }\n .admin-bar-right { gap: 0.75rem; }\n .notifications-btn {\n position: relative;\n background: none;\n border: none;\n color: rgba(255,255,255,0.7);\n padding: 0.375rem;\n border-radius: 0.375rem;\n cursor: pointer;\n transition: all 0.15s;\n }\n .notifications-btn:hover { background: rgba(255,255,255,0.1); color: #fff; }\n .notifications-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n background: #EF4444;\n color: #fff;\n font-size: 0.625rem;\n font-weight: 600;\n border-radius: 9999px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n }\n .notifications-dropdown { position: relative; }\n .notifications-panel {\n position: absolute;\n top: calc(100% + 0.5rem);\n right: 0;\n min-width: 280px;\n max-width: 90vw;\n background: #FFFFFF;\n border: 1px solid #DCDCDE;\n border-radius: 0.5rem;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n z-index: 2100;\n overflow: hidden;\n animation: slideIn 0.15s ease-out;\n }\n .notifications-header {\n padding: 0.75rem 1rem;\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: #646970;\n border-bottom: 1px solid #DCDCDE;\n }\n .notifications-item {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n padding: 0.625rem 1rem;\n border-bottom: 1px solid #F6F7F7;\n }\n .notifications-item:last-child { border-bottom: none; }\n .notifications-action {\n font-size: 0.8125rem;\n font-weight: 600;\n color: #2C3338;\n font-family: ui-monospace, SFMono-Regular, monospace;\n word-break: break-word;\n }\n .notifications-meta {\n display: flex;\n justify-content: space-between;\n gap: 0.75rem;\n font-size: 0.6875rem;\n color: #646970;\n }\n .notifications-empty { padding: 1rem; margin: 0; font-size: 0.8125rem; color: #646970; }\n .user-menu-trigger {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: none;\n border: none;\n color: #fff;\n padding: 0.375rem 0.75rem;\n border-radius: 0.375rem;\n cursor: pointer;\n font-size: 0.8125rem;\n font-weight: 500;\n transition: background 0.15s;\n }\n .user-menu-trigger:hover { background: rgba(255,255,255,0.1); }\n .user-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(135deg, #D8B45E 0%, #B99542 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 0.875rem;\n color: #0A0A0A;\n }\n .user-menu-dropdown {\n position: absolute;\n top: calc(100% + 0.5rem);\n right: 0;\n min-width: 200px;\n background: #FFFFFF;\n border: 1px solid #DCDCDE;\n border-radius: 0.5rem;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n z-index: 2100;\n overflow: hidden;\n animation: slideIn 0.15s ease-out;\n }\n @keyframes slideIn { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } }\n .user-menu-header {\n padding: 1rem;\n border-bottom: 1px solid #DCDCDE;\n }\n .user-menu-name { font-weight: 600; color: #0A0A0A; font-size: 0.875rem; }\n .user-menu-email { color: #646970; font-size: 0.75rem; margin-top: 0.125rem; }\n .user-menu-divider { height: 1px; background: #DCDCDE; }\n .user-menu-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.625rem 1rem;\n background: none;\n border: none;\n color: #2C3338;\n font-size: 0.8125rem;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n transition: background 0.15s;\n }\n .user-menu-item:hover { background: #F6F7F7; }\n .user-menu-item svg { width: 18px; height: 18px; color: #646970; }\n .user-menu-item.danger { color: #EF4444; }\n .user-menu-item.danger:hover { background: #FEF2F2; }\n .lang-menu-dropdown {\n position: absolute;\n top: calc(100% + 0.5rem);\n right: 0;\n min-width: 180px;\n background: #FFFFFF;\n border: 1px solid #DCDCDE;\n border-radius: 0.5rem;\n box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);\n z-index: 2100;\n overflow: hidden;\n animation: slideIn 0.15s ease-out;\n }\n @keyframes slideIn { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } }\n .lang-menu-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.625rem 1rem;\n background: none;\n border: none;\n color: #2C3338;\n font-size: 0.8125rem;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n }\n .lang-menu-item:hover { background: #F6F7F7; }\n .lang-menu-item.active { background: #FAF5E8; color: #B99542; font-weight: 600; }\n .lang-menu-item .flag { font-size: 1rem; }\n @media (max-width: 782px) {\n .admin-bar-menu { display: none; }\n }\n </style>"];
|
|
399
|
+
var _tmpl$2$3 = [
|
|
450
400
|
"<span",
|
|
451
401
|
" class=\"notifications-badge\">",
|
|
452
402
|
"</span>"
|
|
453
403
|
];
|
|
454
|
-
var _tmpl$3$
|
|
404
|
+
var _tmpl$3$3 = [
|
|
455
405
|
"<div",
|
|
456
406
|
" class=\"notifications-panel\" role=\"menu\"",
|
|
457
407
|
"><div class=\"notifications-header\">",
|
|
458
408
|
"</div><!--$-->",
|
|
459
409
|
"<!--/--></div>"
|
|
460
410
|
];
|
|
461
|
-
var _tmpl$4$
|
|
411
|
+
var _tmpl$4$3 = [
|
|
462
412
|
"<div",
|
|
463
413
|
" class=\"lang-menu-dropdown\" role=\"menu\"",
|
|
464
414
|
">",
|
|
@@ -577,19 +527,19 @@ function AdminBar(props) {
|
|
|
577
527
|
year: "numeric"
|
|
578
528
|
});
|
|
579
529
|
};
|
|
580
|
-
return [ssr(_tmpl$$
|
|
530
|
+
return [ssr(_tmpl$$4, ssrHydrationKey()), ssr(_tmpl$8$1, ssrHydrationKey(), ssrAttribute("aria-label", escape(t("layout.appName"), true), false), ssrAttribute("aria-label", escape(t("adminBar.mainMenu"), true), false), escape(t("layout.nav.content")), escape(t("layout.nav.media")), escape(t("layout.nav.settings")), ssrAttribute("aria-label", escape(t("adminBar.notifications"), true), false) + ssrAttribute("aria-expanded", escape(showNotifications(), true), false), escape(createComponent(Show, {
|
|
581
531
|
get when() {
|
|
582
532
|
return notifications().length > 0;
|
|
583
533
|
},
|
|
584
534
|
get children() {
|
|
585
|
-
return ssr(_tmpl$2$
|
|
535
|
+
return ssr(_tmpl$2$3, ssrHydrationKey(), escape(notifications().length));
|
|
586
536
|
}
|
|
587
537
|
})), escape(createComponent(Show, {
|
|
588
538
|
get when() {
|
|
589
539
|
return showNotifications();
|
|
590
540
|
},
|
|
591
541
|
get children() {
|
|
592
|
-
return ssr(_tmpl$3$
|
|
542
|
+
return ssr(_tmpl$3$3, ssrHydrationKey(), ssrAttribute("aria-label", escape(t("adminBar.notifications"), true), false), escape(t("adminBar.notifications")), escape(createComponent(Show, {
|
|
593
543
|
get when() {
|
|
594
544
|
return notifications().length > 0;
|
|
595
545
|
},
|
|
@@ -606,7 +556,7 @@ function AdminBar(props) {
|
|
|
606
556
|
return showLangMenu();
|
|
607
557
|
},
|
|
608
558
|
get children() {
|
|
609
|
-
return ssr(_tmpl$4$
|
|
559
|
+
return ssr(_tmpl$4$3, ssrHydrationKey(), ssrAttribute("aria-label", escape(t("common.language"), true), false), escape(SUPPORTED_LOCALES.map((loc) => ssr(_tmpl$1, ssrHydrationKey() + ssrAttribute("class", currentLocale === loc ? "lang-menu-item active" : "lang-menu-item", false), escape(LOCALE_FLAGS[loc] ?? "🌐"), escape(LOCALE_LABELS[loc] ?? loc)))));
|
|
610
560
|
}
|
|
611
561
|
})), escape(createComponent(Show, {
|
|
612
562
|
get when() {
|
|
@@ -632,438 +582,11 @@ function AdminBar(props) {
|
|
|
632
582
|
})), ssrAttribute("aria-label", escape(t("adminBar.toggleSidebar"), true), false))];
|
|
633
583
|
}
|
|
634
584
|
//#endregion
|
|
635
|
-
//#region src/components/screen-options/ScreenOptions.tsx
|
|
636
|
-
var _tmpl$$5 = [
|
|
637
|
-
"<div",
|
|
638
|
-
" class=\"screen-options-panel\" role=\"region\"",
|
|
639
|
-
"><div class=\"screen-options-header\"><h3>",
|
|
640
|
-
"</h3><button class=\"screen-options-close\"",
|
|
641
|
-
" type=\"button\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg></button></div><div class=\"screen-options-content\"><fieldset><legend>",
|
|
642
|
-
"</legend><div class=\"screen-options-checkboxes\">",
|
|
643
|
-
"</div></fieldset><div class=\"screen-options-footer\"><button class=\"btn btn-primary\">",
|
|
644
|
-
"</button></div></div></div>"
|
|
645
|
-
];
|
|
646
|
-
var _tmpl$2$4 = [
|
|
647
|
-
"<div",
|
|
648
|
-
" class=\"screen-options\"><button class=\"screen-options-trigger\"",
|
|
649
|
-
" type=\"button\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"></path></svg><span>",
|
|
650
|
-
"</span><svg class=\"chevron\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"></path></svg></button><!--$-->",
|
|
651
|
-
"<!--/--></div>"
|
|
652
|
-
];
|
|
653
|
-
var _tmpl$3$4 = ["<style", ">\n .screen-options { position: relative; }\n .screen-options-trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.375rem 0.75rem;\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n color: var(--color-text);\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n }\n .screen-options-trigger:hover {\n background: var(--color-surface-hover);\n border-color: var(--color-primary);\n }\n .screen-options-trigger .chevron {\n transition: transform 0.15s;\n flex-shrink: 0;\n }\n .screen-options-trigger[aria-expanded=\"true\"] .chevron {\n transform: rotate(180deg);\n }\n .screen-options-panel {\n position: absolute;\n top: calc(100% + 0.5rem);\n right: 0;\n min-width: 280px;\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-xl);\n z-index: 1000;\n animation: slideIn 0.15s ease-out;\n }\n @keyframes slideIn { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } }\n .screen-options-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid var(--color-border);\n }\n .screen-options-header h3 { font-size: 0.875rem; font-weight: 600; }\n .screen-options-close {\n background: none; border: none; padding: 0.25rem;\n color: var(--color-muted); cursor: pointer; border-radius: var(--radius-sm);\n }\n .screen-options-close:hover { background: var(--color-background); color: var(--color-text); }\n .screen-options-content { padding: 1rem; }\n .screen-options-content fieldset { border: none; margin: 0; padding: 0; }\n .screen-options-content legend {\n font-size: 0.75rem; font-weight: 600; text-transform: uppercase;\n color: var(--color-muted); letter-spacing: 0.04em; margin-bottom: 0.75rem;\n }\n .screen-options-checkboxes { display: flex; flex-direction: column; gap: 0.5rem; }\n .screen-options-checkbox {\n display: flex; align-items: center; gap: 0.5rem;\n padding: 0.5rem; border-radius: var(--radius-md);\n cursor: pointer; transition: background 0.15s;\n }\n .screen-options-checkbox:hover { background: var(--color-background); }\n .screen-options-checkbox input { width: 16px; height: 16px; accent-color: var(--color-primary); }\n .screen-options-checkbox span { font-size: 0.8125rem; color: var(--color-text); }\n .screen-options-footer { display: flex; justify-content: flex-end; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--color-border); }\n </style>"];
|
|
654
|
-
var _tmpl$4$4 = [
|
|
655
|
-
"<label",
|
|
656
|
-
" class=\"screen-options-checkbox\"><input type=\"checkbox\"",
|
|
657
|
-
"><span>",
|
|
658
|
-
"</span></label>"
|
|
659
|
-
];
|
|
660
|
-
var STORAGE_KEY = "screen-options";
|
|
661
|
-
/** Preferências salvas (localStorage) — precedem o default do painel. */
|
|
662
|
-
function loadPrefs() {
|
|
663
|
-
try {
|
|
664
|
-
return JSON.parse(localStorage.getItem(STORAGE_KEY) ?? "{}");
|
|
665
|
-
} catch {
|
|
666
|
-
return {};
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
function ScreenOptions(props) {
|
|
670
|
-
const { t } = useTranslation();
|
|
671
|
-
const [open, setOpen] = createSignal(false);
|
|
672
|
-
const [enabled, setEnabled] = createSignal({
|
|
673
|
-
...Object.fromEntries(props.panels.map((p) => [p.id, p.defaultOpen !== false])),
|
|
674
|
-
...loadPrefs()
|
|
675
|
-
});
|
|
676
|
-
const handleClickOutside = (e) => {
|
|
677
|
-
if (!e.target.closest(".screen-options")) setOpen(false);
|
|
678
|
-
};
|
|
679
|
-
onMount(() => {
|
|
680
|
-
if (isServer) return;
|
|
681
|
-
document.addEventListener("click", handleClickOutside);
|
|
682
|
-
});
|
|
683
|
-
onCleanup(() => {
|
|
684
|
-
if (isServer) return;
|
|
685
|
-
document.removeEventListener("click", handleClickOutside);
|
|
686
|
-
});
|
|
687
|
-
return [ssr(_tmpl$2$4, ssrHydrationKey(), ssrAttribute("aria-expanded", escape(open(), true), false) + ssrAttribute("aria-label", escape(t("screenOptions.label"), true), false), escape(t("screenOptions.title")), escape(createComponent(Show, {
|
|
688
|
-
get when() {
|
|
689
|
-
return open();
|
|
690
|
-
},
|
|
691
|
-
get children() {
|
|
692
|
-
return ssr(_tmpl$$5, ssrHydrationKey(), ssrAttribute("aria-label", escape(t("screenOptions.title"), true), false), escape(t("screenOptions.title")), ssrAttribute("aria-label", escape(t("common.close"), true), false), escape(t("screenOptions.showOnScreen")), escape(props.panels.map((panel) => ssr(_tmpl$4$4, ssrHydrationKey(), ssrAttribute("checked", enabled()[panel.id] ?? panel.defaultOpen !== false, true), escape(panel.label)))), escape(t("common.close")));
|
|
693
|
-
}
|
|
694
|
-
}))), ssr(_tmpl$3$4, ssrHydrationKey())];
|
|
695
|
-
}
|
|
696
|
-
//#endregion
|
|
697
|
-
//#region src/lib/sanitize.ts
|
|
698
|
-
/**
|
|
699
|
-
* Sanitizador de HTML em allowlist para pontos de injeção (innerHTML).
|
|
700
|
-
*
|
|
701
|
-
* O admin injeta HTML apenas no conteúdo das abas de ajuda (HelpTabs), que
|
|
702
|
-
* vem do i18n — mas todo innerHTML passa por aqui por defesa em profundidade.
|
|
703
|
-
*
|
|
704
|
-
* Garantias:
|
|
705
|
-
* - Allowlist de tags e atributos (script/style/svg/iframe/form são removidos,
|
|
706
|
-
* incluindo o conteúdo de tags de texto bruto como <script> e <style>).
|
|
707
|
-
* - Atributos de evento (on*), style e demais fora da allowlist são descartados.
|
|
708
|
-
* - href/src têm o protocolo validado DEPOIS de decodificar entidades e remover
|
|
709
|
-
* tab/newline — o valor emitido é re-escapado a partir do valor decodificado,
|
|
710
|
-
* de modo que o que o navegador decodifica é exatamente o que foi validado
|
|
711
|
-
* (bloqueia `javascript:`, `javascript:`, `javascript:`, etc).
|
|
712
|
-
* - Texto é escapado (& < >), preservando entidades já válidas.
|
|
713
|
-
* - Tags de fechamento sem âncora são ignoradas: conteúdo malicioso não consegue
|
|
714
|
-
* "escapar" do container nem desbalancear a árvore (o quebra-cabeça de abas
|
|
715
|
-
* e widgets continua íntegro).
|
|
716
|
-
*
|
|
717
|
-
* Puro JavaScript, sem APIs de DOM: roda igual no SSR (Node) e no navegador.
|
|
718
|
-
*/
|
|
719
|
-
/** Tags permitidas (conteúdo rico simples: ajuda, títulos, listas, links). */
|
|
720
|
-
var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
721
|
-
"a",
|
|
722
|
-
"abbr",
|
|
723
|
-
"b",
|
|
724
|
-
"blockquote",
|
|
725
|
-
"br",
|
|
726
|
-
"code",
|
|
727
|
-
"dd",
|
|
728
|
-
"div",
|
|
729
|
-
"dl",
|
|
730
|
-
"dt",
|
|
731
|
-
"em",
|
|
732
|
-
"figcaption",
|
|
733
|
-
"figure",
|
|
734
|
-
"h1",
|
|
735
|
-
"h2",
|
|
736
|
-
"h3",
|
|
737
|
-
"h4",
|
|
738
|
-
"h5",
|
|
739
|
-
"h6",
|
|
740
|
-
"hr",
|
|
741
|
-
"i",
|
|
742
|
-
"img",
|
|
743
|
-
"li",
|
|
744
|
-
"ol",
|
|
745
|
-
"p",
|
|
746
|
-
"pre",
|
|
747
|
-
"q",
|
|
748
|
-
"s",
|
|
749
|
-
"span",
|
|
750
|
-
"strong",
|
|
751
|
-
"sub",
|
|
752
|
-
"sup",
|
|
753
|
-
"u",
|
|
754
|
-
"ul"
|
|
755
|
-
]);
|
|
756
|
-
/** Tags vazias (emitidas com fechamento próprio, nunca empilhadas). */
|
|
757
|
-
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
758
|
-
"br",
|
|
759
|
-
"hr",
|
|
760
|
-
"img"
|
|
761
|
-
]);
|
|
762
|
-
/**
|
|
763
|
-
* Tags cujo conteúdo é texto bruto no HTML. Ao encontrá-las abertas, todo o
|
|
764
|
-
* miolo é descartado até o fechamento correspondente (senão, o conteúdo do
|
|
765
|
-
* <script> viraria texto visível ou vetor de parse).
|
|
766
|
-
*/
|
|
767
|
-
var RAW_TEXT_TAGS = /* @__PURE__ */ new Set([
|
|
768
|
-
"script",
|
|
769
|
-
"style",
|
|
770
|
-
"iframe",
|
|
771
|
-
"object",
|
|
772
|
-
"embed",
|
|
773
|
-
"svg",
|
|
774
|
-
"math",
|
|
775
|
-
"textarea",
|
|
776
|
-
"title",
|
|
777
|
-
"noscript",
|
|
778
|
-
"template"
|
|
779
|
-
]);
|
|
780
|
-
/** Atributos permitidos (globais; validação extra por atributo abaixo). */
|
|
781
|
-
var ALLOWED_ATTRS = /* @__PURE__ */ new Set([
|
|
782
|
-
"class",
|
|
783
|
-
"title",
|
|
784
|
-
"alt",
|
|
785
|
-
"width",
|
|
786
|
-
"height",
|
|
787
|
-
"href",
|
|
788
|
-
"src",
|
|
789
|
-
"target",
|
|
790
|
-
"rel"
|
|
791
|
-
]);
|
|
792
|
-
/** Esquemas aceitos em href (links externos, e-mail, telefone). */
|
|
793
|
-
var HREF_SCHEMES = /* @__PURE__ */ new Set([
|
|
794
|
-
"http",
|
|
795
|
-
"https",
|
|
796
|
-
"mailto",
|
|
797
|
-
"tel"
|
|
798
|
-
]);
|
|
799
|
-
/** Esquemas aceitos em src (somente rede). */
|
|
800
|
-
var SRC_SCHEMES = /* @__PURE__ */ new Set(["http", "https"]);
|
|
801
|
-
/** Entidades nomeadas relevantes (as que poderiam alterar a validação de URL). */
|
|
802
|
-
var NAMED_ENTITIES = {
|
|
803
|
-
amp: "&",
|
|
804
|
-
lt: "<",
|
|
805
|
-
gt: ">",
|
|
806
|
-
quot: "\"",
|
|
807
|
-
apos: "'",
|
|
808
|
-
colon: ":",
|
|
809
|
-
tab: " ",
|
|
810
|
-
newline: "\n",
|
|
811
|
-
sol: "/",
|
|
812
|
-
lpar: "(",
|
|
813
|
-
rpar: ")",
|
|
814
|
-
num: "#",
|
|
815
|
-
period: ".",
|
|
816
|
-
excl: "!",
|
|
817
|
-
comma: ","
|
|
818
|
-
};
|
|
819
|
-
/** Decodifica referências numéricas e nomeadas (uma passada, como o navegador). */
|
|
820
|
-
function decodeEntities(value) {
|
|
821
|
-
return value.replace(/&#x([0-9a-fA-F]+);?/g, (_m, hex) => fromCodePoint(parseInt(hex, 16))).replace(/&#(\d+);?/g, (_m, dec) => fromCodePoint(parseInt(dec, 10))).replace(/&([a-zA-Z][a-zA-Z0-9]{1,30});?/g, (m, name) => {
|
|
822
|
-
return NAMED_ENTITIES[name in NAMED_ENTITIES ? name : name.toLowerCase()] ?? m;
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
function fromCodePoint(cp) {
|
|
826
|
-
if (!Number.isFinite(cp) || cp < 0 || cp > 1114111) return "";
|
|
827
|
-
try {
|
|
828
|
-
return String.fromCodePoint(cp);
|
|
829
|
-
} catch {
|
|
830
|
-
return "";
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
/** Escapa valor para uso dentro de atributo entre aspas duplas. */
|
|
834
|
-
function escapeAttr(value) {
|
|
835
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
836
|
-
}
|
|
837
|
-
/**
|
|
838
|
-
* Escapa texto preservando entidades já válidas (evita exibir `&`
|
|
839
|
-
* literalmente quando a tradução usa `&` de propósito).
|
|
840
|
-
*/
|
|
841
|
-
function escapeText(text) {
|
|
842
|
-
return text.replace(/&(?![a-zA-Z][a-zA-Z0-9]{1,30};|#[0-9]{1,7};|#[xX][0-9a-fA-F]{1,6};)|[<>]/g, (m) => m === "&" ? "&" : m === "<" ? "<" : ">");
|
|
843
|
-
}
|
|
844
|
-
/**
|
|
845
|
-
* Valida URL decodificando entidades e removendo tab/newline (mesmo tratamento
|
|
846
|
-
* do parser de URL do navegador) antes de inspecionar o esquema.
|
|
847
|
-
*/
|
|
848
|
-
function isSafeUrl(raw, allowedSchemes) {
|
|
849
|
-
const decoded = decodeEntities(raw).replace(/[\t\n\r]/g, "").trim();
|
|
850
|
-
const scheme = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(decoded);
|
|
851
|
-
if (!scheme) return true;
|
|
852
|
-
return allowedSchemes.has(scheme[1].toLowerCase());
|
|
853
|
-
}
|
|
854
|
-
/** Normaliza valor de atributo: decodifica (como o navegador faria) e re-escapa. */
|
|
855
|
-
function normalizeAttrValue(raw) {
|
|
856
|
-
return escapeAttr(decodeEntities(raw));
|
|
857
|
-
}
|
|
858
|
-
/**
|
|
859
|
-
* Extrai pares nome/valor de uma tag, respeitando aspas (um `>` dentro de
|
|
860
|
-
* aspas não termina a tag) e valores não-aspados do HTML.
|
|
861
|
-
*/
|
|
862
|
-
function parseAttrs(body) {
|
|
863
|
-
const pairs = [];
|
|
864
|
-
const n = body.length;
|
|
865
|
-
let i = 0;
|
|
866
|
-
const isWs = (c) => c === " " || c === " " || c === "\n" || c === "\r" || c === "\f";
|
|
867
|
-
while (i < n) {
|
|
868
|
-
while (i < n && (isWs(body.charAt(i)) || body.charAt(i) === "/")) i++;
|
|
869
|
-
if (i >= n) break;
|
|
870
|
-
let name = "";
|
|
871
|
-
while (i < n && !isWs(body.charAt(i)) && body.charAt(i) !== "=" && body.charAt(i) !== ">" && body.charAt(i) !== "/" && body.charAt(i) !== "<") {
|
|
872
|
-
name += body.charAt(i);
|
|
873
|
-
i++;
|
|
874
|
-
}
|
|
875
|
-
if (!name) {
|
|
876
|
-
i++;
|
|
877
|
-
continue;
|
|
878
|
-
}
|
|
879
|
-
let value = "";
|
|
880
|
-
let j = i;
|
|
881
|
-
while (j < n && isWs(body.charAt(j))) j++;
|
|
882
|
-
if (j < n && body.charAt(j) === "=") {
|
|
883
|
-
j++;
|
|
884
|
-
while (j < n && isWs(body.charAt(j))) j++;
|
|
885
|
-
if (j < n && (body.charAt(j) === "\"" || body.charAt(j) === "'")) {
|
|
886
|
-
const quote = body.charAt(j);
|
|
887
|
-
j++;
|
|
888
|
-
const start = j;
|
|
889
|
-
while (j < n && body.charAt(j) !== quote) j++;
|
|
890
|
-
value = body.slice(start, j);
|
|
891
|
-
j++;
|
|
892
|
-
} else {
|
|
893
|
-
const start = j;
|
|
894
|
-
while (j < n && !isWs(body.charAt(j)) && body.charAt(j) !== ">") j++;
|
|
895
|
-
value = body.slice(start, j);
|
|
896
|
-
}
|
|
897
|
-
i = j;
|
|
898
|
-
}
|
|
899
|
-
pairs.push([name.toLowerCase(), value]);
|
|
900
|
-
}
|
|
901
|
-
return pairs;
|
|
902
|
-
}
|
|
903
|
-
/** Filtra atributos: allowlist + validação de protocolo; força rel seguro. */
|
|
904
|
-
function filterAttrs(tag, pairs) {
|
|
905
|
-
const kept = [];
|
|
906
|
-
const seen = /* @__PURE__ */ new Set();
|
|
907
|
-
let targetBlank = false;
|
|
908
|
-
for (const [name, raw] of pairs) {
|
|
909
|
-
if (!ALLOWED_ATTRS.has(name) || seen.has(name)) continue;
|
|
910
|
-
if (name === "href" && !isSafeUrl(raw, HREF_SCHEMES)) continue;
|
|
911
|
-
if (name === "src" && !isSafeUrl(raw, SRC_SCHEMES)) continue;
|
|
912
|
-
if (name === "target") {
|
|
913
|
-
if (normalizeAttrValue(raw) !== "_blank") continue;
|
|
914
|
-
targetBlank = true;
|
|
915
|
-
continue;
|
|
916
|
-
}
|
|
917
|
-
if (name === "rel") continue;
|
|
918
|
-
seen.add(name);
|
|
919
|
-
kept.push(`${name}="${normalizeAttrValue(raw)}"`);
|
|
920
|
-
}
|
|
921
|
-
if (tag === "a" && targetBlank) {
|
|
922
|
-
kept.push("target=\"_blank\"");
|
|
923
|
-
kept.push("rel=\"noopener noreferrer\"");
|
|
924
|
-
}
|
|
925
|
-
return kept.length > 0 ? ` ${kept.join(" ")}` : "";
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Sanitiza uma string de HTML. Retorna apenas marcação da allowlist.
|
|
929
|
-
* Idempotente e sem dependências de DOM (seguro no SSR e no cliente).
|
|
930
|
-
*/
|
|
931
|
-
function sanitizeHtml(input) {
|
|
932
|
-
if (typeof input !== "string" || input.length === 0) return "";
|
|
933
|
-
const lower = input.toLowerCase();
|
|
934
|
-
const n = input.length;
|
|
935
|
-
const stack = [];
|
|
936
|
-
let out = "";
|
|
937
|
-
let i = 0;
|
|
938
|
-
while (i < n) {
|
|
939
|
-
const lt = input.indexOf("<", i);
|
|
940
|
-
if (lt === -1) {
|
|
941
|
-
out += escapeText(input.slice(i));
|
|
942
|
-
break;
|
|
943
|
-
}
|
|
944
|
-
if (lt > i) out += escapeText(input.slice(i, lt));
|
|
945
|
-
if (input.startsWith("<!--", lt)) {
|
|
946
|
-
const end = input.indexOf("-->", lt + 4);
|
|
947
|
-
i = end === -1 ? n : end + 3;
|
|
948
|
-
continue;
|
|
949
|
-
}
|
|
950
|
-
if (input.charAt(lt + 1) === "!" || input.charAt(lt + 1) === "?") {
|
|
951
|
-
const end = input.indexOf(">", lt + 2);
|
|
952
|
-
i = end === -1 ? n : end + 1;
|
|
953
|
-
continue;
|
|
954
|
-
}
|
|
955
|
-
const tagMatch = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)(?=[\s/>])/.exec(input.slice(lt, Math.min(lt + 64, n)));
|
|
956
|
-
if (!tagMatch) {
|
|
957
|
-
out += "<";
|
|
958
|
-
i = lt + 1;
|
|
959
|
-
continue;
|
|
960
|
-
}
|
|
961
|
-
const isClosing = tagMatch[1] === "/";
|
|
962
|
-
const tag = tagMatch[2].toLowerCase();
|
|
963
|
-
let j = lt + tagMatch[0].length;
|
|
964
|
-
let quote = "";
|
|
965
|
-
while (j < n) {
|
|
966
|
-
const ch = input[j];
|
|
967
|
-
if (quote) {
|
|
968
|
-
if (ch === quote) quote = "";
|
|
969
|
-
} else if (ch === "\"" || ch === "'") quote = ch;
|
|
970
|
-
else if (ch === ">") break;
|
|
971
|
-
j++;
|
|
972
|
-
}
|
|
973
|
-
if (j >= n) break;
|
|
974
|
-
const body = input.slice(lt + tagMatch[0].length, j);
|
|
975
|
-
i = j + 1;
|
|
976
|
-
if (!isClosing && RAW_TEXT_TAGS.has(tag)) {
|
|
977
|
-
const closeAt = lower.indexOf(`</${tag}`, i);
|
|
978
|
-
if (closeAt === -1) break;
|
|
979
|
-
const closeEnd = input.indexOf(">", closeAt);
|
|
980
|
-
i = closeEnd === -1 ? n : closeEnd + 1;
|
|
981
|
-
continue;
|
|
982
|
-
}
|
|
983
|
-
if (isClosing) {
|
|
984
|
-
const anchor = stack.lastIndexOf(tag);
|
|
985
|
-
if (anchor !== -1) {
|
|
986
|
-
for (let k = stack.length - 1; k >= anchor; k--) out += `</${stack[k]}>`;
|
|
987
|
-
stack.length = anchor;
|
|
988
|
-
}
|
|
989
|
-
continue;
|
|
990
|
-
}
|
|
991
|
-
if (!ALLOWED_TAGS.has(tag)) continue;
|
|
992
|
-
const attrs = filterAttrs(tag, parseAttrs(body));
|
|
993
|
-
if (VOID_TAGS.has(tag)) out += `<${tag}${attrs} />`;
|
|
994
|
-
else {
|
|
995
|
-
out += `<${tag}${attrs}>`;
|
|
996
|
-
stack.push(tag);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
for (let k = stack.length - 1; k >= 0; k--) out += `</${stack[k]}>`;
|
|
1000
|
-
return out;
|
|
1001
|
-
}
|
|
1002
|
-
//#endregion
|
|
1003
|
-
//#region src/components/screen-options/HelpTabs.tsx
|
|
1004
|
-
var _tmpl$$4 = [
|
|
1005
|
-
"<div",
|
|
1006
|
-
" class=\"help-tabs-panel\" role=\"dialog\"",
|
|
1007
|
-
"><div class=\"help-tabs-header\"><h3>",
|
|
1008
|
-
"</h3><button class=\"help-tabs-close\"",
|
|
1009
|
-
" type=\"button\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg></button></div><div class=\"help-tabs-nav\" role=\"tablist\"",
|
|
1010
|
-
">",
|
|
1011
|
-
"</div><div class=\"help-tabs-panels\">",
|
|
1012
|
-
"</div><div class=\"help-tabs-footer\"><button class=\"btn btn-primary\">",
|
|
1013
|
-
"</button></div></div>"
|
|
1014
|
-
];
|
|
1015
|
-
var _tmpl$2$3 = [
|
|
1016
|
-
"<div",
|
|
1017
|
-
" class=\"help-tabs-wrapper\"><div class=\"help-tabs\"><button class=\"help-tabs-trigger\"",
|
|
1018
|
-
" type=\"button\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M12 16v-4M12 8h.01\"></path></svg><span>",
|
|
1019
|
-
"</span><svg class=\"chevron\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"></path></svg></button><!--$-->",
|
|
1020
|
-
"<!--/--></div><style>\n .help-tabs-wrapper { position: relative; }\n .help-tabs { position: relative; }\n .help-tabs-trigger {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.375rem 0.75rem;\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n color: var(--color-text);\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n }\n .help-tabs-trigger:hover {\n background: var(--color-surface-hover);\n border-color: var(--color-primary);\n }\n .help-tabs-trigger .chevron {\n transition: transform 0.15s;\n flex-shrink: 0;\n }\n .help-tabs-trigger[aria-expanded=\"true\"] .chevron {\n transform: rotate(180deg);\n }\n .help-tabs-panel {\n position: absolute;\n top: calc(100% + 0.5rem);\n right: 0;\n width: 480px;\n max-width: 90vw;\n max-height: 70vh;\n background: var(--color-surface);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-lg);\n box-shadow: var(--shadow-xl);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.15s ease-out;\n overflow: hidden;\n }\n @keyframes slideIn { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } }\n .help-tabs-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid var(--color-border);\n }\n .help-tabs-header h3 { font-size: 0.875rem; font-weight: 600; }\n .help-tabs-close {\n background: none; border: none; padding: 0.25rem;\n color: var(--color-muted); cursor: pointer; border-radius: var(--radius-sm);\n }\n .help-tabs-close:hover { background: var(--color-background); color: var(--color-text); }\n .help-tabs-nav {\n display: flex;\n border-bottom: 1px solid var(--color-border);\n overflow-x: auto;\n }\n .help-tabs-tab {\n padding: 0.75rem 1rem;\n background: none; border: none;\n color: var(--color-muted); font-size: 0.8125rem; font-weight: 500;\n cursor: pointer; white-space: nowrap;\n border-bottom: 2px solid transparent;\n transition: all 0.15s;\n }\n .help-tabs-tab:hover { color: var(--color-text); background: var(--color-background); }\n .help-tabs-tab.active {\n color: var(--color-primary);\n border-bottom-color: var(--color-primary);\n font-weight: 600;\n }\n .help-tabs-panels {\n flex: 1; overflow-y: auto; padding: 1.5rem;\n }\n .help-tabs-panel { display: none; }\n .help-tabs-panel.active { display: block; animation: fadeIn 0.15s ease-out; }\n @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n .help-tabs-content { line-height: 1.6; color: var(--color-text); }\n .help-tabs-content h4 { font-size: 0.9375rem; font-weight: 600; margin: 1rem 0 0.5rem; color: var(--color-text); }\n .help-tabs-content h4:first-child { margin-top: 0; }\n .help-tabs-content p { margin: 0 0 0.75rem; color: var(--color-muted); }\n .help-tabs-content ul { margin: 0 0 0.75rem 1.25rem; color: var(--color-text); }\n .help-tabs-content li { margin-bottom: 0.375rem; }\n .help-tabs-content code {\n background: var(--color-background); padding: 0.125rem 0.375rem;\n border-radius: var(--radius-sm); font-size: 0.8125rem;\n font-family: ui-monospace, SFMono-Regular, monospace;\n }\n .help-tabs-content a { color: var(--color-primary); text-decoration: underline; }\n .help-tabs-footer {\n display: flex; justify-content: flex-end;\n padding: 1rem; border-top: 1px solid var(--color-border);\n }\n </style></div>"
|
|
1021
|
-
];
|
|
1022
|
-
var _tmpl$3$3 = [
|
|
1023
|
-
"<button",
|
|
1024
|
-
" role=\"tab\"",
|
|
1025
|
-
" aria-controls=\"",
|
|
1026
|
-
"\" id=\"",
|
|
1027
|
-
"\" type=\"button\">",
|
|
1028
|
-
"</button>"
|
|
1029
|
-
];
|
|
1030
|
-
var _tmpl$4$3 = [
|
|
1031
|
-
"<div",
|
|
1032
|
-
" role=\"tabpanel\" id=\"",
|
|
1033
|
-
"\" aria-labelledby=\"",
|
|
1034
|
-
"\"><div class=\"help-tabs-content\">",
|
|
1035
|
-
"</div></div>"
|
|
1036
|
-
];
|
|
1037
|
-
function HelpTabs(props) {
|
|
1038
|
-
const { t } = useTranslation();
|
|
1039
|
-
const [open, setOpen] = createSignal(false);
|
|
1040
|
-
const [activeTab, setActiveTab] = createSignal(props.tabs[0]?.id ?? "");
|
|
1041
|
-
const handleClickOutside = (e) => {
|
|
1042
|
-
if (!e.target.closest(".help-tabs")) setOpen(false);
|
|
1043
|
-
};
|
|
1044
|
-
onMount(() => {
|
|
1045
|
-
if (isServer) return;
|
|
1046
|
-
document.addEventListener("click", handleClickOutside);
|
|
1047
|
-
});
|
|
1048
|
-
onCleanup(() => {
|
|
1049
|
-
if (isServer) return;
|
|
1050
|
-
document.removeEventListener("click", handleClickOutside);
|
|
1051
|
-
});
|
|
1052
|
-
return ssr(_tmpl$2$3, ssrHydrationKey(), ssrAttribute("aria-expanded", escape(open(), true), false) + ssrAttribute("aria-label", escape(t("helpTabs.label"), true), false), escape(t("helpTabs.title")), escape(createComponent(Show, {
|
|
1053
|
-
get when() {
|
|
1054
|
-
return open();
|
|
1055
|
-
},
|
|
1056
|
-
get children() {
|
|
1057
|
-
return ssr(_tmpl$$4, ssrHydrationKey(), ssrAttribute("aria-label", escape(t("helpTabs.title"), true), false), escape(t("helpTabs.title")), ssrAttribute("aria-label", escape(t("common.close"), true), false), ssrAttribute("aria-label", escape(t("helpTabs.tabs"), true), false), escape(props.tabs.map((tab) => ssr(_tmpl$3$3, ssrHydrationKey() + ssrAttribute("class", activeTab() === tab.id ? "help-tabs-tab active" : "help-tabs-tab", false), ssrAttribute("aria-selected", escape(activeTab(), true) === escape(tab.id, true), false), `help-panel-${escape(tab.id, true)}`, `help-tab-${escape(tab.id, true)}`, escape(tab.label)))), escape(props.tabs.map((tab) => ssr(_tmpl$4$3, ssrHydrationKey() + ssrAttribute("class", activeTab() === tab.id ? "help-tabs-panel active" : "help-tabs-panel", false), `help-panel-${escape(tab.id, true)}`, `help-tab-${escape(tab.id, true)}`, sanitizeHtml(tab.content)))), escape(t("common.close")));
|
|
1058
|
-
}
|
|
1059
|
-
})));
|
|
1060
|
-
}
|
|
1061
|
-
//#endregion
|
|
1062
585
|
//#region src/lib/version.ts
|
|
1063
586
|
/** Versão do release atual (ex.: "0.4.0"). */
|
|
1064
587
|
var APP_VERSION = {
|
|
1065
588
|
name: "okcms",
|
|
1066
|
-
version: "0.4.
|
|
589
|
+
version: "0.4.14",
|
|
1067
590
|
"private": true,
|
|
1068
591
|
description: "Hybrid, modular, API-first CMS",
|
|
1069
592
|
engines: {
|
|
@@ -1428,19 +951,18 @@ function ActivityWidget() {
|
|
|
1428
951
|
var _tmpl$ = [
|
|
1429
952
|
"<footer",
|
|
1430
953
|
" class=\"admin-footer\" role=\"contentinfo\"><div class=\"footer-content\"><div class=\"footer-left\"><p class=\"footer-version\"><span class=\"product-name\">OkCMS</span><span class=\"version-badge\">v<!--$-->",
|
|
1431
|
-
"<!--/--></span></p><
|
|
1432
|
-
"</p></div><nav class=\"footer-links\"",
|
|
954
|
+
"<!--/--></span></p></div><nav class=\"footer-links\"",
|
|
1433
955
|
"><a href=\"https://oktisworks.com\" target=\"_blank\" rel=\"noopener noreferrer\">",
|
|
1434
956
|
"</a><a href=\"https://github.com/oktis-works/cms\" target=\"_blank\" rel=\"noopener noreferrer\">",
|
|
1435
957
|
"</a><a href=\"https://docs.oktisworks.com\" target=\"_blank\" rel=\"noopener noreferrer\">",
|
|
1436
958
|
"</a><a href=\"https://oktisworks.com/community\" target=\"_blank\" rel=\"noopener noreferrer\">",
|
|
1437
959
|
"</a></nav><div class=\"footer-right\"><p class=\"footer-powered\">",
|
|
1438
|
-
"</p></div></div><style>\n .admin-footer {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n height: 48px;\n background:
|
|
960
|
+
"</p></div></div><style>\n .admin-footer {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n height: 48px;\n background: #2d2d2d;\n border-top: 1px solid var(--color-border);\n padding: 0 1.5rem;\n z-index: 1000;\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 0.75rem;\n color: var(--color-muted);\n }\n\n .footer-content {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n max-width: 1400px;\n margin: 0 auto;\n gap: 1.5rem;\n }\n\n .footer-left { display: flex; flex-direction: column; gap: 0.125rem; }\n\n .footer-version {\n display: flex; align-items: center; gap: 0.5rem;\n font-weight: 600; color: var(--color-text); font-size: 0.8125rem;\n }\n\n .version-badge {\n background: var(--color-primary-soft);\n color: var(--color-primary-hover);\n padding: 0.125rem 0.375rem;\n border-radius: var(--radius-sm);\n font-size: 0.6875rem;\n font-weight: 700;\n }\n\n .footer-links {\n display: flex; gap: 1.5rem;\n }\n\n .footer-links a {\n color: var(--color-muted);\n font-size: 0.75rem;\n font-weight: 500;\n text-decoration: none;\n transition: color 0.15s;\n }\n\n .footer-links a:hover { color: var(--color-primary); }\n\n .footer-right { text-align: right; }\n .footer-powered { font-size: 0.6875rem; color: var(--color-muted); }\n\n @media (max-width: 768px) {\n .admin-footer { flex-direction: column; height: auto; padding: 0.75rem 1rem; gap: 0.5rem; }\n .footer-content { flex-direction: column; gap: 0.5rem; }\n .footer-links { flex-wrap: wrap; justify-content: center; }\n }\n\n /* RTL adjustments */\n [dir=\"rtl\"] .footer-links { flex-direction: row-reverse; }\n [dir=\"rtl\"] .footer-right { text-align: left; }\n [dir=\"rtl\"] .footer-left { align-items: flex-end; }\n </style></footer>"
|
|
1439
961
|
];
|
|
1440
962
|
function Footer() {
|
|
1441
963
|
const { t } = useTranslation();
|
|
1442
964
|
const version = APP_VERSION;
|
|
1443
|
-
return ssr(_tmpl$, ssrHydrationKey(), escape(version),
|
|
965
|
+
return ssr(_tmpl$, ssrHydrationKey(), escape(version), ssrAttribute("aria-label", escape(t("footer.links"), true), false), escape(t("footer.website")), escape(t("footer.github")), escape(t("footer.docs")), escape(t("footer.community")), escape(t("footer.poweredBy")));
|
|
1444
966
|
}
|
|
1445
967
|
//#endregion
|
|
1446
968
|
//#region src/layouts/DashboardLayout.astro
|
|
@@ -1449,7 +971,7 @@ var $$DashboardLayout = createComponent$1(($$result, $$props, $$slots) => {
|
|
|
1449
971
|
const Astro = $$result.createAstro($$props, $$slots);
|
|
1450
972
|
Astro.self = $$DashboardLayout;
|
|
1451
973
|
const { title, description } = Astro.props;
|
|
1452
|
-
const { t
|
|
974
|
+
const { t } = Astro.locals;
|
|
1453
975
|
const pathname = Astro.url.pathname;
|
|
1454
976
|
const isActive = (href) => href === "/" ? pathname === "/" : pathname === href || pathname.startsWith(`${href}/`);
|
|
1455
977
|
const navActive = {
|
|
@@ -1472,44 +994,30 @@ var $$DashboardLayout = createComponent$1(($$result, $$props, $$slots) => {
|
|
|
1472
994
|
label: t("settings.postTypes.title"),
|
|
1473
995
|
active: isActive("/settings/post-types")
|
|
1474
996
|
},
|
|
997
|
+
{
|
|
998
|
+
href: "/settings/custom-fields",
|
|
999
|
+
label: t("settings.customFields.title"),
|
|
1000
|
+
active: isActive("/settings/custom-fields")
|
|
1001
|
+
},
|
|
1475
1002
|
{
|
|
1476
1003
|
href: "/settings/taxonomies",
|
|
1477
1004
|
label: t("settings.taxonomies.title"),
|
|
1478
1005
|
active: isActive("/settings/taxonomies")
|
|
1479
|
-
}
|
|
1480
|
-
];
|
|
1481
|
-
const screenOptionsPanels = [
|
|
1482
|
-
{
|
|
1483
|
-
id: "at-glance",
|
|
1484
|
-
label: t("dashboard.widgets.atGlance"),
|
|
1485
|
-
defaultOpen: true
|
|
1486
1006
|
},
|
|
1487
1007
|
{
|
|
1488
|
-
|
|
1489
|
-
label: t("
|
|
1490
|
-
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
id: "quick-draft",
|
|
1494
|
-
label: t("dashboard.widgets.quickDraft.title"),
|
|
1495
|
-
defaultOpen: true
|
|
1496
|
-
}
|
|
1497
|
-
];
|
|
1498
|
-
const helpTabs = [
|
|
1499
|
-
{
|
|
1500
|
-
id: "overview",
|
|
1501
|
-
label: t("helpTabs.topics.overview.label"),
|
|
1502
|
-
content: t("helpTabs.topics.overview.content")
|
|
1008
|
+
href: "/settings/resources",
|
|
1009
|
+
label: t("resources.title"),
|
|
1010
|
+
active: isActive("/settings/resources")
|
|
1503
1011
|
},
|
|
1504
1012
|
{
|
|
1505
|
-
|
|
1506
|
-
label: t("
|
|
1507
|
-
|
|
1013
|
+
href: "/settings/access",
|
|
1014
|
+
label: t("access.title"),
|
|
1015
|
+
active: isActive("/settings/access")
|
|
1508
1016
|
},
|
|
1509
1017
|
{
|
|
1510
|
-
|
|
1511
|
-
label: t("
|
|
1512
|
-
|
|
1018
|
+
href: "/settings/operations",
|
|
1019
|
+
label: t("operations.title"),
|
|
1020
|
+
active: isActive("/settings/operations")
|
|
1513
1021
|
}
|
|
1514
1022
|
];
|
|
1515
1023
|
return renderTemplate`${renderComponent($$result, "BaseLayout", $$BaseLayout, {
|
|
@@ -1522,34 +1030,13 @@ var $$DashboardLayout = createComponent$1(($$result, $$props, $$slots) => {
|
|
|
1522
1030
|
"client:component-hydration": "load",
|
|
1523
1031
|
"client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/admin-bar/AdminBar.tsx",
|
|
1524
1032
|
"client:component-export": "AdminBar"
|
|
1525
|
-
})}${maybeRenderHead($$result)}<div class="layout" data-astro-cid-ynf3rr4n><!-- Sidebar colapsavel — o estado (body.sidebar-collapsed) e aplicado pelo script abaixo --><aside class="sidebar" data-astro-cid-ynf3rr4n><div class="sidebar-header" data-astro-cid-ynf3rr4n><
|
|
1033
|
+
})}${maybeRenderHead($$result)}<div class="layout" data-astro-cid-ynf3rr4n><!-- Sidebar colapsavel — o estado (body.sidebar-collapsed) e aplicado pelo script abaixo --><aside class="sidebar" data-astro-cid-ynf3rr4n><div class="sidebar-header" data-astro-cid-ynf3rr4n><span class="sidebar-collapsed-brand"${addAttribute(t("layout.appName"), "title")} data-astro-cid-ynf3rr4n><svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="28" height="28" data-astro-cid-ynf3rr4n><rect width="32" height="32" rx="8" fill="url(#grad)" data-astro-cid-ynf3rr4n></rect><path d="M8 10h16M8 16h12M8 22h8" stroke="#0A0A0A" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n></path><defs data-astro-cid-ynf3rr4n><linearGradient id="grad" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse" data-astro-cid-ynf3rr4n><stop offset="0%" stop-color="#D8B45E" data-astro-cid-ynf3rr4n></stop><stop offset="100%" stop-color="#B99542" data-astro-cid-ynf3rr4n></stop></linearGradient></defs></svg></span></div><nav class="sidebar-nav" data-astro-cid-ynf3rr4n><a href="/"${addAttribute(["nav-item", { active: navActive.dashboard }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><rect x="3" y="3" width="7" height="7" data-astro-cid-ynf3rr4n></rect><rect x="14" y="3" width="7" height="7" data-astro-cid-ynf3rr4n></rect><rect x="14" y="14" width="7" height="7" data-astro-cid-ynf3rr4n></rect><rect x="3" y="14" width="7" height="7" data-astro-cid-ynf3rr4n></rect></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.dashboard")}</span></a><a href="/content"${addAttribute(["nav-item", { active: navActive.content }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" data-astro-cid-ynf3rr4n></path><polyline points="14 2 14 8 20 8" data-astro-cid-ynf3rr4n></polyline><line x1="16" y1="13" x2="8" y2="13" data-astro-cid-ynf3rr4n></line><line x1="16" y1="17" x2="8" y2="17" data-astro-cid-ynf3rr4n></line><polyline points="10 9 9 9 8 9" data-astro-cid-ynf3rr4n></polyline></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.content")}</span></a><a href="/media"${addAttribute(["nav-item", { active: navActive.media }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><rect x="3" y="3" width="18" height="18" rx="2" ry="2" data-astro-cid-ynf3rr4n></rect><circle cx="8.5" cy="8.5" r="1.5" data-astro-cid-ynf3rr4n></circle><polyline points="21 15 16 10 5 21" data-astro-cid-ynf3rr4n></polyline></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.media")}</span></a><a href="/users"${addAttribute(["nav-item", { active: navActive.users }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" data-astro-cid-ynf3rr4n></path><circle cx="9" cy="7" r="4" data-astro-cid-ynf3rr4n></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87" data-astro-cid-ynf3rr4n></path><path d="M16 3.13a4 4 0 0 1 0 7.75" data-astro-cid-ynf3rr4n></path></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.users")}</span></a><a href="/settings"${addAttribute(["nav-item", { active: navActive.settings }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><circle cx="12" cy="12" r="3" data-astro-cid-ynf3rr4n></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06-.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1.82-.33l-.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0-2.83l-.06-.06a1.65 1.65 0 0 0-.33-1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" data-astro-cid-ynf3rr4n></path></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.settings")}</span></a><!-- Submenu de configurações fica agrupado diretamente sob Settings. --><div class="nav-submenu" data-astro-cid-ynf3rr4n>${settingsChildren.map((child) => renderTemplate`<a${addAttribute(child.href, "href")}${addAttribute(["nav-subitem", { active: child.active }], "class:list")} data-astro-cid-ynf3rr4n>${child.label}</a>`)}</div><a href="/plugins"${addAttribute(["nav-item", { active: navActive.plugins }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><rect x="2" y="2" width="20" height="20" rx="2" ry="2" data-astro-cid-ynf3rr4n></rect><path d="M15 7h4a2 2 0 0 1 2 2v4" data-astro-cid-ynf3rr4n></path><path d="M9 17H5a2 2 0 0 1-2-2V9" data-astro-cid-ynf3rr4n></path><line x1="8" y1="12" x2="16" y2="12" data-astro-cid-ynf3rr4n></line></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.plugins")}</span></a><a href="/themes"${addAttribute(["nav-item", { active: navActive.themes }], "class:list")} data-astro-cid-ynf3rr4n><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-ynf3rr4n><circle cx="12" cy="12" r="10" data-astro-cid-ynf3rr4n></circle><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" data-astro-cid-ynf3rr4n></path><path d="M2 12h20" data-astro-cid-ynf3rr4n></path></svg><span class="nav-label" data-astro-cid-ynf3rr4n>${t("layout.nav.themes")}</span></a><!-- D1: slots de extensao — paginas de menu declaradas por plugins ativos -->${renderComponent($$result, "PluginExtensionsSlot", PluginExtensionsSlot, {
|
|
1526
1034
|
"client:load": true,
|
|
1527
1035
|
"data-astro-cid-ynf3rr4n": true,
|
|
1528
1036
|
"client:component-hydration": "load",
|
|
1529
1037
|
"client:component-path": "/home/runner/work/cms/cms/apps/admin/src/ext/extensions.tsx",
|
|
1530
1038
|
"client:component-export": "PluginExtensionsSlot"
|
|
1531
|
-
})}</nav></aside><main class="main-content" data-astro-cid-ynf3rr4n><!--
|
|
1532
|
-
"client:load": true,
|
|
1533
|
-
"panels": screenOptionsPanels,
|
|
1534
|
-
"data-astro-cid-ynf3rr4n": true,
|
|
1535
|
-
"client:component-hydration": "load",
|
|
1536
|
-
"client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/screen-options/ScreenOptions.tsx",
|
|
1537
|
-
"client:component-export": "ScreenOptions"
|
|
1538
|
-
})}${renderComponent($$result, "HelpTabs", HelpTabs, {
|
|
1539
|
-
"client:load": true,
|
|
1540
|
-
"tabs": helpTabs,
|
|
1541
|
-
"data-astro-cid-ynf3rr4n": true,
|
|
1542
|
-
"client:component-hydration": "load",
|
|
1543
|
-
"client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/screen-options/HelpTabs.tsx",
|
|
1544
|
-
"client:component-export": "HelpTabs"
|
|
1545
|
-
})}</div><div class="content-wrapper" data-astro-cid-ynf3rr4n><header class="main-header" data-astro-cid-ynf3rr4n><h1 class="text-lg font-bold" data-astro-cid-ynf3rr4n>${title}</h1><div class="header-actions" data-astro-cid-ynf3rr4n>${renderComponent($$result, "LanguageSelector", LanguageSelector, {
|
|
1546
|
-
"client:load": true,
|
|
1547
|
-
"locale": locale,
|
|
1548
|
-
"data-astro-cid-ynf3rr4n": true,
|
|
1549
|
-
"client:component-hydration": "load",
|
|
1550
|
-
"client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/LanguageSelector.tsx",
|
|
1551
|
-
"client:component-export": "LanguageSelector"
|
|
1552
|
-
})}<button class="btn btn-secondary btn-sm" id="logout-btn" data-astro-cid-ynf3rr4n>${t("layout.actions.logout")}</button></div></header><div class="content" data-astro-cid-ynf3rr4n>${renderSlot($$result, $$slots["default"])}</div><!-- Dashboard Widgets (only on dashboard page) -->${pathname === "/" && renderTemplate`<div class="dashboard-widgets-area" data-astro-cid-ynf3rr4n><div class="dashboard-widgets-grid" data-astro-cid-ynf3rr4n>${renderComponent($$result, "AtGlanceWidget", AtGlanceWidget, {
|
|
1039
|
+
})}</nav></aside><main class="main-content" data-astro-cid-ynf3rr4n><div class="content-wrapper" data-astro-cid-ynf3rr4n><div class="content" data-astro-cid-ynf3rr4n>${renderSlot($$result, $$slots["default"])}</div><!-- Dashboard Widgets (only on dashboard page) -->${pathname === "/" && renderTemplate`<div class="dashboard-widgets-area" data-astro-cid-ynf3rr4n><div class="dashboard-widgets-grid" data-astro-cid-ynf3rr4n>${renderComponent($$result, "AtGlanceWidget", AtGlanceWidget, {
|
|
1553
1040
|
"client:load": true,
|
|
1554
1041
|
"data-astro-cid-ynf3rr4n": true,
|
|
1555
1042
|
"client:component-hydration": "load",
|