kempo 4.2.19 → 4.2.21

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.
Files changed (176) hide show
  1. package/app-public/CATCH.page.html +15 -0
  2. package/app-public/kempo-global.global.html +0 -6
  3. package/bin/cli.js +4 -21
  4. package/dist/admin/accounts/groups/[name]/index.page.html +114 -4
  5. package/dist/admin/accounts/groups/index.page.html +89 -4
  6. package/dist/admin/accounts/permissions/index.page.html +86 -4
  7. package/dist/admin/accounts/users/[id]/index.page.html +117 -3
  8. package/dist/admin/accounts/users/index.page.html +118 -4
  9. package/dist/admin/components/AddGroupControl.js +1 -5
  10. package/dist/admin/components/AddGroupControl.js.map +1 -1
  11. package/dist/admin/components/AdminTableControl.js +2 -0
  12. package/dist/admin/components/AdminTableControl.js.map +1 -0
  13. package/dist/admin/components/ClearExpiredSessionsControl.js +1 -5
  14. package/dist/admin/components/ClearExpiredSessionsControl.js.map +1 -1
  15. package/dist/admin/components/GroupDeleteSelected.js +1 -5
  16. package/dist/admin/components/GroupDeleteSelected.js.map +1 -1
  17. package/dist/admin/components/GroupRemoveRecord.js +1 -5
  18. package/dist/admin/components/GroupRemoveRecord.js.map +1 -1
  19. package/dist/admin/components/TableRowDelete.js +1 -3
  20. package/dist/admin/components/TableRowDelete.js.map +1 -1
  21. package/dist/admin/components/TableRowLink.js +1 -7
  22. package/dist/admin/components/TableRowLink.js.map +1 -1
  23. package/dist/admin/components/tableControls/AddMember.js +1 -5
  24. package/dist/admin/components/tableControls/AddMember.js.map +1 -1
  25. package/dist/admin/components/tableControls/AddPermission.js +1 -5
  26. package/dist/admin/components/tableControls/AddPermission.js.map +1 -1
  27. package/dist/admin/components/tableControls/InstallExtension.js +1 -5
  28. package/dist/admin/components/tableControls/InstallExtension.js.map +1 -1
  29. package/dist/admin/components/tableControls/UninstallExtension.js +1 -5
  30. package/dist/admin/components/tableControls/UninstallExtension.js.map +1 -1
  31. package/dist/admin/content/fragments/edit/index.page.html +8 -1
  32. package/dist/admin/content/fragments/index.page.html +88 -3
  33. package/dist/admin/content/globals/edit/index.page.html +8 -1
  34. package/dist/admin/content/globals/index.page.html +103 -8
  35. package/dist/admin/content/pages/edit/index.page.html +8 -1
  36. package/dist/admin/content/pages/index.page.html +225 -28
  37. package/dist/admin/content/templates/edit/index.page.html +8 -1
  38. package/dist/admin/content/templates/index.page.html +117 -3
  39. package/dist/admin/default.template.html +20 -1
  40. package/dist/admin/extensions/index.page.html +59 -2
  41. package/dist/admin/icons/extension_add.svg +1 -0
  42. package/dist/admin/icons/extension_remove.svg +1 -0
  43. package/dist/admin/index.page.html +5 -1
  44. package/dist/admin/init.js.map +1 -1
  45. package/dist/admin/nav.fragment.html +84 -2
  46. package/dist/admin/settings/[owner]/[name]/index.page.html +110 -4
  47. package/dist/admin/settings/index.page.html +89 -4
  48. package/dist/kempo/api/admin-globals/DELETE.js +1 -1
  49. package/dist/kempo/api/admin-globals/DELETE.js.map +1 -1
  50. package/dist/kempo/api/admin-globals/GET.js +1 -1
  51. package/dist/kempo/api/admin-globals/GET.js.map +1 -1
  52. package/dist/kempo/api/admin-globals/POST.js +1 -1
  53. package/dist/kempo/api/admin-globals/POST.js.map +1 -1
  54. package/dist/kempo/api/admin-globals/[id]/GET.js +1 -1
  55. package/dist/kempo/api/admin-globals/[id]/GET.js.map +1 -1
  56. package/dist/kempo/api/admin-globals/[id]/PUT.js +1 -1
  57. package/dist/kempo/api/admin-globals/[id]/PUT.js.map +1 -1
  58. package/dist/kempo/api/admin-globals/[id]/disable/PUT.js +1 -1
  59. package/dist/kempo/api/admin-globals/[id]/disable/PUT.js.map +1 -1
  60. package/dist/kempo/api/admin-globals/[id]/enable/PUT.js +1 -1
  61. package/dist/kempo/api/admin-globals/[id]/enable/PUT.js.map +1 -1
  62. package/dist/kempo/api/extensions/DELETE.js +1 -1
  63. package/dist/kempo/api/extensions/DELETE.js.map +1 -1
  64. package/dist/kempo/api/extensions/POST.js +1 -1
  65. package/dist/kempo/api/extensions/POST.js.map +1 -1
  66. package/dist/kempo/api/extensions/[name]/disable/POST.js +1 -1
  67. package/dist/kempo/api/extensions/[name]/disable/POST.js.map +1 -1
  68. package/dist/kempo/api/extensions/[name]/enable/POST.js +1 -1
  69. package/dist/kempo/api/extensions/[name]/enable/POST.js.map +1 -1
  70. package/dist/kempo/api/extensions/[name]/update/POST.js +1 -1
  71. package/dist/kempo/api/extensions/[name]/update/POST.js.map +1 -1
  72. package/dist/kempo/api/extensions/[name]/update-check/GET.js +1 -1
  73. package/dist/kempo/api/extensions/[name]/update-check/GET.js.map +1 -1
  74. package/dist/kempo/api/fragments/DELETE.js +1 -1
  75. package/dist/kempo/api/fragments/DELETE.js.map +1 -1
  76. package/dist/kempo/api/fragments/GET.js +1 -1
  77. package/dist/kempo/api/fragments/GET.js.map +1 -1
  78. package/dist/kempo/api/fragments/POST.js +1 -1
  79. package/dist/kempo/api/fragments/POST.js.map +1 -1
  80. package/dist/kempo/api/fragments/disable/PUT.js +1 -1
  81. package/dist/kempo/api/fragments/disable/PUT.js.map +1 -1
  82. package/dist/kempo/api/fragments/enable/PUT.js +1 -1
  83. package/dist/kempo/api/fragments/enable/PUT.js.map +1 -1
  84. package/dist/kempo/api/fragments/file/GET.js +1 -1
  85. package/dist/kempo/api/fragments/file/GET.js.map +1 -1
  86. package/dist/kempo/api/fragments/file/PATCH.js +1 -1
  87. package/dist/kempo/api/fragments/file/PATCH.js.map +1 -1
  88. package/dist/kempo/api/fragments/file/PUT.js +1 -1
  89. package/dist/kempo/api/fragments/file/PUT.js.map +1 -1
  90. package/dist/kempo/api/fragments/lock/PUT.js +1 -1
  91. package/dist/kempo/api/fragments/lock/PUT.js.map +1 -1
  92. package/dist/kempo/api/globals/DELETE.js +1 -1
  93. package/dist/kempo/api/globals/DELETE.js.map +1 -1
  94. package/dist/kempo/api/globals/GET.js +1 -1
  95. package/dist/kempo/api/globals/GET.js.map +1 -1
  96. package/dist/kempo/api/globals/POST.js +1 -1
  97. package/dist/kempo/api/globals/POST.js.map +1 -1
  98. package/dist/kempo/api/globals/disable/PUT.js +1 -1
  99. package/dist/kempo/api/globals/disable/PUT.js.map +1 -1
  100. package/dist/kempo/api/globals/enable/PUT.js +1 -1
  101. package/dist/kempo/api/globals/enable/PUT.js.map +1 -1
  102. package/dist/kempo/api/globals/entry/GET.js +1 -1
  103. package/dist/kempo/api/globals/entry/GET.js.map +1 -1
  104. package/dist/kempo/api/globals/entry/PUT.js +1 -1
  105. package/dist/kempo/api/globals/entry/PUT.js.map +1 -1
  106. package/dist/kempo/api/globals/lock/PUT.js +1 -1
  107. package/dist/kempo/api/globals/lock/PUT.js.map +1 -1
  108. package/dist/kempo/api/pages/DELETE.js +1 -1
  109. package/dist/kempo/api/pages/DELETE.js.map +1 -1
  110. package/dist/kempo/api/pages/GET.js +1 -1
  111. package/dist/kempo/api/pages/GET.js.map +1 -1
  112. package/dist/kempo/api/pages/POST.js +1 -1
  113. package/dist/kempo/api/pages/POST.js.map +1 -1
  114. package/dist/kempo/api/pages/directories/GET.js +1 -1
  115. package/dist/kempo/api/pages/directories/GET.js.map +1 -1
  116. package/dist/kempo/api/pages/disable/PUT.js +1 -1
  117. package/dist/kempo/api/pages/disable/PUT.js.map +1 -1
  118. package/dist/kempo/api/pages/enable/PUT.js +1 -1
  119. package/dist/kempo/api/pages/enable/PUT.js.map +1 -1
  120. package/dist/kempo/api/pages/file/GET.js +1 -1
  121. package/dist/kempo/api/pages/file/GET.js.map +1 -1
  122. package/dist/kempo/api/pages/file/PATCH.js +1 -1
  123. package/dist/kempo/api/pages/file/PATCH.js.map +1 -1
  124. package/dist/kempo/api/pages/file/PUT.js +1 -1
  125. package/dist/kempo/api/pages/file/PUT.js.map +1 -1
  126. package/dist/kempo/api/pages/lock/PUT.js +1 -1
  127. package/dist/kempo/api/pages/lock/PUT.js.map +1 -1
  128. package/dist/kempo/api/pages/rescan/POST.js +2 -0
  129. package/dist/kempo/api/pages/rescan/POST.js.map +1 -0
  130. package/dist/kempo/api/pages/search/GET.js +1 -1
  131. package/dist/kempo/api/pages/search/GET.js.map +1 -1
  132. package/dist/kempo/api/pages/templates/GET.js +1 -1
  133. package/dist/kempo/api/pages/templates/GET.js.map +1 -1
  134. package/dist/kempo/api/templates/DELETE.js +1 -1
  135. package/dist/kempo/api/templates/DELETE.js.map +1 -1
  136. package/dist/kempo/api/templates/GET.js +1 -1
  137. package/dist/kempo/api/templates/GET.js.map +1 -1
  138. package/dist/kempo/api/templates/POST.js +1 -1
  139. package/dist/kempo/api/templates/POST.js.map +1 -1
  140. package/dist/kempo/api/templates/disable/PUT.js +1 -1
  141. package/dist/kempo/api/templates/disable/PUT.js.map +1 -1
  142. package/dist/kempo/api/templates/enable/PUT.js +1 -1
  143. package/dist/kempo/api/templates/enable/PUT.js.map +1 -1
  144. package/dist/kempo/api/templates/file/GET.js +1 -1
  145. package/dist/kempo/api/templates/file/GET.js.map +1 -1
  146. package/dist/kempo/api/templates/file/PATCH.js +1 -1
  147. package/dist/kempo/api/templates/file/PATCH.js.map +1 -1
  148. package/dist/kempo/api/templates/file/PUT.js +1 -1
  149. package/dist/kempo/api/templates/file/PUT.js.map +1 -1
  150. package/dist/kempo/api/templates/lock/PUT.js +1 -1
  151. package/dist/kempo/api/templates/lock/PUT.js.map +1 -1
  152. package/dist/kempo/api/user/[userid]/name/GET.js +2 -0
  153. package/dist/kempo/api/user/[userid]/name/GET.js.map +1 -0
  154. package/dist/kempo/components/UserDisplayName.js +2 -0
  155. package/dist/kempo/components/UserDisplayName.js.map +1 -0
  156. package/dist/kempo/sdk.js +1 -1
  157. package/dist/kempo/sdk.js.map +1 -1
  158. package/middleware/kempo.js +99 -25
  159. package/package.json +16 -9
  160. package/server/utils/admin-global-content/createAdminGlobalContent.js +4 -3
  161. package/server/utils/admin-global-content/deleteAdminGlobalContent.js +2 -2
  162. package/server/utils/admin-global-content/deleteAdminGlobalContentByOwner.js +2 -2
  163. package/server/utils/admin-global-content/disableAdminGlobalContent.js +2 -2
  164. package/server/utils/admin-global-content/enableAdminGlobalContent.js +2 -2
  165. package/server/utils/admin-global-content/getAdminGlobalContent.js +2 -2
  166. package/server/utils/admin-global-content/helpers.js +12 -1
  167. package/server/utils/admin-global-content/listAdminGlobalContent.js +2 -2
  168. package/server/utils/admin-global-content/updateAdminGlobalContent.js +2 -2
  169. package/server/utils/email/sendEmail.js +9 -3
  170. package/server/utils/extensions/uninstallExtension.js +54 -21
  171. package/server/utils/fragments/listFragments.js +10 -1
  172. package/server/utils/hooks/triggerHook.js +15 -13
  173. package/server/utils/pages/listPages.js +57 -7
  174. package/app-public/kempo-global.global-disabled.html +0 -0
  175. package/app-public/new-page.page.html +0 -17
  176. package/app-public/test.page.html +0 -21
