kempo 4.2.16 → 4.2.17
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/bin/cli.js +21 -4
- package/dist/admin/components/AddGroupControl.js +2 -2
- package/dist/admin/components/AddGroupControl.js.map +1 -1
- package/dist/admin/components/ClearExpiredSessionsControl.js +2 -2
- package/dist/admin/components/ClearExpiredSessionsControl.js.map +1 -1
- package/dist/admin/components/FragmentEditor.js +15 -15
- package/dist/admin/components/FragmentEditor.js.map +1 -1
- package/dist/admin/components/GlobalContentEditor.js +12 -12
- package/dist/admin/components/GlobalContentEditor.js.map +1 -1
- package/dist/admin/components/GroupDeleteSelected.js +2 -2
- package/dist/admin/components/GroupDeleteSelected.js.map +1 -1
- package/dist/admin/components/GroupRemoveRecord.js +2 -2
- package/dist/admin/components/GroupRemoveRecord.js.map +1 -1
- package/dist/admin/components/Monaco.js +1 -1
- package/dist/admin/components/Monaco.js.map +1 -1
- package/dist/admin/components/PageEditor.js +42 -28
- package/dist/admin/components/PageEditor.js.map +1 -1
- package/dist/admin/components/TableRowDelete.js +2 -2
- package/dist/admin/components/TableRowDelete.js.map +1 -1
- package/dist/admin/components/TableRowLink.js +2 -2
- package/dist/admin/components/TableRowLink.js.map +1 -1
- package/dist/admin/components/TemplateEditor.js +18 -18
- package/dist/admin/components/TemplateEditor.js.map +1 -1
- package/dist/admin/components/ValueEditor.js +17 -17
- package/dist/admin/components/ValueEditor.js.map +1 -1
- package/dist/admin/components/tableControls/AddMember.js +2 -2
- package/dist/admin/components/tableControls/AddMember.js.map +1 -1
- package/dist/admin/components/tableControls/AddPermission.js +2 -2
- package/dist/admin/components/tableControls/AddPermission.js.map +1 -1
- package/dist/admin/components/tableControls/InstallExtension.js +2 -2
- package/dist/admin/components/tableControls/InstallExtension.js.map +1 -1
- package/dist/admin/components/tableControls/UninstallExtension.js +2 -2
- package/dist/admin/components/tableControls/UninstallExtension.js.map +1 -1
- package/dist/admin/extensions/index.page.html +49 -15
- package/dist/admin/icons/open_in_new.svg +1 -0
- package/dist/admin/nav.fragment.html +1 -1
- package/dist/kempo/api/admin-globals/DELETE.js +1 -1
- package/dist/kempo/api/admin-globals/DELETE.js.map +1 -1
- package/dist/kempo/api/admin-globals/GET.js +1 -1
- package/dist/kempo/api/admin-globals/GET.js.map +1 -1
- package/dist/kempo/api/admin-globals/POST.js +1 -1
- package/dist/kempo/api/admin-globals/POST.js.map +1 -1
- package/dist/kempo/api/admin-globals/[id]/GET.js +1 -1
- package/dist/kempo/api/admin-globals/[id]/GET.js.map +1 -1
- package/dist/kempo/api/admin-globals/[id]/PUT.js +1 -1
- package/dist/kempo/api/admin-globals/[id]/PUT.js.map +1 -1
- package/dist/kempo/api/admin-globals/[id]/disable/PUT.js +1 -1
- package/dist/kempo/api/admin-globals/[id]/disable/PUT.js.map +1 -1
- package/dist/kempo/api/admin-globals/[id]/enable/PUT.js +1 -1
- package/dist/kempo/api/admin-globals/[id]/enable/PUT.js.map +1 -1
- package/dist/kempo/api/auth/change-password/POST.js +1 -1
- package/dist/kempo/api/auth/change-password/POST.js.map +1 -1
- package/dist/kempo/api/auth/login/email/POST.js +1 -1
- package/dist/kempo/api/auth/login/email/POST.js.map +1 -1
- package/dist/kempo/api/auth/logout/POST.js +1 -1
- package/dist/kempo/api/auth/logout/POST.js.map +1 -1
- package/dist/kempo/api/auth/register/email/POST.js +1 -1
- package/dist/kempo/api/auth/register/email/POST.js.map +1 -1
- package/dist/kempo/api/auth/reset-password/POST.js +1 -1
- package/dist/kempo/api/auth/reset-password/POST.js.map +1 -1
- package/dist/kempo/api/auth/session/GET.js +1 -1
- package/dist/kempo/api/auth/session/GET.js.map +1 -1
- package/dist/kempo/api/auth/verify-email/POST.js +1 -1
- package/dist/kempo/api/auth/verify-email/POST.js.map +1 -1
- package/dist/kempo/api/extensions/DELETE.js +1 -1
- package/dist/kempo/api/extensions/DELETE.js.map +1 -1
- package/dist/kempo/api/extensions/GET.js +1 -1
- package/dist/kempo/api/extensions/GET.js.map +1 -1
- package/dist/kempo/api/extensions/POST.js +1 -1
- package/dist/kempo/api/extensions/POST.js.map +1 -1
- package/dist/kempo/api/extensions/[name]/disable/POST.js +1 -1
- package/dist/kempo/api/extensions/[name]/disable/POST.js.map +1 -1
- package/dist/kempo/api/extensions/[name]/enable/POST.js +1 -1
- package/dist/kempo/api/extensions/[name]/enable/POST.js.map +1 -1
- package/dist/kempo/api/extensions/[name]/update/POST.js +1 -1
- package/dist/kempo/api/extensions/[name]/update/POST.js.map +1 -1
- package/dist/kempo/api/extensions/[name]/update-check/GET.js +1 -1
- package/dist/kempo/api/extensions/[name]/update-check/GET.js.map +1 -1
- package/dist/kempo/api/extensions/available/GET.js +1 -1
- package/dist/kempo/api/extensions/available/GET.js.map +1 -1
- package/dist/kempo/api/extensions/known/GET.js +1 -1
- package/dist/kempo/api/extensions/known/GET.js.map +1 -1
- package/dist/kempo/api/forgot-password/POST.js +1 -1
- package/dist/kempo/api/forgot-password/POST.js.map +1 -1
- package/dist/kempo/api/fragments/DELETE.js +1 -1
- package/dist/kempo/api/fragments/DELETE.js.map +1 -1
- package/dist/kempo/api/fragments/GET.js +1 -1
- package/dist/kempo/api/fragments/GET.js.map +1 -1
- package/dist/kempo/api/fragments/POST.js +1 -1
- package/dist/kempo/api/fragments/POST.js.map +1 -1
- package/dist/kempo/api/fragments/disable/PUT.js +1 -1
- package/dist/kempo/api/fragments/disable/PUT.js.map +1 -1
- package/dist/kempo/api/fragments/enable/PUT.js +1 -1
- package/dist/kempo/api/fragments/enable/PUT.js.map +1 -1
- package/dist/kempo/api/fragments/file/GET.js +1 -1
- package/dist/kempo/api/fragments/file/GET.js.map +1 -1
- package/dist/kempo/api/fragments/file/PATCH.js +1 -1
- package/dist/kempo/api/fragments/file/PATCH.js.map +1 -1
- package/dist/kempo/api/fragments/file/PUT.js +1 -1
- package/dist/kempo/api/fragments/file/PUT.js.map +1 -1
- package/dist/kempo/api/fragments/lock/PUT.js +2 -2
- package/dist/kempo/api/fragments/lock/PUT.js.map +1 -1
- package/dist/kempo/api/globals/DELETE.js +1 -1
- package/dist/kempo/api/globals/DELETE.js.map +1 -1
- package/dist/kempo/api/globals/GET.js +1 -1
- package/dist/kempo/api/globals/GET.js.map +1 -1
- package/dist/kempo/api/globals/POST.js +1 -1
- package/dist/kempo/api/globals/POST.js.map +1 -1
- package/dist/kempo/api/globals/disable/PUT.js +1 -1
- package/dist/kempo/api/globals/disable/PUT.js.map +1 -1
- package/dist/kempo/api/globals/enable/PUT.js +1 -1
- package/dist/kempo/api/globals/enable/PUT.js.map +1 -1
- package/dist/kempo/api/globals/entry/GET.js +1 -1
- package/dist/kempo/api/globals/entry/GET.js.map +1 -1
- package/dist/kempo/api/globals/entry/PUT.js +1 -1
- package/dist/kempo/api/globals/entry/PUT.js.map +1 -1
- package/dist/kempo/api/globals/lock/PUT.js +2 -2
- package/dist/kempo/api/globals/lock/PUT.js.map +1 -1
- package/dist/kempo/api/groups/DELETE.js +1 -1
- package/dist/kempo/api/groups/DELETE.js.map +1 -1
- package/dist/kempo/api/groups/GET.js +1 -1
- package/dist/kempo/api/groups/GET.js.map +1 -1
- package/dist/kempo/api/groups/PATCH.js +1 -1
- package/dist/kempo/api/groups/PATCH.js.map +1 -1
- package/dist/kempo/api/groups/POST.js +1 -1
- package/dist/kempo/api/groups/POST.js.map +1 -1
- package/dist/kempo/api/groups/[name]/GET.js +1 -1
- package/dist/kempo/api/groups/[name]/GET.js.map +1 -1
- package/dist/kempo/api/groups/[name]/members/DELETE.js +1 -1
- package/dist/kempo/api/groups/[name]/members/DELETE.js.map +1 -1
- package/dist/kempo/api/groups/[name]/members/GET.js +1 -1
- package/dist/kempo/api/groups/[name]/members/GET.js.map +1 -1
- package/dist/kempo/api/groups/[name]/members/POST.js +1 -1
- package/dist/kempo/api/groups/[name]/members/POST.js.map +1 -1
- package/dist/kempo/api/groups/[name]/permissions/DELETE.js +1 -1
- package/dist/kempo/api/groups/[name]/permissions/DELETE.js.map +1 -1
- package/dist/kempo/api/groups/[name]/permissions/GET.js +1 -1
- package/dist/kempo/api/groups/[name]/permissions/GET.js.map +1 -1
- package/dist/kempo/api/groups/[name]/permissions/POST.js +1 -1
- package/dist/kempo/api/groups/[name]/permissions/POST.js.map +1 -1
- package/dist/kempo/api/pages/DELETE.js +1 -1
- package/dist/kempo/api/pages/DELETE.js.map +1 -1
- package/dist/kempo/api/pages/GET.js +1 -1
- package/dist/kempo/api/pages/GET.js.map +1 -1
- package/dist/kempo/api/pages/POST.js +1 -1
- package/dist/kempo/api/pages/POST.js.map +1 -1
- package/dist/kempo/api/pages/directories/GET.js +1 -1
- package/dist/kempo/api/pages/directories/GET.js.map +1 -1
- package/dist/kempo/api/pages/disable/PUT.js +1 -1
- package/dist/kempo/api/pages/disable/PUT.js.map +1 -1
- package/dist/kempo/api/pages/enable/PUT.js +1 -1
- package/dist/kempo/api/pages/enable/PUT.js.map +1 -1
- package/dist/kempo/api/pages/file/GET.js +1 -1
- package/dist/kempo/api/pages/file/GET.js.map +1 -1
- package/dist/kempo/api/pages/file/PATCH.js +1 -1
- package/dist/kempo/api/pages/file/PATCH.js.map +1 -1
- package/dist/kempo/api/pages/file/PUT.js +1 -1
- package/dist/kempo/api/pages/file/PUT.js.map +1 -1
- package/dist/kempo/api/pages/lock/PUT.js +2 -2
- package/dist/kempo/api/pages/lock/PUT.js.map +1 -1
- package/dist/kempo/api/pages/search/GET.js +2 -2
- package/dist/kempo/api/pages/search/GET.js.map +1 -1
- package/dist/kempo/api/pages/templates/GET.js +1 -1
- package/dist/kempo/api/pages/templates/GET.js.map +1 -1
- package/dist/kempo/api/permissions/DELETE.js +1 -1
- package/dist/kempo/api/permissions/DELETE.js.map +1 -1
- package/dist/kempo/api/permissions/GET.js +1 -1
- package/dist/kempo/api/permissions/GET.js.map +1 -1
- package/dist/kempo/api/permissions/PATCH.js +1 -1
- package/dist/kempo/api/permissions/PATCH.js.map +1 -1
- package/dist/kempo/api/permissions/POST.js +1 -1
- package/dist/kempo/api/permissions/POST.js.map +1 -1
- package/dist/kempo/api/settings/[owner]/GET.js +1 -1
- package/dist/kempo/api/settings/[owner]/GET.js.map +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/DELETE.js +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/DELETE.js.map +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/GET.js +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/GET.js.map +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/POST.js +1 -1
- package/dist/kempo/api/settings/[owner]/[name]/POST.js.map +1 -1
- package/dist/kempo/api/settings/public/GET.js +1 -1
- package/dist/kempo/api/settings/public/GET.js.map +1 -1
- package/dist/kempo/api/templates/DELETE.js +1 -1
- package/dist/kempo/api/templates/DELETE.js.map +1 -1
- package/dist/kempo/api/templates/GET.js +1 -1
- package/dist/kempo/api/templates/GET.js.map +1 -1
- package/dist/kempo/api/templates/POST.js +1 -1
- package/dist/kempo/api/templates/POST.js.map +1 -1
- package/dist/kempo/api/templates/disable/PUT.js +1 -1
- package/dist/kempo/api/templates/disable/PUT.js.map +1 -1
- package/dist/kempo/api/templates/enable/PUT.js +1 -1
- package/dist/kempo/api/templates/enable/PUT.js.map +1 -1
- package/dist/kempo/api/templates/file/GET.js +1 -1
- package/dist/kempo/api/templates/file/GET.js.map +1 -1
- package/dist/kempo/api/templates/file/PATCH.js +1 -1
- package/dist/kempo/api/templates/file/PATCH.js.map +1 -1
- package/dist/kempo/api/templates/file/PUT.js +1 -1
- package/dist/kempo/api/templates/file/PUT.js.map +1 -1
- package/dist/kempo/api/templates/lock/PUT.js +2 -2
- package/dist/kempo/api/templates/lock/PUT.js.map +1 -1
- package/dist/kempo/api/user/DELETE.js +1 -1
- package/dist/kempo/api/user/DELETE.js.map +1 -1
- package/dist/kempo/api/user/GET.js +1 -1
- package/dist/kempo/api/user/GET.js.map +1 -1
- package/dist/kempo/api/user/PATCH.js +1 -1
- package/dist/kempo/api/user/PATCH.js.map +1 -1
- package/dist/kempo/api/user/[userid]/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/groups/DELETE.js +1 -1
- package/dist/kempo/api/user/[userid]/groups/DELETE.js.map +1 -1
- package/dist/kempo/api/user/[userid]/groups/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/groups/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/groups/POST.js +1 -1
- package/dist/kempo/api/user/[userid]/groups/POST.js.map +1 -1
- package/dist/kempo/api/user/[userid]/permissions/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/permissions/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/permissions/all/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/permissions/all/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/permissions/list/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/permissions/list/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/permissions/some/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/permissions/some/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/sessions/DELETE.js +1 -1
- package/dist/kempo/api/user/[userid]/sessions/DELETE.js.map +1 -1
- package/dist/kempo/api/user/[userid]/sessions/GET.js +1 -1
- package/dist/kempo/api/user/[userid]/sessions/GET.js.map +1 -1
- package/dist/kempo/api/user/[userid]/sessions/expired/DELETE.js +1 -1
- package/dist/kempo/api/user/[userid]/sessions/expired/DELETE.js.map +1 -1
- package/dist/kempo/api/user/create/POST.js +1 -1
- package/dist/kempo/api/user/create/POST.js.map +1 -1
- package/dist/kempo/api/user/search/GET.js +1 -1
- package/dist/kempo/api/user/search/GET.js.map +1 -1
- package/dist/kempo/components/LogoutBtn.js +1 -1
- package/dist/kempo/components/LogoutBtn.js.map +1 -1
- package/dist/kempo/components/Menu.js +9 -9
- package/dist/kempo/components/Menu.js.map +1 -1
- package/dist/kempo/components/Permission.js +1 -1
- package/dist/kempo/components/Permission.js.map +1 -1
- package/dist/kempo/components/Role.js +1 -1
- package/dist/kempo/components/Role.js.map +1 -1
- package/dist/kempo/components/UserCreatedAt.js +1 -1
- package/dist/kempo/components/UserCreatedAt.js.map +1 -1
- package/dist/kempo/components/UserEmail.js +1 -1
- package/dist/kempo/components/UserEmail.js.map +1 -1
- package/dist/kempo/components/UserEmailVerified.js +1 -1
- package/dist/kempo/components/UserEmailVerified.js.map +1 -1
- package/dist/kempo/components/UserName.js +1 -1
- package/dist/kempo/components/UserName.js.map +1 -1
- package/dist/kempo/fetch.js +1 -1
- package/dist/kempo/fetch.js.map +1 -1
- package/dist/kempo/sdk.js +1 -1
- package/dist/kempo/sdk.js.map +1 -1
- package/middleware/kempo.js +36 -6
- package/package.json +2 -2
- package/server/utils/extensions/installExtension.js +19 -13
- package/server/utils/extensions/uninstallExtension.js +6 -10
- package/server/utils/pages/deletePage.js +2 -10
- package/dist/admin/accounts/groups/[name]/index.html +0 -518
- package/dist/admin/accounts/groups/index.html +0 -378
- package/dist/admin/accounts/permissions/index.html +0 -397
- package/dist/admin/accounts/users/[id]/index.html +0 -541
- package/dist/admin/accounts/users/index.html +0 -396
- package/dist/admin/content/fragments/edit/index.html +0 -132
- package/dist/admin/content/fragments/index.html +0 -375
- package/dist/admin/content/globals/edit/index.html +0 -132
- package/dist/admin/content/globals/index.html +0 -358
- package/dist/admin/content/pages/edit/index.html +0 -132
- package/dist/admin/content/pages/index.html +0 -509
- package/dist/admin/content/templates/edit/index.html +0 -132
- package/dist/admin/content/templates/index.html +0 -429
- package/dist/admin/extensions/index.html +0 -222
- package/dist/admin/index.html +0 -130
- package/dist/admin/settings/[owner]/[name]/index.html +0 -449
- package/dist/admin/settings/index.html +0 -410
package/bin/cli.js
CHANGED
|
@@ -289,6 +289,18 @@ if(!useDefaults){
|
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
+
let wantsDrizzleStudio = false;
|
|
293
|
+
|
|
294
|
+
if(!useDefaults){
|
|
295
|
+
const { drizzleStudio } = await inquirer.prompt([{
|
|
296
|
+
type: 'confirm',
|
|
297
|
+
name: 'drizzleStudio',
|
|
298
|
+
message: 'Would you like to install drizzle-studio? It is used for interacting with the database during development, not recommended for production.',
|
|
299
|
+
default: true
|
|
300
|
+
}]);
|
|
301
|
+
wantsDrizzleStudio = drizzleStudio;
|
|
302
|
+
}
|
|
303
|
+
|
|
292
304
|
/*
|
|
293
305
|
Step 3: Scaffold project files
|
|
294
306
|
*/
|
|
@@ -297,15 +309,19 @@ console.log('\n--- Scaffolding project files ---\n');
|
|
|
297
309
|
|
|
298
310
|
const pkgPath = join(projectDir, 'package.json');
|
|
299
311
|
if(!existsSync(pkgPath)){
|
|
312
|
+
const scripts = {
|
|
313
|
+
dev: 'kempo-server --root public --port 9876',
|
|
314
|
+
start: 'kempo-server --root public --port 9876'
|
|
315
|
+
};
|
|
316
|
+
if(wantsDrizzleStudio){
|
|
317
|
+
scripts['db:studio'] = 'drizzle-kit studio';
|
|
318
|
+
}
|
|
300
319
|
writeFileSync(pkgPath, JSON.stringify({
|
|
301
320
|
name: projectName,
|
|
302
321
|
version: '1.0.0',
|
|
303
322
|
type: 'module',
|
|
304
323
|
private: true,
|
|
305
|
-
scripts
|
|
306
|
-
dev: 'kempo-server --root public --port 9876',
|
|
307
|
-
start: 'kempo-server --root public --port 9876'
|
|
308
|
-
}
|
|
324
|
+
scripts
|
|
309
325
|
}, null, 2) + '\n');
|
|
310
326
|
console.log('Created package.json');
|
|
311
327
|
}
|
|
@@ -511,4 +527,5 @@ Next steps:
|
|
|
511
527
|
Then open:
|
|
512
528
|
http://localhost:9876 (your site)
|
|
513
529
|
http://localhost:9876/admin (admin panel)
|
|
530
|
+
${wantsDrizzleStudio ? '\nTo view your database:\n npm run db:studio\n' : ''}
|
|
514
531
|
`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import o from"/kempo-ui/components/tableControls/TableControl.js";import{html as t}from"/kempo-ui/lit-all.min.js";import"/kempo-ui/components/Icon.js";export default class n extends o{render(){return t`
|
|
2
2
|
<button class="no-btn icon-btn" title="Add to Group">
|
|
3
3
|
<k-icon name="add"></k-icon>
|
|
4
4
|
</button>
|
|
5
|
-
`}}customElements.define("admin-add-group-control",
|
|
5
|
+
`}}customElements.define("admin-add-group-control",n);
|
|
6
6
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\AddGroupControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\AddGroupControl.js","names":["TableControl","html","AddGroupControl","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class AddGroupControl extends TableControl {\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" title=\"Add to Group\">\r\n <k-icon name=\"add\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-add-group-control', AddGroupControl);\r\n"],"mappings":"OAAOA,
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\AddGroupControl.js","names":["TableControl","html","AddGroupControl","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class AddGroupControl extends TableControl {\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" title=\"Add to Group\">\r\n <k-icon name=\"add\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-add-group-control', AddGroupControl);\r\n"],"mappings":"OAAOA,MAAkB,oEAChBC,MAAY,iCACd,8CAEQ,MAAMC,UAAwBF,EAC3C,MAAAG,GACE,OAAOF,CAAI;;;;KAKb,EAGFG,eAAeC,OAAO,0BAA2BH","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/tableControls/TableControl.js";import{html as o}from"/kempo-ui/lit-all.min.js";import"/kempo-ui/components/Icon.js";export default class n extends e{render(){return o`
|
|
2
2
|
<button class="no-btn icon-btn" title="Clear Expired Sessions">
|
|
3
3
|
<k-icon name="timer_off"></k-icon>
|
|
4
4
|
</button>
|
|
5
|
-
`}}customElements.define("admin-clear-expired-sessions",
|
|
5
|
+
`}}customElements.define("admin-clear-expired-sessions",n);
|
|
6
6
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\ClearExpiredSessionsControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\ClearExpiredSessionsControl.js","names":["TableControl","html","ClearExpiredSessionsControl","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class ClearExpiredSessionsControl extends TableControl {\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" title=\"Clear Expired Sessions\">\r\n <k-icon name=\"timer_off\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-clear-expired-sessions', ClearExpiredSessionsControl);\r\n"],"mappings":"OAAOA,
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\ClearExpiredSessionsControl.js","names":["TableControl","html","ClearExpiredSessionsControl","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class ClearExpiredSessionsControl extends TableControl {\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" title=\"Clear Expired Sessions\">\r\n <k-icon name=\"timer_off\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-clear-expired-sessions', ClearExpiredSessionsControl);\r\n"],"mappings":"OAAOA,MAAkB,oEAChBC,MAAY,iCACd,8CAEQ,MAAMC,UAAoCF,EACvD,MAAAG,GACE,OAAOF,CAAI;;;;KAKb,EAGFG,eAAeC,OAAO,+BAAgCH","ignoreList":[]}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/ShadowComponent.js";import{html as t}from"/kempo-ui/lit-all.min.js";import{getFragment as a,updateFragment as n,deleteFragments as i,moveFragment as r,listDirectories as s}from"/kempo/sdk.js";import o from"/kempo-ui/components/Dialog.js";import l from"/kempo-ui/components/Toast.js";import"/kempo-ui/components/Icon.js";import"/kempo-ui/components/Accordion.js";import"/kempo-ui/components/CodeEditor.js";export default class d extends e{static properties={loading:{state:!0},error:{state:!0},saving:{state:!0},fragment:{state:!0}};constructor(){super(),this.loading=!0,this.error=!1,this.saving=!1,this.fragment=null,this.file=""}async connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this.handleKeyDown);const e=new URLSearchParams(window.location.search).get("fragment");if(this.file=e?e+".fragment.html":"",!this.file)return this.loading=!1,void(this.error=!0);const[t,n]=await a(this.file);this.loading=!1,t?this.error=!0:(this.fragment=n,document.title=`Edit: ${n.name} - Admin`)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown)}getFormState(){const e=this.shadowRoot;return{name:e.querySelector("#metaName")?.value??this.fragment.name,markup:e.querySelector("k-code-editor")?.getValue()??this.fragment.markup}}handleKeyDown=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),this.saving||this.fragment?.locked||this.handleSave())};handleDelete=()=>{o.confirm("Delete this fragment? This action cannot be undone.",async e=>{if(!e)return;const[t]=await i([this.file]);t?l.error(t.msg||"Failed to delete fragment"):(l.success("Fragment deleted"),setTimeout(()=>{window.location.href="/admin/content/fragments"},1e3))})};handleMove=async()=>{const[,e]=await s(),a=e?.directories||["."],i=this.file.replace(/\.fragment\.html$/,"").split("/"),d=i.pop(),m=i.join("/")||".",c=e=>(e||"/").replace(/^\//,"").replace(/\/$/,"")||".",g="."===m?"/":"/"+m,p=o.create(t`
|
|
2
2
|
<div class="p">
|
|
3
3
|
<div class="mb">
|
|
4
4
|
<label class="d-b mb-sm"><strong>Location</strong></label>
|
|
5
|
-
<input type="text" id="dlg-move-dir" class="full" list="dlg-move-dir-list" .value="${
|
|
5
|
+
<input type="text" id="dlg-move-dir" class="full" list="dlg-move-dir-list" .value="${g}" placeholder="/">
|
|
6
6
|
<datalist id="dlg-move-dir-list">
|
|
7
|
-
${
|
|
7
|
+
${a.map(e=>t`<option value="${"."===e?"/":"/"+e}">`)}
|
|
8
8
|
</datalist>
|
|
9
9
|
</div>
|
|
10
10
|
<div>
|
|
11
11
|
<label class="d-b mb-sm"><strong>Fragment Name</strong></label>
|
|
12
|
-
<input type="text" id="dlg-move-name" class="full" .value="${
|
|
12
|
+
<input type="text" id="dlg-move-name" class="full" .value="${d}">
|
|
13
13
|
<p class="mt-sm muted"><small id="dlg-move-preview"></small></p>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
|
-
`,{title:"Move Fragment",confirmText:"Save and Move Fragment",confirmAction:async()=>{const e=
|
|
16
|
+
`,{title:"Move Fragment",confirmText:"Save and Move Fragment",confirmAction:async()=>{const e=p.querySelector("#dlg-move-dir").value.trim()||"/",t=p.querySelector("#dlg-move-name").value.trim();if(!t)return void l.error("Fragment name is required");if(!/^\/[a-zA-Z0-9_\-\[\]\/]*$/.test(a=e)||a.includes("..")||a.includes("//"))return void l.error("Invalid directory path");var a;const i=c(e),s="."===i?`${t}.fragment.html`:`${i}/${t}.fragment.html`;this.saving=!0;const[o]=await n({file:this.file,markup:this.getFormState().markup});if(this.saving=!1,o)return void l.error(o.msg||"Failed to save fragment");const[d,m]=await r({file:this.file,newFile:s});if(d)return void l.error(d.msg||"Failed to move fragment");l.success("Fragment saved and moved");const g=m.file.replace(/\.fragment\.html$/,"");setTimeout(()=>{window.location.href=`/admin/content/fragments/edit?fragment=${encodeURIComponent(g)}`},1e3)},cancelText:"Cancel"}),v=()=>{const e=c(p.querySelector("#dlg-move-dir").value||"/"),t=p.querySelector("#dlg-move-name").value,a="."===e?"/":"/"+e+"/";p.querySelector("#dlg-move-preview").textContent=t?a+t:""};p.querySelector("#dlg-move-dir").addEventListener("input",v),p.querySelector("#dlg-move-name").addEventListener("input",v),v()};handleReset=()=>{o.confirm("Reset this fragment? Any unsaved changes will be lost.",e=>{e&&(this.fragment={...this.fragment})})};handleSave=async()=>{this.saving=!0;const e=this.getFormState(),[t,a]=await n({file:this.file,markup:e.markup});if(this.saving=!1,t)return void l.error(t.msg||"Failed to save fragment");this.fragment={...this.fragment,markup:e.markup,updatedAt:a.updatedAt};const i=this.file.replace(/\.fragment\.html$/,"").split("/"),s=i.pop(),o=i.join("/"),d=e.name.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(d&&d!==s){const e=o?`${o}/${d}.fragment.html`:`${d}.fragment.html`,[t,a]=await r({file:this.file,newFile:e});if(t)return void l.error(t.msg||"Failed to rename fragment file");l.success("Fragment saved and renamed");const n=a.file.replace(/\.fragment\.html$/,"");return void setTimeout(()=>{window.location.href=`/admin/content/fragments/edit?fragment=${encodeURIComponent(n)}`},1e3)}document.title=`Edit: ${this.fragment.name} - Admin`,l.success("Fragment saved")};render(){if(this.loading)return t`<div>Loading fragment...</div>`;if(this.error)return t`
|
|
17
17
|
<div>
|
|
18
18
|
<p>Fragment not found.</p>
|
|
19
19
|
<a href="/admin/content/fragments">Back to Fragments</a>
|
|
20
20
|
</div>
|
|
21
|
-
`;const{fragment:e}=this,
|
|
22
|
-
${
|
|
21
|
+
`;const{fragment:e}=this,a="custom"===e.owner,n=e.locked;return t`
|
|
22
|
+
${n?t`
|
|
23
23
|
<div class="p r mb bc-warning tc-warning">
|
|
24
|
-
<k-icon name="lock"></k-icon> This fragment is locked and cannot be edited.
|
|
24
|
+
<k-icon name="lock"></k-icon> This fragment is locked and cannot be edited. ${"custom"===e.owner?"Locked by developer":`Managed by: ${e.owner||"external system"}`}
|
|
25
25
|
</div>
|
|
26
26
|
`:""}
|
|
27
27
|
<div class="d-f mb">
|
|
@@ -31,13 +31,13 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
31
31
|
</a>
|
|
32
32
|
</div>
|
|
33
33
|
<div class="flex"></div>
|
|
34
|
-
${
|
|
34
|
+
${a&&!n?t`
|
|
35
35
|
<div class="btn-grp mrh mb">
|
|
36
36
|
<button class="danger" @click="${this.handleDelete}"><k-icon name="delete"></k-icon> Delete</button>
|
|
37
37
|
<button @click="${this.handleMove}"><k-icon name="drive_file_move"></k-icon> Move Fragment</button>
|
|
38
38
|
</div>
|
|
39
39
|
`:""}
|
|
40
|
-
${
|
|
40
|
+
${n?"":t`
|
|
41
41
|
<div class="btn-grp mrh mb">
|
|
42
42
|
<button @click="${this.handleReset}"><k-icon name="restart_alt"></k-icon> Reset</button>
|
|
43
43
|
<button id="saveBtn" class="primary" ?disabled="${this.saving}" @click="${this.handleSave}">
|
|
@@ -55,16 +55,16 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
55
55
|
<div class="p">
|
|
56
56
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
57
57
|
<label style="min-width: 120px;"><strong>Name</strong></label>
|
|
58
|
-
<input type="text" id="metaName" class="flex" .value="${e.name||""}" ?disabled="${!
|
|
58
|
+
<input type="text" id="metaName" class="flex" .value="${e.name||""}" ?disabled="${!a||n}">
|
|
59
59
|
</div>
|
|
60
60
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
61
61
|
<label style="min-width: 120px;"><strong>Directory</strong></label>
|
|
62
62
|
<span class="muted">${(()=>{const e=this.file.replace(/\.fragment\.html$/,"").split("/");return e.pop(),e.length?e.join("/"):"/"})()}</span>
|
|
63
|
-
${
|
|
63
|
+
${a&&!n?t`
|
|
64
64
|
<button class="icon-btn no-btn ph" title="Move Fragment" @click="${this.handleMove}"><k-icon name="drive_file_move"></k-icon></button>
|
|
65
65
|
`:""}
|
|
66
66
|
</div>
|
|
67
|
-
${e.author?
|
|
67
|
+
${e.author?t`
|
|
68
68
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
69
69
|
<label style="min-width: 120px;"><strong>Author</strong></label>
|
|
70
70
|
<span class="muted">${e.author}</span>
|
|
@@ -92,10 +92,10 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
92
92
|
language="html"
|
|
93
93
|
.value="${e.markup||""}"
|
|
94
94
|
style="height: 500px;"
|
|
95
|
-
?disabled="${
|
|
95
|
+
?disabled="${n}"
|
|
96
96
|
></k-code-editor>
|
|
97
97
|
</div>
|
|
98
98
|
</k-accordion-panel>
|
|
99
99
|
</k-accordion>
|
|
100
|
-
`}}customElements.define("admin-fragment-editor",
|
|
100
|
+
`}}customElements.define("admin-fragment-editor",d);
|
|
101
101
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\FragmentEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\FragmentEditor.js","names":["ShadowComponent","html","getFragment","updateFragment","deleteFragments","moveFragment","listDirectories","Dialog","Toast","FragmentEditor","static","loading","state","error","saving","fragment","constructor","super","this","file","connectedCallback","document","addEventListener","handleKeyDown","param","URLSearchParams","window","location","search","get","err","title","name","disconnectedCallback","removeEventListener","getFormState","root","shadowRoot","querySelector","value","markup","getValue","e","ctrlKey","metaKey","key","preventDefault","locked","handleSave","handleDelete","confirm","async","confirmed","msg","success","setTimeout","href","handleMove","dirData","directories","parts","replace","split","currentName","pop","currentDir","join","dirToInternal","p","currentDirDisplay","$dialog","create","map","d","confirmText","confirmAction","dirInput","trim","newName","test","includes","newDir","newFile","saveError","moveError","moved","newParam","encodeURIComponent","cancelText","updatePreview","dir","prefix","textContent","handleReset","saved","updatedAt","currentSlug","newSlug","toLowerCase","render","isCustom","owner","isLocked","length","author","createdAt","Date","toLocaleString","customElements","define"],"sources":["0"],"sourcesContent":["import ShadowComponent from '/kempo-ui/components/ShadowComponent.js';\nimport { html } from '/kempo-ui/lit-all.min.js';\nimport { getFragment, updateFragment, deleteFragments, moveFragment, listDirectories } from '/kempo/sdk.js';\nimport Dialog from '/kempo-ui/components/Dialog.js';\nimport Toast from '/kempo-ui/components/Toast.js';\nimport '/kempo-ui/components/Icon.js';\nimport '/kempo-ui/components/Accordion.js';\nimport '/kempo-ui/components/CodeEditor.js';\n\nexport default class FragmentEditor extends ShadowComponent {\n static properties = {\n loading: { state: true },\n error: { state: true },\n saving: { state: true },\n fragment: { state: true }\n };\n\n constructor() {\n super();\n this.loading = true;\n this.error = false;\n this.saving = false;\n this.fragment = null;\n this.file = '';\n }\n\n async connectedCallback() {\n super.connectedCallback();\n document.addEventListener('keydown', this.handleKeyDown);\n const param = new URLSearchParams(window.location.search).get('fragment');\n this.file = param ? param + '.fragment.html' : '';\n\n if(!this.file){\n this.loading = false;\n this.error = true;\n return;\n }\n\n const [err, fragment] = await getFragment(this.file);\n this.loading = false;\n\n if(err){\n this.error = true;\n return;\n }\n\n this.fragment = fragment;\n document.title = `Edit: ${fragment.name} - Admin`;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /*\n Helpers\n */\n\n getFormState() {\n const root = this.shadowRoot;\n return {\n name: root.querySelector('#metaName')?.value ?? this.fragment.name,\n markup: root.querySelector('k-code-editor')?.getValue() ?? this.fragment.markup\n };\n }\n\n /*\n Event Handlers\n */\n\n handleKeyDown = e => {\n if((e.ctrlKey || e.metaKey) && e.key === 's'){\n e.preventDefault();\n if(!this.saving && !this.fragment?.locked) this.handleSave();\n }\n };\n\n handleDelete = () => {\n Dialog.confirm('Delete this fragment? This action cannot be undone.', async confirmed => {\n if(!confirmed) return;\n const [error] = await deleteFragments([this.file]);\n if(error){\n Toast.error(error.msg || 'Failed to delete fragment');\n return;\n }\n Toast.success('Fragment deleted');\n setTimeout(() => { window.location.href = '/admin/content/fragments'; }, 1000);\n });\n };\n\n handleMove = async () => {\n const [, dirData] = await listDirectories();\n const directories = dirData?.directories || ['.'];\n\n const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/');\n const currentName = parts.pop();\n const currentDir = parts.join('/') || '.';\n\n const isValidDir = p => /^\\/[a-zA-Z0-9_\\-\\[\\]\\/]*$/.test(p) && !p.includes('..') && !p.includes('//');\n const dirToInternal = p => { const t = (p || '/').replace(/^\\//, '').replace(/\\/$/, ''); return t || '.'; };\n const currentDirDisplay = currentDir === '.' ? '/' : '/' + currentDir;\n\n const $dialog = Dialog.create(html`\n <div class=\"p\">\n <div class=\"mb\">\n <label class=\"d-b mb-sm\"><strong>Location</strong></label>\n <input type=\"text\" id=\"dlg-move-dir\" class=\"full\" list=\"dlg-move-dir-list\" .value=\"${currentDirDisplay}\" placeholder=\"/\">\n <datalist id=\"dlg-move-dir-list\">\n ${directories.map(d => html`<option value=\"${d === '.' ? '/' : '/' + d}\">`)}\n </datalist>\n </div>\n <div>\n <label class=\"d-b mb-sm\"><strong>Fragment Name</strong></label>\n <input type=\"text\" id=\"dlg-move-name\" class=\"full\" .value=\"${currentName}\">\n <p class=\"mt-sm muted\"><small id=\"dlg-move-preview\"></small></p>\n </div>\n </div>\n `, {\n title: 'Move Fragment',\n confirmText: 'Save and Move Fragment',\n confirmAction: async () => {\n const dirInput = $dialog.querySelector('#dlg-move-dir').value.trim() || '/';\n const newName = $dialog.querySelector('#dlg-move-name').value.trim();\n if(!newName){\n Toast.error('Fragment name is required');\n return;\n }\n if(!isValidDir(dirInput)){\n Toast.error('Invalid directory path');\n return;\n }\n const newDir = dirToInternal(dirInput);\n const newFile = newDir === '.'\n ? `${newName}.fragment.html`\n : `${newDir}/${newName}.fragment.html`;\n\n this.saving = true;\n const [saveError] = await updateFragment({ file: this.file, markup: this.getFormState().markup });\n this.saving = false;\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save fragment');\n return;\n }\n\n const [moveError, moved] = await moveFragment({ file: this.file, newFile });\n if(moveError){\n Toast.error(moveError.msg || 'Failed to move fragment');\n return;\n }\n\n Toast.success('Fragment saved and moved');\n const newParam = moved.file.replace(/\\.fragment\\.html$/, '');\n setTimeout(() => {\n window.location.href = `/admin/content/fragments/edit?fragment=${encodeURIComponent(newParam)}`;\n }, 1000);\n },\n cancelText: 'Cancel'\n });\n\n const updatePreview = () => {\n const dir = dirToInternal($dialog.querySelector('#dlg-move-dir').value || '/');\n const name = $dialog.querySelector('#dlg-move-name').value;\n const prefix = dir === '.' ? '/' : '/' + dir + '/';\n $dialog.querySelector('#dlg-move-preview').textContent = name ? prefix + name : '';\n };\n $dialog.querySelector('#dlg-move-dir').addEventListener('input', updatePreview);\n $dialog.querySelector('#dlg-move-name').addEventListener('input', updatePreview);\n updatePreview();\n };\n\n handleReset = () => {\n Dialog.confirm('Reset this fragment? Any unsaved changes will be lost.', confirmed => {\n if(!confirmed) return;\n this.fragment = { ...this.fragment };\n });\n };\n\n handleSave = async () => {\n this.saving = true;\n const state = this.getFormState();\n const [saveError, saved] = await updateFragment({ file: this.file, markup: state.markup });\n this.saving = false;\n\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save fragment');\n return;\n }\n\n this.fragment = { ...this.fragment, markup: state.markup, updatedAt: saved.updatedAt };\n\n const slugify = n => n.toLowerCase().trim().replace(/[^\\w\\s-]/g, '').replace(/[\\s_]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');\n const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/');\n const currentSlug = parts.pop();\n const dir = parts.join('/');\n const newSlug = slugify(state.name);\n\n if(newSlug && newSlug !== currentSlug){\n const newFile = dir ? `${dir}/${newSlug}.fragment.html` : `${newSlug}.fragment.html`;\n const [moveError, moved] = await moveFragment({ file: this.file, newFile });\n if(moveError){\n Toast.error(moveError.msg || 'Failed to rename fragment file');\n return;\n }\n Toast.success('Fragment saved and renamed');\n const newParam = moved.file.replace(/\\.fragment\\.html$/, '');\n setTimeout(() => {\n window.location.href = `/admin/content/fragments/edit?fragment=${encodeURIComponent(newParam)}`;\n }, 1000);\n return;\n }\n\n document.title = `Edit: ${this.fragment.name} - Admin`;\n Toast.success('Fragment saved');\n };\n\n /*\n Render\n */\n\n render() {\n if(this.loading) return html`<div>Loading fragment...</div>`;\n\n if(this.error) return html`\n <div>\n <p>Fragment not found.</p>\n <a href=\"/admin/content/fragments\">Back to Fragments</a>\n </div>\n `;\n\n const { fragment } = this;\n const isCustom = fragment.owner === 'custom';\n const isLocked = fragment.locked;\n\n return html`\n ${isLocked ? html`\n <div class=\"p r mb bc-warning tc-warning\">\n <k-icon name=\"lock\"></k-icon> This fragment is locked and cannot be edited. It is managed by ${isCustom ? 'an extension' : 'the system'}.\n </div>\n ` : ''}\n <div class=\"d-f mb\">\n <div class=\"btn-grp mrh mb\">\n <a href=\"/admin/content/fragments\" class=\"btn\">\n <k-icon name=\"arrow\" direction=\"left\"></k-icon> Fragments\n </a>\n </div>\n <div class=\"flex\"></div>\n ${isCustom && !isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button class=\"danger\" @click=\"${this.handleDelete}\"><k-icon name=\"delete\"></k-icon> Delete</button>\n <button @click=\"${this.handleMove}\"><k-icon name=\"drive_file_move\"></k-icon> Move Fragment</button>\n </div>\n ` : ''}\n ${!isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button @click=\"${this.handleReset}\"><k-icon name=\"restart_alt\"></k-icon> Reset</button>\n <button id=\"saveBtn\" class=\"primary\" ?disabled=\"${this.saving}\" @click=\"${this.handleSave}\">\n <k-icon name=\"save\"></k-icon> Save\n </button>\n </div>\n ` : ''}\n </div>\n\n <h1 class=\"mb\">Fragment: ${fragment.name}</h1>\n\n <k-accordion>\n <k-accordion-header for-panel=\"metadata\">Metadata</k-accordion-header>\n <k-accordion-panel name=\"metadata\">\n <div class=\"p\">\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Name</strong></label>\n <input type=\"text\" id=\"metaName\" class=\"flex\" .value=\"${fragment.name || ''}\" ?disabled=\"${!isCustom || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Directory</strong></label>\n <span class=\"muted\">${(() => { const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/'); parts.pop(); return parts.length ? parts.join('/') : '/'; })()}</span>\n ${isCustom && !isLocked ? html`\n <button class=\"icon-btn no-btn ph\" title=\"Move Fragment\" @click=\"${this.handleMove}\"><k-icon name=\"drive_file_move\"></k-icon></button>\n ` : ''}\n </div>\n ${fragment.author ? html`\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Author</strong></label>\n <span class=\"muted\">${fragment.author}</span>\n </div>\n ` : ''}\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Owner</strong></label>\n <span class=\"muted\">${fragment.owner || ''}</span>\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Created</strong></label>\n <span class=\"muted\">${fragment.createdAt ? new Date(fragment.createdAt).toLocaleString() : ''}</span>\n </div>\n <div class=\"d-f\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Updated</strong></label>\n <span class=\"muted\">${fragment.updatedAt ? new Date(fragment.updatedAt).toLocaleString() : ''}</span>\n </div>\n </div>\n </k-accordion-panel>\n <k-accordion-header for-panel=\"fragment\" active>Fragment</k-accordion-header>\n <k-accordion-panel name=\"fragment\" active>\n <div class=\"p\">\n <k-code-editor\n class=\"r b\"\n language=\"html\"\n .value=\"${fragment.markup || ''}\"\n style=\"height: 500px;\"\n ?disabled=\"${isLocked}\"\n ></k-code-editor>\n </div>\n </k-accordion-panel>\n </k-accordion>\n `;\n }\n}\n\ncustomElements.define('admin-fragment-editor', FragmentEditor);\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\FragmentEditor.js","names":["ShadowComponent","html","getFragment","updateFragment","deleteFragments","moveFragment","listDirectories","Dialog","Toast","FragmentEditor","static","loading","state","error","saving","fragment","constructor","super","this","file","connectedCallback","document","addEventListener","handleKeyDown","param","URLSearchParams","window","location","search","get","err","title","name","disconnectedCallback","removeEventListener","getFormState","root","shadowRoot","querySelector","value","markup","getValue","e","ctrlKey","metaKey","key","preventDefault","locked","handleSave","handleDelete","confirm","async","confirmed","msg","success","setTimeout","href","handleMove","dirData","directories","parts","replace","split","currentName","pop","currentDir","join","dirToInternal","p","currentDirDisplay","$dialog","create","map","d","confirmText","confirmAction","dirInput","trim","newName","test","includes","newDir","newFile","saveError","moveError","moved","newParam","encodeURIComponent","cancelText","updatePreview","dir","prefix","textContent","handleReset","saved","updatedAt","currentSlug","newSlug","toLowerCase","render","isCustom","owner","isLocked","length","author","createdAt","Date","toLocaleString","customElements","define"],"sources":["0"],"sourcesContent":["import ShadowComponent from '/kempo-ui/components/ShadowComponent.js';\nimport { html } from '/kempo-ui/lit-all.min.js';\nimport { getFragment, updateFragment, deleteFragments, moveFragment, listDirectories } from '/kempo/sdk.js';\nimport Dialog from '/kempo-ui/components/Dialog.js';\nimport Toast from '/kempo-ui/components/Toast.js';\nimport '/kempo-ui/components/Icon.js';\nimport '/kempo-ui/components/Accordion.js';\nimport '/kempo-ui/components/CodeEditor.js';\n\nexport default class FragmentEditor extends ShadowComponent {\n static properties = {\n loading: { state: true },\n error: { state: true },\n saving: { state: true },\n fragment: { state: true }\n };\n\n constructor() {\n super();\n this.loading = true;\n this.error = false;\n this.saving = false;\n this.fragment = null;\n this.file = '';\n }\n\n async connectedCallback() {\n super.connectedCallback();\n document.addEventListener('keydown', this.handleKeyDown);\n const param = new URLSearchParams(window.location.search).get('fragment');\n this.file = param ? param + '.fragment.html' : '';\n\n if(!this.file){\n this.loading = false;\n this.error = true;\n return;\n }\n\n const [err, fragment] = await getFragment(this.file);\n this.loading = false;\n\n if(err){\n this.error = true;\n return;\n }\n\n this.fragment = fragment;\n document.title = `Edit: ${fragment.name} - Admin`;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /*\n Helpers\n */\n\n getFormState() {\n const root = this.shadowRoot;\n return {\n name: root.querySelector('#metaName')?.value ?? this.fragment.name,\n markup: root.querySelector('k-code-editor')?.getValue() ?? this.fragment.markup\n };\n }\n\n /*\n Event Handlers\n */\n\n handleKeyDown = e => {\n if((e.ctrlKey || e.metaKey) && e.key === 's'){\n e.preventDefault();\n if(!this.saving && !this.fragment?.locked) this.handleSave();\n }\n };\n\n handleDelete = () => {\n Dialog.confirm('Delete this fragment? This action cannot be undone.', async confirmed => {\n if(!confirmed) return;\n const [error] = await deleteFragments([this.file]);\n if(error){\n Toast.error(error.msg || 'Failed to delete fragment');\n return;\n }\n Toast.success('Fragment deleted');\n setTimeout(() => { window.location.href = '/admin/content/fragments'; }, 1000);\n });\n };\n\n handleMove = async () => {\n const [, dirData] = await listDirectories();\n const directories = dirData?.directories || ['.'];\n\n const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/');\n const currentName = parts.pop();\n const currentDir = parts.join('/') || '.';\n\n const isValidDir = p => /^\\/[a-zA-Z0-9_\\-\\[\\]\\/]*$/.test(p) && !p.includes('..') && !p.includes('//');\n const dirToInternal = p => { const t = (p || '/').replace(/^\\//, '').replace(/\\/$/, ''); return t || '.'; };\n const currentDirDisplay = currentDir === '.' ? '/' : '/' + currentDir;\n\n const $dialog = Dialog.create(html`\n <div class=\"p\">\n <div class=\"mb\">\n <label class=\"d-b mb-sm\"><strong>Location</strong></label>\n <input type=\"text\" id=\"dlg-move-dir\" class=\"full\" list=\"dlg-move-dir-list\" .value=\"${currentDirDisplay}\" placeholder=\"/\">\n <datalist id=\"dlg-move-dir-list\">\n ${directories.map(d => html`<option value=\"${d === '.' ? '/' : '/' + d}\">`)}\n </datalist>\n </div>\n <div>\n <label class=\"d-b mb-sm\"><strong>Fragment Name</strong></label>\n <input type=\"text\" id=\"dlg-move-name\" class=\"full\" .value=\"${currentName}\">\n <p class=\"mt-sm muted\"><small id=\"dlg-move-preview\"></small></p>\n </div>\n </div>\n `, {\n title: 'Move Fragment',\n confirmText: 'Save and Move Fragment',\n confirmAction: async () => {\n const dirInput = $dialog.querySelector('#dlg-move-dir').value.trim() || '/';\n const newName = $dialog.querySelector('#dlg-move-name').value.trim();\n if(!newName){\n Toast.error('Fragment name is required');\n return;\n }\n if(!isValidDir(dirInput)){\n Toast.error('Invalid directory path');\n return;\n }\n const newDir = dirToInternal(dirInput);\n const newFile = newDir === '.'\n ? `${newName}.fragment.html`\n : `${newDir}/${newName}.fragment.html`;\n\n this.saving = true;\n const [saveError] = await updateFragment({ file: this.file, markup: this.getFormState().markup });\n this.saving = false;\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save fragment');\n return;\n }\n\n const [moveError, moved] = await moveFragment({ file: this.file, newFile });\n if(moveError){\n Toast.error(moveError.msg || 'Failed to move fragment');\n return;\n }\n\n Toast.success('Fragment saved and moved');\n const newParam = moved.file.replace(/\\.fragment\\.html$/, '');\n setTimeout(() => {\n window.location.href = `/admin/content/fragments/edit?fragment=${encodeURIComponent(newParam)}`;\n }, 1000);\n },\n cancelText: 'Cancel'\n });\n\n const updatePreview = () => {\n const dir = dirToInternal($dialog.querySelector('#dlg-move-dir').value || '/');\n const name = $dialog.querySelector('#dlg-move-name').value;\n const prefix = dir === '.' ? '/' : '/' + dir + '/';\n $dialog.querySelector('#dlg-move-preview').textContent = name ? prefix + name : '';\n };\n $dialog.querySelector('#dlg-move-dir').addEventListener('input', updatePreview);\n $dialog.querySelector('#dlg-move-name').addEventListener('input', updatePreview);\n updatePreview();\n };\n\n handleReset = () => {\n Dialog.confirm('Reset this fragment? Any unsaved changes will be lost.', confirmed => {\n if(!confirmed) return;\n this.fragment = { ...this.fragment };\n });\n };\n\n handleSave = async () => {\n this.saving = true;\n const state = this.getFormState();\n const [saveError, saved] = await updateFragment({ file: this.file, markup: state.markup });\n this.saving = false;\n\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save fragment');\n return;\n }\n\n this.fragment = { ...this.fragment, markup: state.markup, updatedAt: saved.updatedAt };\n\n const slugify = n => n.toLowerCase().trim().replace(/[^\\w\\s-]/g, '').replace(/[\\s_]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');\n const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/');\n const currentSlug = parts.pop();\n const dir = parts.join('/');\n const newSlug = slugify(state.name);\n\n if(newSlug && newSlug !== currentSlug){\n const newFile = dir ? `${dir}/${newSlug}.fragment.html` : `${newSlug}.fragment.html`;\n const [moveError, moved] = await moveFragment({ file: this.file, newFile });\n if(moveError){\n Toast.error(moveError.msg || 'Failed to rename fragment file');\n return;\n }\n Toast.success('Fragment saved and renamed');\n const newParam = moved.file.replace(/\\.fragment\\.html$/, '');\n setTimeout(() => {\n window.location.href = `/admin/content/fragments/edit?fragment=${encodeURIComponent(newParam)}`;\n }, 1000);\n return;\n }\n\n document.title = `Edit: ${this.fragment.name} - Admin`;\n Toast.success('Fragment saved');\n };\n\n /*\n Render\n */\n\n render() {\n if(this.loading) return html`<div>Loading fragment...</div>`;\n\n if(this.error) return html`\n <div>\n <p>Fragment not found.</p>\n <a href=\"/admin/content/fragments\">Back to Fragments</a>\n </div>\n `;\n\n const { fragment } = this;\n const isCustom = fragment.owner === 'custom';\n const isLocked = fragment.locked;\n\n return html`\n ${isLocked ? html`\n <div class=\"p r mb bc-warning tc-warning\">\n <k-icon name=\"lock\"></k-icon> This fragment is locked and cannot be edited. ${fragment.owner === 'custom' ? 'Locked by developer' : `Managed by: ${fragment.owner || 'external system'}`}\n </div>\n ` : ''}\n <div class=\"d-f mb\">\n <div class=\"btn-grp mrh mb\">\n <a href=\"/admin/content/fragments\" class=\"btn\">\n <k-icon name=\"arrow\" direction=\"left\"></k-icon> Fragments\n </a>\n </div>\n <div class=\"flex\"></div>\n ${isCustom && !isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button class=\"danger\" @click=\"${this.handleDelete}\"><k-icon name=\"delete\"></k-icon> Delete</button>\n <button @click=\"${this.handleMove}\"><k-icon name=\"drive_file_move\"></k-icon> Move Fragment</button>\n </div>\n ` : ''}\n ${!isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button @click=\"${this.handleReset}\"><k-icon name=\"restart_alt\"></k-icon> Reset</button>\n <button id=\"saveBtn\" class=\"primary\" ?disabled=\"${this.saving}\" @click=\"${this.handleSave}\">\n <k-icon name=\"save\"></k-icon> Save\n </button>\n </div>\n ` : ''}\n </div>\n\n <h1 class=\"mb\">Fragment: ${fragment.name}</h1>\n\n <k-accordion>\n <k-accordion-header for-panel=\"metadata\">Metadata</k-accordion-header>\n <k-accordion-panel name=\"metadata\">\n <div class=\"p\">\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Name</strong></label>\n <input type=\"text\" id=\"metaName\" class=\"flex\" .value=\"${fragment.name || ''}\" ?disabled=\"${!isCustom || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Directory</strong></label>\n <span class=\"muted\">${(() => { const parts = this.file.replace(/\\.fragment\\.html$/, '').split('/'); parts.pop(); return parts.length ? parts.join('/') : '/'; })()}</span>\n ${isCustom && !isLocked ? html`\n <button class=\"icon-btn no-btn ph\" title=\"Move Fragment\" @click=\"${this.handleMove}\"><k-icon name=\"drive_file_move\"></k-icon></button>\n ` : ''}\n </div>\n ${fragment.author ? html`\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Author</strong></label>\n <span class=\"muted\">${fragment.author}</span>\n </div>\n ` : ''}\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Owner</strong></label>\n <span class=\"muted\">${fragment.owner || ''}</span>\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Created</strong></label>\n <span class=\"muted\">${fragment.createdAt ? new Date(fragment.createdAt).toLocaleString() : ''}</span>\n </div>\n <div class=\"d-f\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Updated</strong></label>\n <span class=\"muted\">${fragment.updatedAt ? new Date(fragment.updatedAt).toLocaleString() : ''}</span>\n </div>\n </div>\n </k-accordion-panel>\n <k-accordion-header for-panel=\"fragment\" active>Fragment</k-accordion-header>\n <k-accordion-panel name=\"fragment\" active>\n <div class=\"p\">\n <k-code-editor\n class=\"r b\"\n language=\"html\"\n .value=\"${fragment.markup || ''}\"\n style=\"height: 500px;\"\n ?disabled=\"${isLocked}\"\n ></k-code-editor>\n </div>\n </k-accordion-panel>\n </k-accordion>\n `;\n }\n}\n\ncustomElements.define('admin-fragment-editor', FragmentEditor);\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/ShadowComponent.js";import{html as t}from"/kempo-ui/lit-all.min.js";import{getGlobalContent as n,updateGlobalContent as a,deleteGlobalContent as i}from"/kempo/sdk.js";import s from"/kempo-ui/components/Dialog.js";import o from"/kempo-ui/components/Toast.js";import"/kempo-ui/components/Icon.js";import"/kempo-ui/components/Accordion.js";import"/kempo-ui/components/CodeEditor.js";export default class r extends e{static properties={loading:{state:!0},error:{state:!0},saving:{state:!0},entry:{state:!0}};constructor(){super(),this.loading=!0,this.error=!1,this.saving=!1,this.entry=null,this.entryId=""}async connectedCallback(){if(super.connectedCallback(),document.addEventListener("keydown",this.handleKeyDown),this.entryId=new URLSearchParams(window.location.search).get("id")||"",!this.entryId)return this.loading=!1,void(this.error=!0);const[e,t]=await n(this.entryId);this.loading=!1,e?this.error=!0:(this.entry=t,document.title=`Edit: ${t.name||this.entryId} - Admin`)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown)}handleKeyDown=e=>{(e.ctrlKey||e.metaKey)&&"s"===e.key&&(e.preventDefault(),this.saving||this.entry?.locked||this.handleSave())};handleSave=async()=>{this.saving=!0;const e=this.shadowRoot,t=e.querySelector("#metaName").value,n=e.querySelector("#metaLocation").value,i=e.querySelector("#metaPriority").value,s=e.querySelector("k-code-editor"),r=s?s.getValue():this.entry.markup,[l,d]=await a({id:this.entryId,name:t,location:n,priority:i,markup:r});this.saving=!1,l?o.error(l.msg||"Failed to save global content"):(this.entry={...this.entry,name:t,location:n,priority:i,markup:r,updatedAt:d.updatedAt},document.title=`Edit: ${t||this.entryId} - Admin`,o.success("Global content saved"))};handleReset=()=>{s.confirm("Reset this entry? Any unsaved changes will be lost.",e=>{e&&(this.entry={...this.entry})})};handleDelete=()=>{s.confirm("Delete this global content entry? This action cannot be undone.",async e=>{if(!e)return;const[t]=await i([this.entryId]);t?o.error(t.msg||"Failed to delete global content"):(o.success("Global content deleted"),setTimeout(()=>{window.location.href="/admin/content/globals"},1e3))})};render(){if(this.loading)return t`<div>Loading global content...</div>`;if(this.error)return t`
|
|
2
2
|
<div>
|
|
3
3
|
<p>Global content entry not found.</p>
|
|
4
4
|
<a href="/admin/content/globals">Back to Global Content</a>
|
|
5
5
|
</div>
|
|
6
|
-
`;const{entry:e}=this,
|
|
7
|
-
${
|
|
6
|
+
`;const{entry:e}=this,n="system"===e.owner,a=e.locked;return t`
|
|
7
|
+
${a?t`
|
|
8
8
|
<div class="p r mb bc-warning tc-warning">
|
|
9
|
-
<k-icon name="lock"></k-icon> This entry is locked and cannot be edited.
|
|
9
|
+
<k-icon name="lock"></k-icon> This entry is locked and cannot be edited. ${"custom"===e.owner?"Locked by developer":`Managed by: ${e.owner||"external system"}`}
|
|
10
10
|
</div>
|
|
11
11
|
`:""}
|
|
12
12
|
<div class="d-f mb">
|
|
@@ -16,12 +16,12 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
16
16
|
</a>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="flex"></div>
|
|
19
|
-
${
|
|
19
|
+
${n||a?"":t`
|
|
20
20
|
<div class="btn-grp mrh mb">
|
|
21
21
|
<button class="danger" @click="${this.handleDelete}"><k-icon name="delete"></k-icon> Delete</button>
|
|
22
22
|
</div>
|
|
23
23
|
`}
|
|
24
|
-
${
|
|
24
|
+
${a?"":t`
|
|
25
25
|
<div class="btn-grp mrh mb">
|
|
26
26
|
<button @click="${this.handleReset}"><k-icon name="restart_alt"></k-icon> Reset</button>
|
|
27
27
|
<button id="saveBtn" class="primary" ?disabled="${this.saving}" @click="${this.handleSave}">
|
|
@@ -38,17 +38,17 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
38
38
|
<div class="p">
|
|
39
39
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
40
40
|
<label style="min-width: 120px;"><strong>Name</strong></label>
|
|
41
|
-
<input type="text" id="metaName" class="flex" .value="${e.name||""}" ?disabled="${
|
|
41
|
+
<input type="text" id="metaName" class="flex" .value="${e.name||""}" ?disabled="${n||a}">
|
|
42
42
|
</div>
|
|
43
43
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
44
44
|
<label style="min-width: 120px;"><strong>Location</strong></label>
|
|
45
|
-
<input type="text" id="metaLocation" class="flex" .value="${e.location||""}" ?disabled="${
|
|
45
|
+
<input type="text" id="metaLocation" class="flex" .value="${e.location||""}" ?disabled="${n||a}">
|
|
46
46
|
</div>
|
|
47
47
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
48
48
|
<label style="min-width: 120px;"><strong>Priority</strong></label>
|
|
49
|
-
<input type="number" id="metaPriority" class="flex" .value="${e.priority??0}" ?disabled="${
|
|
49
|
+
<input type="number" id="metaPriority" class="flex" .value="${e.priority??0}" ?disabled="${n||a}">
|
|
50
50
|
</div>
|
|
51
|
-
${
|
|
51
|
+
${n?"":t`
|
|
52
52
|
<div class="d-f mb" style="align-items: center; gap: var(--spacer);">
|
|
53
53
|
<label style="min-width: 120px;"><strong>Author</strong></label>
|
|
54
54
|
<span class="muted">${e.author||""}</span>
|
|
@@ -76,10 +76,10 @@ import ShadowComponent from"/kempo-ui/components/ShadowComponent.js";import{html
|
|
|
76
76
|
language="html"
|
|
77
77
|
.value="${e.markup||""}"
|
|
78
78
|
style="height: 500px;"
|
|
79
|
-
?disabled="${
|
|
79
|
+
?disabled="${a}"
|
|
80
80
|
></k-code-editor>
|
|
81
81
|
</div>
|
|
82
82
|
</k-accordion-panel>
|
|
83
83
|
</k-accordion>
|
|
84
|
-
`}}customElements.define("admin-global-content-editor",
|
|
84
|
+
`}}customElements.define("admin-global-content-editor",r);
|
|
85
85
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\GlobalContentEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\GlobalContentEditor.js","names":["ShadowComponent","html","getGlobalContent","updateGlobalContent","deleteGlobalContent","Dialog","Toast","GlobalContentEditor","static","loading","state","error","saving","entry","constructor","super","this","entryId","connectedCallback","document","addEventListener","handleKeyDown","URLSearchParams","window","location","search","get","err","title","name","disconnectedCallback","removeEventListener","e","ctrlKey","metaKey","key","preventDefault","locked","handleSave","async","root","shadowRoot","querySelector","value","priority","editor","markup","getValue","saveError","saved","id","msg","updatedAt","success","handleReset","confirm","confirmed","handleDelete","setTimeout","href","render","isSystem","owner","isLocked","author","createdAt","Date","toLocaleString","customElements","define"],"sources":["0"],"sourcesContent":["import ShadowComponent from '/kempo-ui/components/ShadowComponent.js';\nimport { html } from '/kempo-ui/lit-all.min.js';\nimport { getGlobalContent, updateGlobalContent, deleteGlobalContent } from '/kempo/sdk.js';\nimport Dialog from '/kempo-ui/components/Dialog.js';\nimport Toast from '/kempo-ui/components/Toast.js';\nimport '/kempo-ui/components/Icon.js';\nimport '/kempo-ui/components/Accordion.js';\nimport '/kempo-ui/components/CodeEditor.js';\n\nexport default class GlobalContentEditor extends ShadowComponent {\n static properties = {\n loading: { state: true },\n error: { state: true },\n saving: { state: true },\n entry: { state: true }\n };\n\n constructor() {\n super();\n this.loading = true;\n this.error = false;\n this.saving = false;\n this.entry = null;\n this.entryId = '';\n }\n\n async connectedCallback() {\n super.connectedCallback();\n document.addEventListener('keydown', this.handleKeyDown);\n this.entryId = new URLSearchParams(window.location.search).get('id') || '';\n\n if(!this.entryId){\n this.loading = false;\n this.error = true;\n return;\n }\n\n const [err, entry] = await getGlobalContent(this.entryId);\n this.loading = false;\n\n if(err){\n this.error = true;\n return;\n }\n\n this.entry = entry;\n document.title = `Edit: ${entry.name || this.entryId} - Admin`;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /*\n Event Handlers\n */\n\n handleKeyDown = e => {\n if((e.ctrlKey || e.metaKey) && e.key === 's'){\n e.preventDefault();\n if(!this.saving && !this.entry?.locked) this.handleSave();\n }\n };\n\n handleSave = async () => {\n this.saving = true;\n const root = this.shadowRoot;\n const name = root.querySelector('#metaName').value;\n const location = root.querySelector('#metaLocation').value;\n const priority = root.querySelector('#metaPriority').value;\n const editor = root.querySelector('k-code-editor');\n const markup = editor ? editor.getValue() : this.entry.markup;\n\n const [saveError, saved] = await updateGlobalContent({\n id: this.entryId, name, location, priority, markup\n });\n this.saving = false;\n\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save global content');\n return;\n }\n\n this.entry = { ...this.entry, name, location, priority, markup, updatedAt: saved.updatedAt };\n document.title = `Edit: ${name || this.entryId} - Admin`;\n Toast.success('Global content saved');\n };\n\n handleReset = () => {\n Dialog.confirm('Reset this entry? Any unsaved changes will be lost.', confirmed => {\n if(!confirmed) return;\n this.entry = { ...this.entry };\n });\n };\n\n handleDelete = () => {\n Dialog.confirm('Delete this global content entry? This action cannot be undone.', async confirmed => {\n if(!confirmed) return;\n const [error] = await deleteGlobalContent([this.entryId]);\n if(error){\n Toast.error(error.msg || 'Failed to delete global content');\n return;\n }\n Toast.success('Global content deleted');\n setTimeout(() => { window.location.href = '/admin/content/globals'; }, 1000);\n });\n };\n\n /*\n Render\n */\n\n render() {\n if(this.loading) return html`<div>Loading global content...</div>`;\n\n if(this.error) return html`\n <div>\n <p>Global content entry not found.</p>\n <a href=\"/admin/content/globals\">Back to Global Content</a>\n </div>\n `;\n\n const { entry } = this;\n const isSystem = entry.owner === 'system';\n const isLocked = entry.locked;\n\n return html`\n ${isLocked ? html`\n <div class=\"p r mb bc-warning tc-warning\">\n <k-icon name=\"lock\"></k-icon> This entry is locked and cannot be edited. It is managed by ${isSystem ? 'the system' : 'an extension'}.\n </div>\n ` : ''}\n <div class=\"d-f mb\">\n <div class=\"btn-grp mrh mb\">\n <a href=\"/admin/content/globals\" class=\"btn\">\n <k-icon name=\"arrow\" direction=\"left\"></k-icon> Global Content\n </a>\n </div>\n <div class=\"flex\"></div>\n ${!isSystem && !isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button class=\"danger\" @click=\"${this.handleDelete}\"><k-icon name=\"delete\"></k-icon> Delete</button>\n </div>\n ` : ''}\n ${!isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button @click=\"${this.handleReset}\"><k-icon name=\"restart_alt\"></k-icon> Reset</button>\n <button id=\"saveBtn\" class=\"primary\" ?disabled=\"${this.saving}\" @click=\"${this.handleSave}\">\n <k-icon name=\"save\"></k-icon> Save\n </button>\n </div>\n ` : ''}\n </div>\n <h1 class=\"mb\">Global Content: ${entry.name || this.entryId}</h1>\n\n <k-accordion>\n <k-accordion-header for-panel=\"metadata\">Metadata</k-accordion-header>\n <k-accordion-panel name=\"metadata\">\n <div class=\"p\">\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Name</strong></label>\n <input type=\"text\" id=\"metaName\" class=\"flex\" .value=\"${entry.name || ''}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Location</strong></label>\n <input type=\"text\" id=\"metaLocation\" class=\"flex\" .value=\"${entry.location || ''}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Priority</strong></label>\n <input type=\"number\" id=\"metaPriority\" class=\"flex\" .value=\"${entry.priority ?? 0}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n ${!isSystem ? html`\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Author</strong></label>\n <span class=\"muted\">${entry.author || ''}</span>\n </div>\n ` : ''}\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Owner</strong></label>\n <span class=\"muted\">${entry.owner || ''}</span>\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Created</strong></label>\n <span class=\"muted\">${entry.createdAt ? new Date(entry.createdAt).toLocaleString() : ''}</span>\n </div>\n <div class=\"d-f\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Updated</strong></label>\n <span class=\"muted\">${entry.updatedAt ? new Date(entry.updatedAt).toLocaleString() : ''}</span>\n </div>\n </div>\n </k-accordion-panel>\n <k-accordion-header for-panel=\"content\" active>Content</k-accordion-header>\n <k-accordion-panel name=\"content\" active>\n <div class=\"p\">\n <k-code-editor\n class=\"r b\"\n language=\"html\"\n .value=\"${entry.markup || ''}\"\n style=\"height: 500px;\"\n ?disabled=\"${isLocked}\"\n ></k-code-editor>\n </div>\n </k-accordion-panel>\n </k-accordion>\n `;\n }\n}\n\ncustomElements.define('admin-global-content-editor', GlobalContentEditor);\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\GlobalContentEditor.js","names":["ShadowComponent","html","getGlobalContent","updateGlobalContent","deleteGlobalContent","Dialog","Toast","GlobalContentEditor","static","loading","state","error","saving","entry","constructor","super","this","entryId","connectedCallback","document","addEventListener","handleKeyDown","URLSearchParams","window","location","search","get","err","title","name","disconnectedCallback","removeEventListener","e","ctrlKey","metaKey","key","preventDefault","locked","handleSave","async","root","shadowRoot","querySelector","value","priority","editor","markup","getValue","saveError","saved","id","msg","updatedAt","success","handleReset","confirm","confirmed","handleDelete","setTimeout","href","render","isSystem","owner","isLocked","author","createdAt","Date","toLocaleString","customElements","define"],"sources":["0"],"sourcesContent":["import ShadowComponent from '/kempo-ui/components/ShadowComponent.js';\nimport { html } from '/kempo-ui/lit-all.min.js';\nimport { getGlobalContent, updateGlobalContent, deleteGlobalContent } from '/kempo/sdk.js';\nimport Dialog from '/kempo-ui/components/Dialog.js';\nimport Toast from '/kempo-ui/components/Toast.js';\nimport '/kempo-ui/components/Icon.js';\nimport '/kempo-ui/components/Accordion.js';\nimport '/kempo-ui/components/CodeEditor.js';\n\nexport default class GlobalContentEditor extends ShadowComponent {\n static properties = {\n loading: { state: true },\n error: { state: true },\n saving: { state: true },\n entry: { state: true }\n };\n\n constructor() {\n super();\n this.loading = true;\n this.error = false;\n this.saving = false;\n this.entry = null;\n this.entryId = '';\n }\n\n async connectedCallback() {\n super.connectedCallback();\n document.addEventListener('keydown', this.handleKeyDown);\n this.entryId = new URLSearchParams(window.location.search).get('id') || '';\n\n if(!this.entryId){\n this.loading = false;\n this.error = true;\n return;\n }\n\n const [err, entry] = await getGlobalContent(this.entryId);\n this.loading = false;\n\n if(err){\n this.error = true;\n return;\n }\n\n this.entry = entry;\n document.title = `Edit: ${entry.name || this.entryId} - Admin`;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /*\n Event Handlers\n */\n\n handleKeyDown = e => {\n if((e.ctrlKey || e.metaKey) && e.key === 's'){\n e.preventDefault();\n if(!this.saving && !this.entry?.locked) this.handleSave();\n }\n };\n\n handleSave = async () => {\n this.saving = true;\n const root = this.shadowRoot;\n const name = root.querySelector('#metaName').value;\n const location = root.querySelector('#metaLocation').value;\n const priority = root.querySelector('#metaPriority').value;\n const editor = root.querySelector('k-code-editor');\n const markup = editor ? editor.getValue() : this.entry.markup;\n\n const [saveError, saved] = await updateGlobalContent({\n id: this.entryId, name, location, priority, markup\n });\n this.saving = false;\n\n if(saveError){\n Toast.error(saveError.msg || 'Failed to save global content');\n return;\n }\n\n this.entry = { ...this.entry, name, location, priority, markup, updatedAt: saved.updatedAt };\n document.title = `Edit: ${name || this.entryId} - Admin`;\n Toast.success('Global content saved');\n };\n\n handleReset = () => {\n Dialog.confirm('Reset this entry? Any unsaved changes will be lost.', confirmed => {\n if(!confirmed) return;\n this.entry = { ...this.entry };\n });\n };\n\n handleDelete = () => {\n Dialog.confirm('Delete this global content entry? This action cannot be undone.', async confirmed => {\n if(!confirmed) return;\n const [error] = await deleteGlobalContent([this.entryId]);\n if(error){\n Toast.error(error.msg || 'Failed to delete global content');\n return;\n }\n Toast.success('Global content deleted');\n setTimeout(() => { window.location.href = '/admin/content/globals'; }, 1000);\n });\n };\n\n /*\n Render\n */\n\n render() {\n if(this.loading) return html`<div>Loading global content...</div>`;\n\n if(this.error) return html`\n <div>\n <p>Global content entry not found.</p>\n <a href=\"/admin/content/globals\">Back to Global Content</a>\n </div>\n `;\n\n const { entry } = this;\n const isSystem = entry.owner === 'system';\n const isLocked = entry.locked;\n\n return html`\n ${isLocked ? html`\n <div class=\"p r mb bc-warning tc-warning\">\n <k-icon name=\"lock\"></k-icon> This entry is locked and cannot be edited. ${entry.owner === 'custom' ? 'Locked by developer' : `Managed by: ${entry.owner || 'external system'}`}\n </div>\n ` : ''}\n <div class=\"d-f mb\">\n <div class=\"btn-grp mrh mb\">\n <a href=\"/admin/content/globals\" class=\"btn\">\n <k-icon name=\"arrow\" direction=\"left\"></k-icon> Global Content\n </a>\n </div>\n <div class=\"flex\"></div>\n ${!isSystem && !isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button class=\"danger\" @click=\"${this.handleDelete}\"><k-icon name=\"delete\"></k-icon> Delete</button>\n </div>\n ` : ''}\n ${!isLocked ? html`\n <div class=\"btn-grp mrh mb\">\n <button @click=\"${this.handleReset}\"><k-icon name=\"restart_alt\"></k-icon> Reset</button>\n <button id=\"saveBtn\" class=\"primary\" ?disabled=\"${this.saving}\" @click=\"${this.handleSave}\">\n <k-icon name=\"save\"></k-icon> Save\n </button>\n </div>\n ` : ''}\n </div>\n <h1 class=\"mb\">Global Content: ${entry.name || this.entryId}</h1>\n\n <k-accordion>\n <k-accordion-header for-panel=\"metadata\">Metadata</k-accordion-header>\n <k-accordion-panel name=\"metadata\">\n <div class=\"p\">\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Name</strong></label>\n <input type=\"text\" id=\"metaName\" class=\"flex\" .value=\"${entry.name || ''}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Location</strong></label>\n <input type=\"text\" id=\"metaLocation\" class=\"flex\" .value=\"${entry.location || ''}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Priority</strong></label>\n <input type=\"number\" id=\"metaPriority\" class=\"flex\" .value=\"${entry.priority ?? 0}\" ?disabled=\"${isSystem || isLocked}\">\n </div>\n ${!isSystem ? html`\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Author</strong></label>\n <span class=\"muted\">${entry.author || ''}</span>\n </div>\n ` : ''}\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Owner</strong></label>\n <span class=\"muted\">${entry.owner || ''}</span>\n </div>\n <div class=\"d-f mb\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Created</strong></label>\n <span class=\"muted\">${entry.createdAt ? new Date(entry.createdAt).toLocaleString() : ''}</span>\n </div>\n <div class=\"d-f\" style=\"align-items: center; gap: var(--spacer);\">\n <label style=\"min-width: 120px;\"><strong>Updated</strong></label>\n <span class=\"muted\">${entry.updatedAt ? new Date(entry.updatedAt).toLocaleString() : ''}</span>\n </div>\n </div>\n </k-accordion-panel>\n <k-accordion-header for-panel=\"content\" active>Content</k-accordion-header>\n <k-accordion-panel name=\"content\" active>\n <div class=\"p\">\n <k-code-editor\n class=\"r b\"\n language=\"html\"\n .value=\"${entry.markup || ''}\"\n style=\"height: 500px;\"\n ?disabled=\"${isLocked}\"\n ></k-code-editor>\n </div>\n </k-accordion-panel>\n </k-accordion>\n `;\n }\n}\n\ncustomElements.define('admin-global-content-editor', GlobalContentEditor);\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/tableControls/TableControl.js";import{html as t}from"/kempo-ui/lit-all.min.js";import"/kempo-ui/components/Icon.js";export default class s extends e{constructor(){super({maxWidth:null}),this.selectionChangeHandler=()=>this.requestUpdate()}connectedCallback(){super.connectedCallback(),this.onTableEvent("selectionChange",this.selectionChangeHandler)}disconnectedCallback(){super.disconnectedCallback(),this.table&&this.table.removeEventListener("selectionChange",this.selectionChangeHandler)}deleteSelected=()=>{if(!this.table)return;const e=this.table.getSelectedRecords(),t=e.filter(e=>"system:Users"!==e.name);if(!t.length)return;const s=e.some(e=>"system:Users"===e.name);this.dispatchEvent(new CustomEvent("groupRemoveSelected",{detail:{records:t,systemUsersSkipped:s},bubbles:!0}))};get deletableCount(){return this.table?this.table.getSelectedRecords().filter(e=>"system:Users"!==e.name).length:0}render(){return t`
|
|
2
2
|
<button class="no-btn icon-btn" ?disabled="${0===this.deletableCount}" @click="${this.deleteSelected}">
|
|
3
3
|
<k-icon name="delete"></k-icon>
|
|
4
4
|
</button>
|
|
5
|
-
`}}customElements.define("admin-group-delete-selected",
|
|
5
|
+
`}}customElements.define("admin-group-delete-selected",s);
|
|
6
6
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\GroupDeleteSelected.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\GroupDeleteSelected.js","names":["TableControl","html","GroupDeleteSelected","constructor","super","maxWidth","this","selectionChangeHandler","requestUpdate","connectedCallback","onTableEvent","disconnectedCallback","table","removeEventListener","deleteSelected","selected","getSelectedRecords","records","filter","r","name","length","systemUsersSkipped","some","dispatchEvent","CustomEvent","detail","bubbles","deletableCount","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class GroupDeleteSelected extends TableControl {\r\n constructor() {\r\n super({ maxWidth: null });\r\n this.selectionChangeHandler = () => this.requestUpdate();\r\n }\r\n\r\n connectedCallback() {\r\n super.connectedCallback();\r\n this.onTableEvent('selectionChange', this.selectionChangeHandler);\r\n }\r\n\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n if(this.table) this.table.removeEventListener('selectionChange', this.selectionChangeHandler);\r\n }\r\n\r\n deleteSelected = () => {\r\n if(!this.table) return;\r\n const selected = this.table.getSelectedRecords();\r\n const records = selected.filter(r => r.name !== 'system:Users');\r\n if(!records.length) return;\r\n const systemUsersSkipped = selected.some(r => r.name === 'system:Users');\r\n this.dispatchEvent(new CustomEvent('groupRemoveSelected', {\r\n detail: { records, systemUsersSkipped },\r\n bubbles: true\r\n }));\r\n };\r\n\r\n get deletableCount() {\r\n if(!this.table) return 0;\r\n return this.table.getSelectedRecords().filter(r => r.name !== 'system:Users').length;\r\n }\r\n\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" ?disabled=\"${this.deletableCount === 0}\" @click=\"${this.deleteSelected}\">\r\n <k-icon name=\"delete\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-group-delete-selected', GroupDeleteSelected);\r\n"],"mappings":"OAAOA,
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\GroupDeleteSelected.js","names":["TableControl","html","GroupDeleteSelected","constructor","super","maxWidth","this","selectionChangeHandler","requestUpdate","connectedCallback","onTableEvent","disconnectedCallback","table","removeEventListener","deleteSelected","selected","getSelectedRecords","records","filter","r","name","length","systemUsersSkipped","some","dispatchEvent","CustomEvent","detail","bubbles","deletableCount","render","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class GroupDeleteSelected extends TableControl {\r\n constructor() {\r\n super({ maxWidth: null });\r\n this.selectionChangeHandler = () => this.requestUpdate();\r\n }\r\n\r\n connectedCallback() {\r\n super.connectedCallback();\r\n this.onTableEvent('selectionChange', this.selectionChangeHandler);\r\n }\r\n\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n if(this.table) this.table.removeEventListener('selectionChange', this.selectionChangeHandler);\r\n }\r\n\r\n deleteSelected = () => {\r\n if(!this.table) return;\r\n const selected = this.table.getSelectedRecords();\r\n const records = selected.filter(r => r.name !== 'system:Users');\r\n if(!records.length) return;\r\n const systemUsersSkipped = selected.some(r => r.name === 'system:Users');\r\n this.dispatchEvent(new CustomEvent('groupRemoveSelected', {\r\n detail: { records, systemUsersSkipped },\r\n bubbles: true\r\n }));\r\n };\r\n\r\n get deletableCount() {\r\n if(!this.table) return 0;\r\n return this.table.getSelectedRecords().filter(r => r.name !== 'system:Users').length;\r\n }\r\n\r\n render() {\r\n return html`\r\n <button class=\"no-btn icon-btn\" ?disabled=\"${this.deletableCount === 0}\" @click=\"${this.deleteSelected}\">\r\n <k-icon name=\"delete\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-group-delete-selected', GroupDeleteSelected);\r\n"],"mappings":"OAAOA,MAAkB,oEAChBC,MAAY,iCACd,8CAEQ,MAAMC,UAA4BF,EAC/C,WAAAG,GACEC,MAAM,CAAEC,SAAU,OAClBC,KAAKC,uBAAyB,IAAMD,KAAKE,eAC3C,CAEA,iBAAAC,GACEL,MAAMK,oBACNH,KAAKI,aAAa,kBAAmBJ,KAAKC,uBAC5C,CAEA,oBAAAI,GACEP,MAAMO,uBACHL,KAAKM,OAAON,KAAKM,MAAMC,oBAAoB,kBAAmBP,KAAKC,uBACxE,CAEAO,eAAiB,KACf,IAAIR,KAAKM,MAAO,OAChB,MAAMG,EAAWT,KAAKM,MAAMI,qBACtBC,EAAUF,EAASG,OAAOC,GAAgB,iBAAXA,EAAEC,MACvC,IAAIH,EAAQI,OAAQ,OACpB,MAAMC,EAAqBP,EAASQ,KAAKJ,GAAgB,iBAAXA,EAAEC,MAChDd,KAAKkB,cAAc,IAAIC,YAAY,sBAAuB,CACxDC,OAAQ,CAAET,UAASK,sBACnBK,SAAS,MAIb,kBAAIC,GACF,OAAItB,KAAKM,MACFN,KAAKM,MAAMI,qBAAqBE,OAAOC,GAAgB,iBAAXA,EAAEC,MAAyBC,OADvD,CAEzB,CAEA,MAAAQ,GACE,OAAO5B,CAAI;mDAC4D,IAAxBK,KAAKsB,2BAAiCtB,KAAKQ;;;KAI5F,EAGFgB,eAAeC,OAAO,8BAA+B7B","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/tableControls/TableControl.js";import{html as o}from"/kempo-ui/lit-all.min.js";import"/kempo-ui/components/Icon.js";export default class t extends e{remove=()=>{this.record&&this.table.deleteRecord(this.record)};render(){return"system:Users"===this.record?.name?o``:o`
|
|
2
2
|
<button class="no-btn icon-btn" @click="${this.remove}">
|
|
3
3
|
<k-icon name="delete"></k-icon>
|
|
4
4
|
</button>
|
|
5
|
-
`}}customElements.define("admin-group-remove-record",
|
|
5
|
+
`}}customElements.define("admin-group-remove-record",t);
|
|
6
6
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\GroupRemoveRecord.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\GroupRemoveRecord.js","names":["TableControl","html","GroupRemoveRecord","remove","this","record","table","deleteRecord","render","name","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class GroupRemoveRecord extends TableControl {\r\n remove = () => {\r\n if(this.record) this.table.deleteRecord(this.record);\r\n };\r\n\r\n render() {\r\n if(this.record?.name === 'system:Users') return html``;\r\n return html`\r\n <button class=\"no-btn icon-btn\" @click=\"${this.remove}\">\r\n <k-icon name=\"delete\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-group-remove-record', GroupRemoveRecord);\r\n"],"mappings":"OAAOA,
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\GroupRemoveRecord.js","names":["TableControl","html","GroupRemoveRecord","remove","this","record","table","deleteRecord","render","name","customElements","define"],"sources":["0"],"sourcesContent":["import TableControl from '/kempo-ui/components/tableControls/TableControl.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\nimport '/kempo-ui/components/Icon.js';\r\n\r\nexport default class GroupRemoveRecord extends TableControl {\r\n remove = () => {\r\n if(this.record) this.table.deleteRecord(this.record);\r\n };\r\n\r\n render() {\r\n if(this.record?.name === 'system:Users') return html``;\r\n return html`\r\n <button class=\"no-btn icon-btn\" @click=\"${this.remove}\">\r\n <k-icon name=\"delete\"></k-icon>\r\n </button>\r\n `;\r\n }\r\n}\r\n\r\ncustomElements.define('admin-group-remove-record', GroupRemoveRecord);\r\n"],"mappings":"OAAOA,MAAkB,oEAChBC,MAAY,iCACd,8CAEQ,MAAMC,UAA0BF,EAC7CG,OAAS,KACJC,KAAKC,QAAQD,KAAKE,MAAMC,aAAaH,KAAKC,SAG/C,MAAAG,GACE,MAAyB,iBAAtBJ,KAAKC,QAAQI,KAAgCR,CAAI,GAC7CA,CAAI;gDACiCG,KAAKD;;;KAInD,EAGFO,eAAeC,OAAO,4BAA6BT","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"/kempo-ui/components/LightComponent.js";import{html as t}from"/kempo-ui/lit-all.min.js";let i=null;export default class n extends e{static get properties(){return{language:{type:String},readOnly:{type:Boolean,attribute:"readonly"},height:{type:String}}}#e=null;#t=!1;#i="";constructor(){super(),this.language="json",this.readOnly=!1,this.height="400px"}get value(){return this.#e?this.#e.getValue():this.#i}set value(e){this.#e?this.#e.getValue()!==e&&this.#e.setValue(e):this.#i=e}updated(e){super.updated(e),this.#e||this.#t||(this.#t=!0,this.#n()),this.#e&&(e.has("readOnly")&&this.#e.updateOptions({readOnly:this.readOnly}),e.has("language")&&monaco.editor.setModelLanguage(this.#e.getModel(),this.language))}disconnectedCallback(){super.disconnectedCallback(),this.#e&&(this.#e.dispose(),this.#e=null)}#n=async()=>{await(i||(i=new Promise(e=>{if(window.monaco)return void e();const t=document.createElement("script");t.src="/monaco-editor/vs/loader.js",t.onload=()=>{require.config({paths:{vs:"/monaco-editor/vs"}}),require(["vs/editor/editor.main"],()=>e())},document.head.appendChild(t)}),i));const e=this.querySelector("[data-monaco-container]");if(!e)return;const t="dark"===document.documentElement.getAttribute("theme")||"auto"===document.documentElement.getAttribute("theme")&&window.matchMedia("(prefers-color-scheme: dark)").matches;this.#e=monaco.editor.create(e,{value:this.#i,language:this.language,minimap:{enabled:!1},automaticLayout:!0,theme:t?"vs-dark":"vs",scrollBeyondLastLine:!1,fontSize:14,tabSize:2,readOnly:this.readOnly}),this.#e.onDidChangeModelContent(()=>{this.dispatchEvent(new Event("change"))})};renderLightDom(){return t`<div data-monaco-container style="height: ${this.height}; border: 1px solid var(--c_border); border-radius: var(--radius);"></div>`}}customElements.define("admin-monaco",n);
|
|
2
2
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\admin\components\Monaco.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src\\admin\\components\\Monaco.js","names":["LightComponent","html","monacoLoadPromise","
|
|
1
|
+
{"version":3,"file":"src\\admin\\components\\Monaco.js","names":["LightComponent","html","monacoLoadPromise","Monaco","properties","language","type","String","readOnly","Boolean","attribute","height","editor","initializing","pendingValue","constructor","super","this","value","getValue","v","setValue","updated","changedProperties","initEditor","has","updateOptions","monaco","setModelLanguage","getModel","disconnectedCallback","dispose","async","Promise","resolve","window","script","document","createElement","src","onload","require","config","paths","vs","head","appendChild","container","querySelector","isDark","documentElement","getAttribute","matchMedia","matches","create","minimap","enabled","automaticLayout","theme","scrollBeyondLastLine","fontSize","tabSize","onDidChangeModelContent","dispatchEvent","Event","renderLightDom","customElements","define"],"sources":["0"],"sourcesContent":["import LightComponent from '/kempo-ui/components/LightComponent.js';\r\nimport { html } from '/kempo-ui/lit-all.min.js';\r\n\r\nlet monacoLoadPromise = null;\r\n\r\nconst ensureMonacoLoaded = () => {\r\n\tif(monacoLoadPromise) return monacoLoadPromise;\r\n\tmonacoLoadPromise = new Promise(resolve => {\r\n\t\tif(window.monaco){\r\n\t\t\tresolve();\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst script = document.createElement('script');\r\n\t\tscript.src = '/monaco-editor/vs/loader.js';\r\n\t\tscript.onload = () => {\r\n\t\t\trequire.config({ paths: { vs: '/monaco-editor/vs' } });\r\n\t\t\trequire(['vs/editor/editor.main'], () => resolve());\r\n\t\t};\r\n\t\tdocument.head.appendChild(script);\r\n\t});\r\n\treturn monacoLoadPromise;\r\n};\r\n\r\nexport default class Monaco extends LightComponent {\r\n\tstatic get properties() {\r\n\t\treturn {\r\n\t\t\tlanguage: { type: String },\r\n\t\t\treadOnly: { type: Boolean, attribute: 'readonly' },\r\n\t\t\theight: { type: String }\r\n\t\t};\r\n\t}\r\n\r\n\t#editor = null;\r\n\t#initializing = false;\r\n\t#pendingValue = '';\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.language = 'json';\r\n\t\tthis.readOnly = false;\r\n\t\tthis.height = '400px';\r\n\t}\r\n\r\n\t/*\r\n\t\tValue accessors\r\n\t*/\r\n\r\n\tget value() {\r\n\t\tif(this.#editor) return this.#editor.getValue();\r\n\t\treturn this.#pendingValue;\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif(this.#editor){\r\n\t\t\tif(this.#editor.getValue() !== v) this.#editor.setValue(v);\r\n\t\t} else {\r\n\t\t\tthis.#pendingValue = v;\r\n\t\t}\r\n\t}\r\n\r\n\t/*\r\n\t\tLifecycle\r\n\t*/\r\n\r\n\tupdated(changedProperties) {\r\n\t\tsuper.updated(changedProperties);\r\n\t\tif(!this.#editor && !this.#initializing){\r\n\t\t\tthis.#initializing = true;\r\n\t\t\tthis.#initEditor();\r\n\t\t}\r\n\t\tif(this.#editor){\r\n\t\t\tif(changedProperties.has('readOnly')){\r\n\t\t\t\tthis.#editor.updateOptions({ readOnly: this.readOnly });\r\n\t\t\t}\r\n\t\t\tif(changedProperties.has('language')){\r\n\t\t\t\tmonaco.editor.setModelLanguage(this.#editor.getModel(), this.language);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tdisconnectedCallback() {\r\n\t\tsuper.disconnectedCallback();\r\n\t\tif(this.#editor){\r\n\t\t\tthis.#editor.dispose();\r\n\t\t\tthis.#editor = null;\r\n\t\t}\r\n\t}\r\n\r\n\t/*\r\n\t\tEditor initialization\r\n\t*/\r\n\r\n\t#initEditor = async () => {\r\n\t\tawait ensureMonacoLoaded();\r\n\t\tconst container = this.querySelector('[data-monaco-container]');\r\n\t\tif(!container) return;\r\n\t\tconst isDark = document.documentElement.getAttribute('theme') === 'dark'\r\n\t\t\t|| (document.documentElement.getAttribute('theme') === 'auto'\r\n\t\t\t\t&& window.matchMedia('(prefers-color-scheme: dark)').matches);\r\n\t\tthis.#editor = monaco.editor.create(container, {\r\n\t\t\tvalue: this.#pendingValue,\r\n\t\t\tlanguage: this.language,\r\n\t\t\tminimap: { enabled: false },\r\n\t\t\tautomaticLayout: true,\r\n\t\t\ttheme: isDark ? 'vs-dark' : 'vs',\r\n\t\t\tscrollBeyondLastLine: false,\r\n\t\t\tfontSize: 14,\r\n\t\t\ttabSize: 2,\r\n\t\t\treadOnly: this.readOnly\r\n\t\t});\r\n\t\tthis.#editor.onDidChangeModelContent(() => {\r\n\t\t\tthis.dispatchEvent(new Event('change'));\r\n\t\t});\r\n\t};\r\n\r\n\t/*\r\n\t\tRender\r\n\t*/\r\n\r\n\trenderLightDom() {\r\n\t\treturn html`<div data-monaco-container style=\"height: ${this.height}; border: 1px solid var(--c_border); border-radius: var(--radius);\"></div>`;\r\n\t}\r\n}\r\n\r\ncustomElements.define('admin-monaco', Monaco);\r\n"],"mappings":"OAAOA,MAAoB,wDAClBC,MAAY,2BAErB,IAAIC,EAAoB,oBAoBT,MAAMC,UAAeH,EACnC,qBAAWI,GACV,MAAO,CACNC,SAAU,CAAEC,KAAMC,QAClBC,SAAU,CAAEF,KAAMG,QAASC,UAAW,YACtCC,OAAQ,CAAEL,KAAMC,QAElB,CAEAK,GAAU,KACVC,IAAgB,EAChBC,GAAgB,GAEhB,WAAAC,GACCC,QACAC,KAAKZ,SAAW,OAChBY,KAAKT,UAAW,EAChBS,KAAKN,OAAS,OACf,CAMA,SAAIO,GACH,OAAGD,MAAKL,EAAgBK,MAAKL,EAAQO,WAC9BF,MAAKH,CACb,CAEA,SAAII,CAAME,GACNH,MAAKL,EACJK,MAAKL,EAAQO,aAAeC,GAAGH,MAAKL,EAAQS,SAASD,GAExDH,MAAKH,EAAgBM,CAEvB,CAMA,OAAAE,CAAQC,GACPP,MAAMM,QAAQC,GACVN,MAAKL,GAAYK,MAAKJ,IACzBI,MAAKJ,GAAgB,EACrBI,MAAKO,KAEHP,MAAKL,IACJW,EAAkBE,IAAI,aACxBR,MAAKL,EAAQc,cAAc,CAAElB,SAAUS,KAAKT,WAE1Ce,EAAkBE,IAAI,aACxBE,OAAOf,OAAOgB,iBAAiBX,MAAKL,EAAQiB,WAAYZ,KAAKZ,UAGhE,CAEA,oBAAAyB,GACCd,MAAMc,uBACHb,MAAKL,IACPK,MAAKL,EAAQmB,UACbd,MAAKL,EAAU,KAEjB,CAMAY,GAAcQ,gBAtFX9B,IACHA,EAAoB,IAAI+B,QAAQC,IAC/B,GAAGC,OAAOR,OAET,YADAO,IAGD,MAAME,EAASC,SAASC,cAAc,UACtCF,EAAOG,IAAM,8BACbH,EAAOI,OAAS,KACfC,QAAQC,OAAO,CAAEC,MAAO,CAAEC,GAAI,uBAC9BH,QAAQ,CAAC,yBAA0B,IAAMP,MAE1CG,SAASQ,KAAKC,YAAYV,KAEpBlC,IA0EN,MAAM6C,EAAY9B,KAAK+B,cAAc,2BACrC,IAAID,EAAW,OACf,MAAME,EAA4D,SAAnDZ,SAASa,gBAAgBC,aAAa,UACG,SAAnDd,SAASa,gBAAgBC,aAAa,UACtChB,OAAOiB,WAAW,gCAAgCC,QACvDpC,MAAKL,EAAUe,OAAOf,OAAO0C,OAAOP,EAAW,CAC9C7B,MAAOD,MAAKH,EACZT,SAAUY,KAAKZ,SACfkD,QAAS,CAAEC,SAAS,GACpBC,iBAAiB,EACjBC,MAAOT,EAAS,UAAY,KAC5BU,sBAAsB,EACtBC,SAAU,GACVC,QAAS,EACTrD,SAAUS,KAAKT,WAEhBS,MAAKL,EAAQkD,wBAAwB,KACpC7C,KAAK8C,cAAc,IAAIC,MAAM,cAQ/B,cAAAC,GACC,OAAOhE,CAAI,6CAA6CgB,KAAKN,kFAC9D,EAGDuD,eAAeC,OAAO,eAAgBhE","ignoreList":[]}
|