@@ -1,7 +1,118 @@
1
1
  <!--
2
2
  locked: true
3
3
  -->
4
- <page title="Templates - Admin"><content><script type="module" src="/kempo-ui/components/Table.js"></script><script type="module" src="/kempo-ui/components/tableControls/FirstPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/PrevPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/NextPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/LastPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/PageSelect.js"></script><script type="module" src="/kempo-ui/components/tableControls/PageSize.js"></script><script type="module" src="/kempo-ui/components/tableControls/DeleteRecord.js"></script><script type="module" src="/kempo-ui/components/tableControls/DeleteSelected.js"></script><script type="module" src="/kempo-ui/components/Icon.js"></script><script type="module" src="/admin/components/TableRowLink.js"></script><script type="module" src="/kempo/components/Permission.js"></script><div class="d-f mb" style="align-items: center; gap: var(--spacer);"><h1 class="flex mb0">Templates</h1><k-permission has="system:pages:create"><button id="createTemplateBtn" class="primary">Create Template</button></k-permission></div><h2>Custom Templates</h2><k-table id="customTable" enable-pages page-size="25" page-size-options="[10,25,50,100]" placeholder="No custom templates have been created yet."><admin-table-row-link slot="before" url-pattern="/admin/content/templates/edit?template={editPath}" field-name="editPath"></admin-table-row-link><div slot="top" class="d-f full" style="align-items: center;"><div><k-permission has="system:pages:delete"><k-tc-delete-selected></k-tc-delete-selected></k-permission></div></div><div class="d-f full" style="align-items: center;"><div><k-tc-first-page></k-tc-first-page><k-tc-prev-page></k-tc-prev-page><k-tc-next-page></k-tc-next-page><k-tc-last-page></k-tc-last-page></div><div class="flex"></div><div><k-tc-page-select></k-tc-page-select></div><div class="flex"></div><div><k-tc-page-size></k-tc-page-size></div></div></k-table><h2>Extension Templates</h2><k-table id="extensionTable" enable-pages page-size="25" page-size-options="[10,25,50,100]" placeholder="No extension templates installed."><admin-table-row-link slot="before" url-pattern="/admin/content/templates/edit?template={editPath}" field-name="editPath"></admin-table-row-link><div class="d-f full" style="align-items: center;"><div><k-tc-first-page></k-tc-first-page><k-tc-prev-page></k-tc-prev-page><k-tc-next-page></k-tc-next-page><k-tc-last-page></k-tc-last-page></div><div class="flex"></div><div><k-tc-page-select></k-tc-page-select></div><div class="flex"></div><div><k-tc-page-size></k-tc-page-size></div></div></k-table><h2>System Templates</h2><k-table id="systemTable" enable-pages page-size="25" page-size-options="[10,25,50,100]" placeholder="No system templates found."><admin-table-row-link slot="before" url-pattern="/admin/content/templates/edit?template={editPath}" field-name="editPath"></admin-table-row-link><div class="d-f full" style="align-items: center;"><div><k-tc-first-page></k-tc-first-page><k-tc-prev-page></k-tc-prev-page><k-tc-next-page></k-tc-next-page><k-tc-last-page></k-tc-last-page></div><div class="flex"></div><div><k-tc-page-select></k-tc-page-select></div><div class="flex"></div><div><k-tc-page-size></k-tc-page-size></div></div></k-table><script type="module">import { listTemplates, listDirectories, createTemplate, deleteTemplates, getAllCurrentUserPermissions } from '/kempo/sdk.js';
4
+ <page title="Templates - Admin">
5
+ <content>
6
+ <script type="module" src="/kempo-ui/components/Table.js"></script>
7
+ <script type="module" src="/kempo-ui/components/controls/TcFirstPage.js"></script>
8
+ <script type="module" src="/kempo-ui/components/controls/TcPrevPage.js"></script>
9
+ <script type="module" src="/kempo-ui/components/controls/TcNextPage.js"></script>
10
+ <script type="module" src="/kempo-ui/components/controls/TcLastPage.js"></script>
11
+ <script type="module" src="/kempo-ui/components/controls/TcPageSelect.js"></script>
12
+ <script type="module" src="/kempo-ui/components/controls/TcPageSize.js"></script>
13
+ <script type="module" src="/kempo-ui/components/controls/TcDeleteRecord.js"></script>
14
+ <script type="module" src="/kempo-ui/components/controls/TcDeleteSelected.js"></script>
15
+ <script type="module" src="/kempo-ui/components/Icon.js"></script>
16
+ <script type="module" src="/admin/components/TableRowLink.js"></script>
17
+ <script type="module" src="/kempo/components/Permission.js"></script>
18
+
19
+ <div class="d-f mb" style="align-items: center; gap: var(--spacer);">
20
+ <h1 class="flex mb0">Templates</h1>
21
+ <k-permission has="system:pages:create">
22
+ <button id="createTemplateBtn" class="primary">Create Template</button>
23
+ </k-permission>
24
+ </div>
25
+
26
+ <h2>Custom Templates</h2>
27
+ <k-table
28
+ id="customTable"
29
+ enable-pages
30
+ page-size="25"
31
+ page-size-options="[10,25,50,100]"
32
+ placeholder="No custom templates have been created yet."
33
+ >
34
+ <admin-table-row-link
35
+ slot="before"
36
+ url-pattern="/admin/content/templates/edit?template={editPath}"
37
+ field-name="editPath"
38
+ ></admin-table-row-link>
39
+ <div slot="top" class="d-f full" style="align-items: center;">
40
+ <div>
41
+ <k-permission has="system:pages:delete">
42
+ <kc-tc-delete-selected></kc-tc-delete-selected>
43
+ </k-permission>
44
+ </div>
45
+ </div>
46
+ <div class="d-f full" style="align-items: center;">
47
+ <div>
48
+ <kc-tc-first-page></kc-tc-first-page>
49
+ <kc-tc-prev-page></kc-tc-prev-page>
50
+ <kc-tc-next-page></kc-tc-next-page>
51
+ <kc-tc-last-page></kc-tc-last-page>
52
+ </div>
53
+ <div class="flex"></div>
54
+ <div><kc-tc-page-select></kc-tc-page-select></div>
55
+ <div class="flex"></div>
56
+ <div><kc-tc-page-size></kc-tc-page-size></div>
57
+ </div>
58
+ </k-table>
59
+
60
+ <h2>Extension Templates</h2>
61
+ <k-table
62
+ id="extensionTable"
63
+ enable-pages
64
+ page-size="25"
65
+ page-size-options="[10,25,50,100]"
66
+ placeholder="No extension templates installed."
67
+ >
68
+ <admin-table-row-link
69
+ slot="before"
70
+ url-pattern="/admin/content/templates/edit?template={editPath}"
71
+ field-name="editPath"
72
+ ></admin-table-row-link>
73
+ <div class="d-f full" style="align-items: center;">
74
+ <div>
75
+ <kc-tc-first-page></kc-tc-first-page>
76
+ <kc-tc-prev-page></kc-tc-prev-page>
77
+ <kc-tc-next-page></kc-tc-next-page>
78
+ <kc-tc-last-page></kc-tc-last-page>
79
+ </div>
80
+ <div class="flex"></div>
81
+ <div><kc-tc-page-select></kc-tc-page-select></div>
82
+ <div class="flex"></div>
83
+ <div><kc-tc-page-size></kc-tc-page-size></div>
84
+ </div>
85
+ </k-table>
86
+
87
+ <h2>System Templates</h2>
88
+ <k-table
89
+ id="systemTable"
90
+ enable-pages
91
+ page-size="25"
92
+ page-size-options="[10,25,50,100]"
93
+ placeholder="No system templates found."
94
+ >
95
+ <admin-table-row-link
96
+ slot="before"
97
+ url-pattern="/admin/content/templates/edit?template={editPath}"
98
+ field-name="editPath"
99
+ ></admin-table-row-link>
100
+ <div class="d-f full" style="align-items: center;">
101
+ <div>
102
+ <kc-tc-first-page></kc-tc-first-page>
103
+ <kc-tc-prev-page></kc-tc-prev-page>
104
+ <kc-tc-next-page></kc-tc-next-page>
105
+ <kc-tc-last-page></kc-tc-last-page>
106
+ </div>
107
+ <div class="flex"></div>
108
+ <div><kc-tc-page-select></kc-tc-page-select></div>
109
+ <div class="flex"></div>
110
+ <div><kc-tc-page-size></kc-tc-page-size></div>
111
+ </div>
112
+ </k-table>
113
+
114
+ <script type="module">
115
+ import { listTemplates, listDirectories, createTemplate, deleteTemplates, getAllCurrentUserPermissions } from '/kempo/sdk.js';
5
116
  import { html } from '/kempo-ui/lit-all.min.js';
6
117
  import Dialog from '/kempo-ui/components/Dialog.js';
7
118
  import Toast from '/kempo-ui/components/Toast.js';
@@ -52,7 +163,7 @@
52
163
  if(myPerms.has('system:pages:delete')){
53
164
  $customTable.setAttribute('request-delete', '');
54
165
  $customTable.setAttribute('enable-selection', '');
55
- const del = document.createElement('k-tc-delete-record');
166
+ const del = document.createElement('kc-tc-delete-record');
56
167
  del.setAttribute('slot', 'after');
57
168
  $customTable.appendChild(del);
58
169
  }
@@ -190,4 +301,7 @@
190
301
  updateSlug();
191
302
  });
192
303
  $dialog.querySelector('#dlg-name').addEventListener('input', updateSlug);
193
- });</script></content></page>
304
+ });
305
+ </script>
306
+ </content>
307
+ </page>
@@ -6,4 +6,23 @@
6
6
  created:
7
7
  updated:
8
8
  -->
9
- <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" type="image/png" sizes="48x48" href="/media/icon48.png"><link rel="manifest" href="/manifest.json"><title>{{title}}</title><link rel="stylesheet" href="/kempo-css/kempo.min.css"><script src="/admin/init.js"></script><location name="head"/></head><body><fragment name="nav"/><k-main><location/></k-main><location name="scripts"/></body></html>
9
+ <!DOCTYPE html>
10
+ <html lang="en">
11
+ <head>
12
+ <meta charset="UTF-8">
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
+ <link rel="icon" type="image/png" sizes="48x48" href="/media/icon48.png">
15
+ <link rel="manifest" href="/manifest.json">
16
+ <title>{{title}}</title>
17
+ <link rel="stylesheet" href="/kempo-css/kempo.min.css">
18
+ <script src="/admin/init.js"></script>
19
+ <location name="head" />
20
+ </head>
21
+ <body>
22
+ <fragment name="nav" />
23
+ <k-main>
24
+ <location />
25
+ </k-main>
26
+ <location name="scripts" />
27
+ </body>
28
+ </html>
@@ -1,7 +1,61 @@
1
1
  <!--
2
2
  locked: true
3
3
  -->
4
- <page title="Extensions - Admin"><content><script type="module" src="/kempo-ui/components/Table.js"></script><script type="module" src="/kempo-ui/components/tableControls/FirstPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/PrevPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/NextPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/LastPage.js"></script><script type="module" src="/kempo-ui/components/tableControls/PageSelect.js"></script><script type="module" src="/kempo-ui/components/tableControls/PageSize.js"></script><script type="module" src="/admin/components/tableControls/InstallExtension.js"></script><script type="module" src="/admin/components/tableControls/UninstallExtension.js"></script><script type="module" src="/kempo/components/Permission.js"></script><div class="d-f mb" style="align-items: center; gap: var(--spacer);"><h1 class="flex mb0">Extensions</h1></div><h2>Installed Extensions</h2><k-table id="installedTable" enable-pages page-size="25" placeholder="No extensions are currently installed."><admin-uninstall-extension slot="after"></admin-uninstall-extension><div class="d-f full" style="align-items: center;"><div><k-tc-first-page></k-tc-first-page><k-tc-prev-page></k-tc-prev-page><k-tc-next-page></k-tc-next-page><k-tc-last-page></k-tc-last-page></div><div class="flex"></div><div><k-tc-page-select></k-tc-page-select></div><div class="flex"></div><div><k-tc-page-size></k-tc-page-size></div></div></k-table><h2>Available Extensions</h2><k-table id="availableTable" enable-pages page-size="25" placeholder="No extensions are available to install. Install a kempo extension package via npm first."><admin-install-extension slot="after"></admin-install-extension><div class="d-f full" style="align-items: center;"><div><k-tc-first-page></k-tc-first-page><k-tc-prev-page></k-tc-prev-page><k-tc-next-page></k-tc-next-page><k-tc-last-page></k-tc-last-page></div><div class="flex"></div><div><k-tc-page-select></k-tc-page-select></div><div class="flex"></div><div><k-tc-page-size></k-tc-page-size></div></div></k-table></content><content location="scripts"><script type="module">import { listExtensions, listAvailableExtensions } from '/kempo/sdk.js';
4
+ <page title="Extensions - Admin">
5
+ <content>
6
+ <script type="module" src="/kempo-ui/components/Table.js"></script>
7
+ <script type="module" src="/kempo-ui/components/controls/TcFirstPage.js"></script>
8
+ <script type="module" src="/kempo-ui/components/controls/TcPrevPage.js"></script>
9
+ <script type="module" src="/kempo-ui/components/controls/TcNextPage.js"></script>
10
+ <script type="module" src="/kempo-ui/components/controls/TcLastPage.js"></script>
11
+ <script type="module" src="/kempo-ui/components/controls/TcPageSelect.js"></script>
12
+ <script type="module" src="/kempo-ui/components/controls/TcPageSize.js"></script>
13
+ <script type="module" src="/admin/components/tableControls/InstallExtension.js"></script>
14
+ <script type="module" src="/admin/components/tableControls/UninstallExtension.js"></script>
15
+ <script type="module" src="/kempo/components/Permission.js"></script>
16
+
17
+ <div class="d-f mb" style="align-items: center; gap: var(--spacer);">
18
+ <h1 class="flex mb0">Extensions</h1>
19
+ </div>
20
+
21
+ <h2>Installed Extensions</h2>
22
+ <k-table id="installedTable" enable-pages page-size="25" placeholder="No extensions are currently installed.">
23
+ <admin-uninstall-extension slot="after"></admin-uninstall-extension>
24
+ <div class="d-f full" style="align-items: center;">
25
+ <div>
26
+ <kc-tc-first-page></kc-tc-first-page>
27
+ <kc-tc-prev-page></kc-tc-prev-page>
28
+ <kc-tc-next-page></kc-tc-next-page>
29
+ <kc-tc-last-page></kc-tc-last-page>
30
+ </div>
31
+ <div class="flex"></div>
32
+ <div><kc-tc-page-select></kc-tc-page-select></div>
33
+ <div class="flex"></div>
34
+ <div><kc-tc-page-size></kc-tc-page-size></div>
35
+ </div>
36
+ </k-table>
37
+
38
+ <h2>Available Extensions</h2>
39
+ <k-table id="availableTable" enable-pages page-size="25" placeholder="No extensions are available to install. Install a kempo extension package via npm first.">
40
+ <admin-install-extension slot="after"></admin-install-extension>
41
+ <div class="d-f full" style="align-items: center;">
42
+ <div>
43
+ <kc-tc-first-page></kc-tc-first-page>
44
+ <kc-tc-prev-page></kc-tc-prev-page>
45
+ <kc-tc-next-page></kc-tc-next-page>
46
+ <kc-tc-last-page></kc-tc-last-page>
47
+ </div>
48
+ <div class="flex"></div>
49
+ <div><kc-tc-page-select></kc-tc-page-select></div>
50
+ <div class="flex"></div>
51
+ <div><kc-tc-page-size></kc-tc-page-size></div>
52
+ </div>
53
+ </k-table>
54
+
55
+ </content>
56
+ <content location="scripts">
57
+ <script type="module">
58
+ import { listExtensions, listAvailableExtensions } from '/kempo/sdk.js';
5
59
 
6
60
  const installedTable = document.getElementById('installedTable');
7
61
  const availableTable = document.getElementById('availableTable');
@@ -63,4 +117,7 @@
63
117
  };
64
118
 
65
119
  availableTable.addEventListener('recordDeleted', refreshInstalledTable);
66
- installedTable.addEventListener('recordDeleted', refreshAvailableTable);</script></content></page>
120
+ installedTable.addEventListener('recordDeleted', refreshAvailableTable);
121
+ </script>
122
+ </content>
123
+ </page>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 16667 16667" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M4019.272,16222.329l-2431.295,0c-351.899,0 -653.137,-125.29 -903.74,-375.893c-250.599,-250.599 -375.893,-551.84 -375.893,-903.74l0,-2431.295c511.851,0 959.722,-162.623 1343.611,-487.858c383.889,-325.235 575.833,-738.456 575.833,-1239.643c0,-501.182 -191.944,-914.408 -575.833,-1239.643c-383.889,-325.235 -831.761,-487.858 -1343.611,-487.858l0,-2431.295c0,-351.899 125.29,-653.141 375.893,-903.74c250.599,-250.599 551.84,-375.893 903.74,-375.893l2559.261,0c0,-447.872 154.627,-826.432 463.865,-1135.67c309.238,-309.238 687.802,-463.865 1135.67,-463.865c447.872,0 826.432,154.627 1135.67,463.865c309.238,309.238 463.865,687.802 463.865,1135.67l2559.261,0c351.899,0 653.141,125.29 903.74,375.893c250.599,250.599 375.893,551.84 375.893,903.74l0,2559.261c447.872,0 826.432,154.627 1135.67,463.865c309.238,309.238 463.865,687.802 463.865,1135.67c0,447.872 -154.627,826.432 -463.865,1135.67c-309.238,309.238 -687.802,463.865 -1135.67,463.865l0,2559.261c0,351.899 -125.29,653.137 -375.893,903.74c-250.599,250.599 -551.84,375.893 -903.74,375.893l-2431.295,0c0,-533.172 -167.951,-986.387 -503.854,-1359.608c-335.903,-373.221 -743.785,-559.837 -1223.646,-559.837c-479.861,0 -887.743,186.62 -1223.646,559.837c-335.903,373.221 -503.854,826.432 -503.854,1359.608Zm-2431.295,-1279.627l1359.608,-0.002c255.927,-703.795 666.477,-1199.653 1231.642,-1487.57c565.165,-287.917 1087.684,-431.875 1567.545,-431.875c479.861,0 1002.384,143.958 1567.545,431.875c565.165,287.917 975.719,783.775 1231.642,1487.57l1359.608,0l0,-3838.889l1279.628,0c85.304,0 159.955,-31.989 223.934,-95.972c63.983,-63.983 95.972,-138.63 95.972,-223.934c0,-85.304 -31.989,-159.955 -95.972,-223.934c-63.983,-63.983 -138.634,-95.972 -223.934,-95.972l-1279.628,0l0,-3838.889l-3838.889,0l0,-1279.628c0,-85.304 -31.989,-159.955 -95.972,-223.934c-63.983,-63.983 -138.63,-95.972 -223.934,-95.972c-85.304,0 -159.955,31.989 -223.934,95.972c-63.983,63.983 -95.972,138.634 -95.972,223.934l0,1279.628l-3838.889,0l0,1407.594c575.833,213.266 1039.698,570.509 1391.597,1071.691c351.899,501.182 527.847,1061.023 527.847,1679.514c0,607.823 -175.948,1162.335 -527.847,1663.517c-351.899,501.182 -815.764,863.75 -1391.597,1087.684l0,1407.592Zm12403.694,-8446.685l-1587.205,0l0,-2380.82l-2380.82,0l0,-1587.205l2380.82,0l0,-2380.82l1587.205,0l0,2380.82l2380.82,0l0,1587.205l-2380.82,0l-0,2380.82Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 16667 16667" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M4019.272,16222.329l-2431.295,0c-351.899,0 -653.137,-125.29 -903.74,-375.893c-250.599,-250.599 -375.893,-551.84 -375.893,-903.74l0,-2431.295c511.851,0 959.722,-162.623 1343.611,-487.858c383.889,-325.235 575.833,-738.456 575.833,-1239.643c0,-501.182 -191.944,-914.408 -575.833,-1239.643c-383.889,-325.235 -831.761,-487.858 -1343.611,-487.858l0,-2431.295c0,-351.899 125.29,-653.141 375.893,-903.74c250.599,-250.599 551.84,-375.893 903.74,-375.893l2559.261,0c0,-447.872 154.627,-826.432 463.865,-1135.67c309.238,-309.238 687.802,-463.865 1135.67,-463.865c447.872,0 826.432,154.627 1135.67,463.865c309.238,309.238 463.865,687.802 463.865,1135.67l2559.261,0c351.899,0 653.141,125.29 903.74,375.893c250.599,250.599 375.893,551.84 375.893,903.74l0,2559.261c447.872,0 826.432,154.627 1135.67,463.865c309.238,309.238 463.865,687.802 463.865,1135.67c0,447.872 -154.627,826.432 -463.865,1135.67c-309.238,309.238 -687.802,463.865 -1135.67,463.865l0,2559.261c0,351.899 -125.29,653.137 -375.893,903.74c-250.599,250.599 -551.84,375.893 -903.74,375.893l-2431.295,0c0,-533.172 -167.951,-986.387 -503.854,-1359.608c-335.903,-373.221 -743.785,-559.837 -1223.646,-559.837c-479.861,0 -887.743,186.62 -1223.646,559.837c-335.903,373.221 -503.854,826.432 -503.854,1359.608Zm-2431.295,-1279.627l1359.608,-0.002c255.927,-703.795 666.477,-1199.653 1231.642,-1487.57c565.165,-287.917 1087.684,-431.875 1567.545,-431.875c479.861,0 1002.384,143.958 1567.545,431.875c565.165,287.917 975.719,783.775 1231.642,1487.57l1359.608,0l0,-3838.889l1279.628,0c85.304,0 159.955,-31.989 223.934,-95.972c63.983,-63.983 95.972,-138.63 95.972,-223.934c0,-85.304 -31.989,-159.955 -95.972,-223.934c-63.983,-63.983 -138.634,-95.972 -223.934,-95.972l-1279.628,0l0,-3838.889l-3838.889,0l0,-1279.628c0,-85.304 -31.989,-159.955 -95.972,-223.934c-63.983,-63.983 -138.63,-95.972 -223.934,-95.972c-85.304,0 -159.955,31.989 -223.934,95.972c-63.983,63.983 -95.972,138.634 -95.972,223.934l0,1279.628l-3838.889,0l0,1407.594c575.833,213.266 1039.698,570.509 1391.597,1071.691c351.899,501.182 527.847,1061.023 527.847,1679.514c0,607.823 -175.948,1162.335 -527.847,1663.517c-351.899,501.182 -815.764,863.75 -1391.597,1087.684l0,1407.592Zm14371.18,-11628.351l-6348.844,-0l0,-1587.205l6348.844,0l0,1587.205Z"/></svg>
@@ -2,4 +2,8 @@
2
2
  locked: true
3
3
  template: default
4
4
  -->
5
- <page title="Admin Dashboard"><content><h1>Dashboard</h1></content></page>
5
+ <page title="Admin Dashboard">
6
+ <content>
7
+ <h1>Dashboard</h1>
8
+ </content>
9
+ </page>
@@ -1 +1 @@
1
- {"version":3,"file":"src\\admin\\init.js","names":["window","kempo","pathsToIcons","monacoUrl","litDisableBundleWarning","import"],"sources":["0"],"sourcesContent":["window.kempo = { pathsToIcons: ['/admin/icons', '/kempo/icons', '/kempo-ui/icons'], monacoUrl: '/monaco-editor' };\r\nwindow.litDisableBundleWarning = true;\r\n\r\n/*\r\n Dynamic imports are required here becasue static imports are hoisted and resolved before any code runs,\r\n meaning window.kempo would not yet be set when these components initialize.\r\n Dynamic import() is called at runtime, after the synchronous assignments above,\r\n guaranteeing window.kempo.pathsToIcons is available when the components load.\r\n*/\r\nimport('/kempo-ui/components/Import.js');\r\nimport('/kempo-ui/components/Aside.js');\r\nimport('/kempo-ui/components/Main.js');\r\n"],"mappings":"AAAAA,OAAOC,MAAQ,CAAEC,aAAc,CAAC,eAAgB,eAAgB,mBAAoBC,UAAW,kBAC/FH,OAAOI,yBAA0B,EAQjCC,OAAO,kCACPA,OAAO,iCACPA,OAAO","ignoreList":[]}
1
+ {"version":3,"file":"src\\admin\\init.js","names":["window","kempo","pathsToIcons","monacoUrl","litDisableBundleWarning"],"sources":["0"],"sourcesContent":["window.kempo = { pathsToIcons: ['/admin/icons', '/kempo/icons', '/kempo-ui/icons'], monacoUrl: '/monaco-editor' };\r\nwindow.litDisableBundleWarning = true;\r\n\r\n/*\r\n Dynamic imports are required here becasue static imports are hoisted and resolved before any code runs,\r\n meaning window.kempo would not yet be set when these components initialize.\r\n Dynamic import() is called at runtime, after the synchronous assignments above,\r\n guaranteeing window.kempo.pathsToIcons is available when the components load.\r\n*/\r\nimport('/kempo-ui/components/Import.js');\r\nimport('/kempo-ui/components/Aside.js');\r\nimport('/kempo-ui/components/Main.js');\r\n"],"mappings":"AAAAA,OAAOC,MAAQ,CAAEC,aAAc,CAAC,eAAgB,eAAgB,mBAAoBC,UAAW,kBAC/FH,OAAOI,yBAA0B,SAQ1B,yCACA,wCACA","ignoreList":[]}
@@ -1,7 +1,87 @@
1
1
  <!--
2
2
  locked: true
3
3
  -->
4
- <fragment><k-aside main="push" state="expanded" style="--aside_padding: 0;" persistent-id="admin-nav"><k-aside-toggle><h3 class="m0">Kempo Admin</h3></k-aside-toggle><k-aside-item icon="preview" href="/" no-expand>Site</k-aside-item><k-aside-item icon="cards" href="/admin" no-expand>Dashboard</k-aside-item><k-aside-menu icon="manage-accounts" label="Accounts"><k-aside-item icon="person" href="/admin/accounts/users" no-expand>Users</k-aside-item><k-aside-item icon="group" href="/admin/accounts/groups" no-expand>Groups</k-aside-item><k-aside-item icon="lock" href="/admin/accounts/permissions" no-expand>Permissions</k-aside-item></k-aside-menu><k-aside-menu icon="cards_stack" label="Content"><k-aside-item icon="browse" href="/admin/content/templates">Templates</k-aside-item><k-aside-item icon="docs" href="/admin/content/pages">Pages</k-aside-item><k-aside-item icon="content" href="/admin/content/fragments">Fragments</k-aside-item><k-aside-item icon="globe" href="/admin/content/globals">Global Content</k-aside-item></k-aside-menu><k-aside-item icon="settings" href="/admin/settings" no-expand>Settings</k-aside-item><k-aside-item icon="extension" href="/admin/extensions" no-expand>Extensions</k-aside-item><hr><location name="admin-nav-extensions"></location><k-aside-spacer></k-aside-spacer><k-theme-switcher labels style="--padding:var(--spacer_h);margin:var(--spacer_h) auto"></k-theme-switcher></k-aside><script type="module">import '/kempo-ui/components/ThemeSwitcher.js';
4
+ <fragment>
5
+ <k-aside
6
+ main="push"
7
+ state="expanded"
8
+ style="--aside_padding: 0;"
9
+ persistent-id="admin-nav"
10
+ >
11
+ <k-aside-toggle>
12
+ <h3 class="m0">Kempo Admin</h3>
13
+ </k-aside-toggle>
14
+ <k-aside-item
15
+ icon="preview"
16
+ href="/"
17
+ no-expand
18
+ >Site</k-aside-item>
19
+ <k-aside-item
20
+ icon="cards"
21
+ href="/admin"
22
+ no-expand
23
+ >Dashboard</k-aside-item>
24
+ <k-aside-menu
25
+ icon="manage-accounts"
26
+ label="Accounts"
27
+ >
28
+ <k-aside-item
29
+ icon="person"
30
+ href="/admin/accounts/users"
31
+ no-expand
32
+ >Users</k-aside-item>
33
+ <k-aside-item
34
+ icon="group"
35
+ href="/admin/accounts/groups"
36
+ no-expand
37
+ >Groups</k-aside-item>
38
+ <k-aside-item
39
+ icon="lock"
40
+ href="/admin/accounts/permissions"
41
+ no-expand
42
+ >Permissions</k-aside-item>
43
+ </k-aside-menu>
44
+ <k-aside-menu
45
+ icon="cards_stack"
46
+ label="Content"
47
+ >
48
+ <k-aside-item
49
+ icon="browse"
50
+ href="/admin/content/templates"
51
+ >Templates</k-aside-item>
52
+ <k-aside-item
53
+ icon="docs"
54
+ href="/admin/content/pages"
55
+ >Pages</k-aside-item>
56
+ <k-aside-item
57
+ icon="content"
58
+ href="/admin/content/fragments"
59
+ >Fragments</k-aside-item>
60
+ <k-aside-item
61
+ icon="globe"
62
+ href="/admin/content/globals"
63
+ >Global Content</k-aside-item>
64
+ </k-aside-menu>
65
+ <k-aside-item
66
+ icon="settings"
67
+ href="/admin/settings"
68
+ no-expand
69
+ >Settings</k-aside-item>
70
+ <k-aside-item
71
+ icon="extension"
72
+ href="/admin/extensions"
73
+ no-expand
74
+ >Extensions</k-aside-item>
75
+ <hr>
76
+ <location name="admin-nav-extensions"></location>
77
+ <k-aside-spacer></k-aside-spacer>
78
+ <k-theme-switcher
79
+ labels
80
+ style="--padding:var(--spacer_h);margin:var(--spacer_h) auto"
81
+ ></k-theme-switcher>
82
+ </k-aside>
83
+ <script type="module">
84
+ import '/kempo-ui/components/ThemeSwitcher.js';
5
85
  const items = document.querySelectorAll('k-aside-item');
6
86
  const currentPath = window.location.pathname;
7
87
 
@@ -17,4 +97,6 @@
17
97
  const menu = item.closest('k-aside-menu');
18
98
  if (menu) menu.setAttribute('open', '');
19
99
  }
20
- });</script></fragment>
100
+ });
101
+ </script>
102
+ </fragment>
@@ -1,7 +1,70 @@
1
1
  <!--
2
2
  locked: true
3
3
  -->
4
- <page title="Setting - Admin"><content><script type="module" src="/kempo-ui/components/Icon.js"></script><script type="module" src="/kempo-ui/components/Toggle.js"></script><script type="module" src="/admin/components/Monaco.js"></script><script type="module" src="/kempo/components/Permission.js"></script><div class="mb"><a href="/admin/settings/" class="no-link"><button class="mbh"><k-icon name="arrow" direction="left"></k-icon>Settings</button></a><div class="d-f mb0" style="align-items: center; justify-content: space-between;"><div><h1 class="mb0" id="pageTitle">Setting</h1><p class="tc-muted mb0" id="settingDescription"></p></div><div class="d-f" style="gap: var(--spacer);"><button id="saveBtn" class="primary" disabled="disabled">Save</button> <button id="deleteBtn" class="danger" style="display: none;">Delete</button></div></div></div><div id="loading">Loading setting...</div><div id="notFound" style="display: none;"><p>Setting not found.</p><a href="/admin/settings/">Back to Settings</a></div><div id="content" style="display: none;"><div class="card"><h2>Value</h2><div id="editorContainer" class="mb"></div></div><div class="card"><h2>Metadata</h2><div class="mb"><label class="d-b mbh">Type</label> <select id="typeSelect" class="full"><option value="string">String</option><option value="number">Number</option><option value="boolean">Boolean</option><option value="json">JSON</option></select></div><div class="mb d-f" style="align-items: center; gap: var(--spacer_h);"><k-toggle id="publicToggle"></k-toggle><label>Public (accessible without authentication)</label></div><div class="mb"><label class="d-b mbh">Description</label> <textarea id="descriptionInput" class="full" rows="3"></textarea></div><div class="mb d-f" style="gap: var(--spacer);"><div><span class="tc-muted">Created:</span> <span id="createdAt"></span></div><div><span class="tc-muted">Updated:</span> <span id="updatedAt"></span></div></div></div></div><script type="module">import { getSetting, setSetting, deleteSetting, getAllCurrentUserPermissions } from '/kempo/sdk.js';
4
+ <page title="Setting - Admin">
5
+ <content>
6
+ <script type="module" src="/kempo-ui/components/Icon.js"></script>
7
+ <script type="module" src="/kempo-ui/components/Toggle.js"></script>
8
+ <script type="module" src="/admin/components/Monaco.js"></script>
9
+ <script type="module" src="/kempo/components/Permission.js"></script>
10
+
11
+ <div class="mb">
12
+ <a href="/admin/settings/" class="no-link">
13
+ <button class="mbh"><k-icon name="arrow" direction="left"></k-icon> Settings</button>
14
+ </a>
15
+ <div class="d-f mb0" style="align-items: center; justify-content: space-between;">
16
+ <div>
17
+ <h1 class="mb0" id="pageTitle">Setting</h1>
18
+ <p class="tc-muted mb0" id="settingDescription"></p>
19
+ </div>
20
+ <div class="d-f" style="gap: var(--spacer);">
21
+ <button id="saveBtn" class="primary" disabled>Save</button>
22
+ <button id="deleteBtn" class="danger" style="display: none;">Delete</button>
23
+ </div>
24
+ </div>
25
+ </div>
26
+
27
+ <div id="loading">Loading setting...</div>
28
+ <div id="notFound" style="display: none;">
29
+ <p>Setting not found.</p>
30
+ <a href="/admin/settings/">Back to Settings</a>
31
+ </div>
32
+ <div id="content" style="display: none;">
33
+
34
+ <div class="card">
35
+ <h2>Value</h2>
36
+ <div id="editorContainer" class="mb"></div>
37
+ </div>
38
+
39
+ <div class="card">
40
+ <h2>Metadata</h2>
41
+ <div class="mb">
42
+ <label class="d-b mbh">Type</label>
43
+ <select id="typeSelect" class="full">
44
+ <option value="string">String</option>
45
+ <option value="number">Number</option>
46
+ <option value="boolean">Boolean</option>
47
+ <option value="json">JSON</option>
48
+ </select>
49
+ </div>
50
+ <div class="mb d-f" style="align-items: center; gap: var(--spacer_h);">
51
+ <k-toggle id="publicToggle"></k-toggle>
52
+ <label>Public (accessible without authentication)</label>
53
+ </div>
54
+ <div class="mb">
55
+ <label class="d-b mbh">Description</label>
56
+ <textarea id="descriptionInput" class="full" rows="3"></textarea>
57
+ </div>
58
+ <div class="mb d-f" style="gap: var(--spacer);">
59
+ <div><span class="tc-muted">Created:</span> <span id="createdAt"></span></div>
60
+ <div><span class="tc-muted">Updated:</span> <span id="updatedAt"></span></div>
61
+ </div>
62
+ </div>
63
+
64
+ </div>
65
+
66
+ <script type="module">
67
+ import { getSetting, setSetting, deleteSetting, getAllCurrentUserPermissions } from '/kempo/sdk.js';
5
68
  import Toast from '/kempo-ui/components/Toast.js';
6
69
  import Dialog from '/kempo-ui/components/Dialog.js';
7
70
 
@@ -174,7 +237,9 @@
174
237
  }
175
238
  break;
176
239
  }
240
+ currentType = newType;
177
241
  await renderEditor(newType, converted);
242
+ setTimeout(checkDirty, 0);
178
243
  });
179
244
 
180
245
  /*
@@ -182,7 +247,7 @@
182
247
  */
183
248
 
184
249
  if(canEditValue){
185
- $saveBtn.disabled = false;
250
+ $saveBtn.disabled = true;
186
251
  } else {
187
252
  $typeSelect.disabled = true;
188
253
  $descriptionInput.readOnly = true;
@@ -198,6 +263,36 @@
198
263
  $deleteBtn.style.display = '';
199
264
  }
200
265
 
266
+ /*
267
+ Change detection
268
+ */
269
+
270
+ const checkDirty = () => {
271
+ if(!canEditValue){
272
+ $saveBtn.disabled = true;
273
+ return;
274
+ }
275
+
276
+ let currentValue;
277
+ try { currentValue = getValueFromEditor(); }
278
+ catch(e){ currentValue = undefined; }
279
+
280
+ const dirty = currentValue !== settingData.value
281
+ || $typeSelect.value !== settingData.type
282
+ || $publicToggle.value !== settingData.isPublic
283
+ || $descriptionInput.value.trim() !== (settingData.description || '');
284
+
285
+ $saveBtn.disabled = !dirty;
286
+ };
287
+
288
+ $typeSelect.addEventListener('change', () => {
289
+ setTimeout(checkDirty, 0);
290
+ });
291
+ $publicToggle.addEventListener('change', checkDirty);
292
+ $descriptionInput.addEventListener('input', checkDirty);
293
+ $editorContainer.addEventListener('input', checkDirty, true);
294
+ $editorContainer.addEventListener('change', checkDirty, true);
295
+
201
296
  /*
202
297
  Save
203
298
  */
@@ -219,14 +314,21 @@
219
314
  isPublic: $publicToggle.value,
220
315
  description: $descriptionInput.value.trim()
221
316
  });
222
- $saveBtn.disabled = !canEditValue;
223
317
 
224
318
  if(saveError){
225
319
  Toast.error(saveError.msg || 'Failed to save setting');
320
+ checkDirty();
226
321
  return;
227
322
  }
323
+
324
+ settingData.value = value;
325
+ settingData.type = $typeSelect.value;
326
+ settingData.isPublic = $publicToggle.value;
327
+ settingData.description = $descriptionInput.value.trim();
328
+
228
329
  Toast.success('Setting saved');
229
330
  document.getElementById('updatedAt').textContent = new Date().toLocaleString();
331
+ checkDirty();
230
332
  };
231
333
 
232
334
  $saveBtn.addEventListener('click', save);
@@ -257,4 +359,8 @@
257
359
  }
258
360
  );
259
361
  });
260
- }</script></content></page>
362
+ }
363
+ </script>
364
+
365
+ </content>
366
+ </page>