clay-server 5.2.0-beta.9 → 5.2.0
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/README.md +0 -4
- package/lib/clay-product-control-tools.js +1 -0
- package/lib/clay-product-control.js +14 -11
- package/lib/clay-vendor-usage.js +44 -0
- package/lib/github-star-count.js +147 -0
- package/lib/notes-checklist.js +43 -1
- package/lib/notes.js +2 -1
- package/lib/project-session-notes.js +33 -8
- package/lib/project-sessions.js +63 -24
- package/lib/project-start-protocol.js +29 -0
- package/lib/project-vendor-login.js +2 -0
- package/lib/project.js +5 -1
- package/lib/public/app.js +27 -18
- package/lib/public/css/contextual-clay.css +1 -1
- package/lib/public/css/filebrowser.css +1 -1
- package/lib/public/css/mate-loading-scene.css +21 -0
- package/lib/public/css/overlays.css +64 -256
- package/lib/public/css/project-mate-creation.css +5 -6
- package/lib/public/css/project-start.css +108 -0
- package/lib/public/css/projects-hub.css +53 -14
- package/lib/public/css/settings-shell.css +103 -0
- package/lib/public/css/sidebar.css +7 -0
- package/lib/public/css/title-bar.css +83 -0
- package/lib/public/index.html +50 -63
- package/lib/public/modules/account-transport-settings.js +8 -2
- package/lib/public/modules/admin-settings-email.js +7 -2
- package/lib/public/modules/admin-settings-invitations.js +2 -2
- package/lib/public/modules/admin-settings-projects.js +2 -2
- package/lib/public/modules/admin-settings-ui.js +20 -4
- package/lib/public/modules/admin-settings-users.js +4 -4
- package/lib/public/modules/app-home-hub.js +2 -1
- package/lib/public/modules/app-messages.js +10 -2
- package/lib/public/modules/app-projects.js +1 -407
- package/lib/public/modules/app-rate-limit.js +12 -1
- package/lib/public/modules/clay-tool-presentation.js +1 -0
- package/lib/public/modules/contextual-clay.js +3 -1
- package/lib/public/modules/github-star.js +66 -0
- package/lib/public/modules/home-surface-boot.js +0 -1
- package/lib/public/modules/mate-loading-scene.js +17 -0
- package/lib/public/modules/pane-appearance-bridge.js +59 -0
- package/lib/public/modules/profile.js +11 -3
- package/lib/public/modules/project-mate-creation-workspace.js +13 -4
- package/lib/public/modules/project-session-visibility-settings.js +19 -16
- package/lib/public/modules/project-settings-environment.js +12 -1
- package/lib/public/modules/project-settings.js +119 -129
- package/lib/public/modules/project-start-dialog.js +130 -0
- package/lib/public/modules/project-start-folder-state.js +78 -0
- package/lib/public/modules/project-start-folder-view.js +190 -0
- package/lib/public/modules/project-start-forms.js +66 -0
- package/lib/public/modules/project-start-path.js +60 -0
- package/lib/public/modules/project-start-state.js +54 -0
- package/lib/public/modules/project-start-submit.js +67 -0
- package/lib/public/modules/projects-hub-view.js +32 -44
- package/lib/public/modules/projects-hub.js +39 -28
- package/lib/public/modules/server-settings.js +36 -91
- package/lib/public/modules/settings-project-target.js +56 -0
- package/lib/public/modules/settings-select.js +1 -1
- package/lib/public/modules/settings-shell-registry.js +88 -0
- package/lib/public/modules/settings-shell-view.js +104 -0
- package/lib/public/modules/settings-shell.js +342 -0
- package/lib/public/modules/sidebar-mobile.js +8 -30
- package/lib/public/modules/sidebar-projects.js +2 -1
- package/lib/public/modules/theme.js +31 -3
- package/lib/public/modules/user-settings-integrations.js +2 -1
- package/lib/public/modules/user-settings-layout.js +12 -34
- package/lib/public/modules/user-settings-profile.js +1 -1
- package/lib/public/modules/user-settings.js +18 -85
- package/lib/public/modules/vendor-usage-format.js +93 -0
- package/lib/public/modules/vendor-usage-list.js +45 -0
- package/lib/public/modules/vendor-usage-model.js +215 -0
- package/lib/public/modules/vendor-usage-overview.js +323 -0
- package/lib/public/style.css +10 -7
- package/lib/public/welcome-art/conversation-desk.png +0 -0
- package/lib/public/welcome-art/mate-clay.png +0 -0
- package/lib/public/welcome-art/project-clay.png +0 -0
- package/lib/sdk-bridge.js +6 -1
- package/lib/sdk-message-processor.js +9 -1
- package/lib/sdk-quota-snapshot.js +20 -2
- package/lib/server-github-stars.js +39 -0
- package/lib/server-global-ws.js +21 -17
- package/lib/server.js +11 -0
- package/lib/session-notes-mcp-server.js +26 -4
- package/lib/session-notes-writes.js +88 -0
- package/lib/session-visibility.js +20 -8
- package/lib/sessions.js +12 -2
- package/lib/vendor-usage-acp-readers.js +97 -0
- package/lib/vendor-usage-capabilities.js +88 -0
- package/lib/vendor-usage-http-readers.js +214 -0
- package/lib/vendor-usage-metrics.js +47 -0
- package/lib/vendor-usage-native-readers.js +106 -0
- package/lib/vendor-usage-overview.js +406 -0
- package/lib/vendor-usage-service.js +281 -0
- package/lib/ws-schema.js +4 -2
- package/lib/yoke/adapters/claude.js +12 -0
- package/lib/yoke/adapters/codex-query-contract.js +1 -0
- package/lib/yoke/adapters/codex.js +45 -12
- package/lib/yoke/claude-hook-installer.js +1 -0
- package/lib/yoke/codex-dynamic-tool-names.js +80 -0
- package/lib/yoke/codex-model-catalog.js +37 -3
- package/lib/yoke/muse-services.js +16 -3
- package/lib/yoke/providers/claude-model-descriptions.js +22 -2
- package/lib/yoke/vendor-registry.js +6 -2
- package/package.json +2 -1
- package/lib/public/modules/server-settings-navigation.js +0 -39
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* Unified full-screen settings shell. Personal, Project and Server panes keep
|
|
2
|
+
their ids (so the shared settings-ui primitives still apply) and mount into
|
|
3
|
+
the shell content; their former modal chrome is neutralised here. */
|
|
4
|
+
#settings-shell {
|
|
5
|
+
position: fixed; inset: 0; z-index: 600; display: flex; flex-direction: column;
|
|
6
|
+
background: var(--bg); color: var(--text);
|
|
7
|
+
}
|
|
8
|
+
#settings-shell.hidden { display: none; }
|
|
9
|
+
#settings-shell [hidden], #settings-shell .hidden { display: none !important; }
|
|
10
|
+
#settings-shell :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
11
|
+
|
|
12
|
+
/* --- Header: close and scope tabs --- */
|
|
13
|
+
.settings-shell-header {
|
|
14
|
+
flex: 0 0 auto; display: flex; align-items: center; gap: 12px; min-height: 48px;
|
|
15
|
+
padding: calc(var(--safe-top) + 6px) 16px 6px; border-bottom: 1px solid var(--border-subtle); background: var(--sidebar-bg);
|
|
16
|
+
}
|
|
17
|
+
.settings-shell-close {
|
|
18
|
+
display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px 0 8px; border: 1px solid var(--border);
|
|
19
|
+
border-radius: 8px; background: var(--bg); color: var(--text-secondary); font: inherit; font-size: 13px; cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
.settings-shell-close:hover { color: var(--text); border-color: var(--text-dimmer); }
|
|
22
|
+
.settings-shell-close svg { width: 16px; height: 16px; }
|
|
23
|
+
.settings-shell-close kbd { font: inherit; font-size: 11px; color: var(--text-dimmer); padding-left: 4px; }
|
|
24
|
+
.settings-scope-tabs { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--border); border-radius: 9px; background: var(--bg-alt); }
|
|
25
|
+
.settings-scope-tab {
|
|
26
|
+
min-width: 76px; height: 28px; padding: 0 12px; border: 0; border-radius: 6px; background: none;
|
|
27
|
+
color: var(--text-muted); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
.settings-scope-tab:hover { color: var(--text); }
|
|
30
|
+
.settings-scope-tab.active { background: var(--bg); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, .12); }
|
|
31
|
+
|
|
32
|
+
/* --- Body: navigation + content --- */
|
|
33
|
+
.settings-shell-body { flex: 1 1 auto; min-height: 0; display: flex; }
|
|
34
|
+
.settings-shell-nav { flex: 0 0 240px; width: 240px; overflow-y: auto; background: var(--sidebar-bg); border-right: 1px solid var(--border-subtle); }
|
|
35
|
+
.settings-shell-nav-inner { padding: 20px 12px 32px 14px; }
|
|
36
|
+
.settings-scope-head { display: flex; flex-direction: column; gap: 2px; padding: 0 10px 12px; margin-bottom: 8px; border-bottom: 1px solid var(--border-subtle); }
|
|
37
|
+
.settings-scope-head strong { font-size: 14px; color: var(--text); }
|
|
38
|
+
.settings-scope-head small { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
39
|
+
.settings-scope-hint { font-size: 12px; line-height: 1.35; color: var(--text-muted); }
|
|
40
|
+
.settings-project-picker { padding: 0 4px 12px; }
|
|
41
|
+
.settings-project-picker .settings-label { display: block; margin: 0 0 6px 6px; font-size: 12px; color: var(--text-muted); }
|
|
42
|
+
.settings-project-picker .settings-picker { display: block; width: 100%; }
|
|
43
|
+
.settings-project-picker .settings-picker-menu { right: auto; left: 0; width: 100%; max-width: none; }
|
|
44
|
+
.settings-project-picker select { width: 100%; }
|
|
45
|
+
.settings-shell-nav .settings-nav-item { min-height: 32px; padding: 6px 10px; font-size: 13px; }
|
|
46
|
+
.settings-shell-nav .settings-nav-item.active { background: rgba(var(--overlay-rgb), .08); color: var(--text); }
|
|
47
|
+
.settings-shell-nav .settings-nav-item:focus-visible { outline-offset: -2px; }
|
|
48
|
+
.settings-shell-nav .settings-nav-dropdown { display: none; }
|
|
49
|
+
.settings-shell-content { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 28px 40px calc(var(--safe-bottom) + 56px); }
|
|
50
|
+
.settings-shell-status { max-width: 760px; margin: 0 0 16px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-alt); color: var(--text-secondary); font-size: 13px; }
|
|
51
|
+
.settings-shell-status[data-state="error"] { border-color: color-mix(in srgb, var(--error) 40%, var(--border)); color: var(--error); }
|
|
52
|
+
|
|
53
|
+
/* --- Panes: neutralise the former modal/overlay chrome --- */
|
|
54
|
+
#settings-shell .settings-pane { position: static; inset: auto; z-index: auto; display: block; width: 100%; max-width: 760px; margin: 0; padding: 0; background: none; backdrop-filter: none; animation: none; overflow: visible; }
|
|
55
|
+
#settings-shell .settings-pane.hidden { display: none !important; }
|
|
56
|
+
#user-settings .us-modal, #project-settings .ps-modal {
|
|
57
|
+
position: static; display: block; width: auto; height: auto; border: 0; border-radius: 0; background: none; box-shadow: none; animation: none; overflow: visible;
|
|
58
|
+
}
|
|
59
|
+
#user-settings .us-modal-body, #project-settings .project-settings-layout { display: block; height: auto; overflow: visible; background: none; }
|
|
60
|
+
#user-settings .us-modal-content, #project-settings .project-settings-content, #server-settings .server-settings-content {
|
|
61
|
+
max-width: none; padding: 0; background: none; overflow: visible;
|
|
62
|
+
}
|
|
63
|
+
#project-settings .project-settings-content-inner, #server-settings .server-settings-content-inner { padding: 0; }
|
|
64
|
+
#server-settings .server-settings-layout { display: block; height: auto; background: none; }
|
|
65
|
+
#server-settings .server-settings-layout::after { display: none; }
|
|
66
|
+
#project-settings .ps-section h2, #user-settings .us-section h2, #server-settings .server-settings-section h2 { margin-top: 0; }
|
|
67
|
+
#project-settings.ps-no-target .ps-section { display: none; }
|
|
68
|
+
#project-settings .settings-empty { padding: 24px 0; }
|
|
69
|
+
|
|
70
|
+
/* --- Inline subviews (admin editors, avatar crop): replace the page's list in place --- */
|
|
71
|
+
.has-subview > :not(h2):not(.settings-subview) { display: none !important; }
|
|
72
|
+
.admin-subview, .avatar-positioner-inline { display: block; position: static; padding: 0; background: none; }
|
|
73
|
+
.admin-subview .admin-modal {
|
|
74
|
+
position: static; width: auto; max-width: 640px; max-height: none; margin: 0; border: 1px solid var(--border);
|
|
75
|
+
border-radius: 10px; background: var(--bg); box-shadow: none;
|
|
76
|
+
}
|
|
77
|
+
.admin-subview .admin-modal-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border-subtle); }
|
|
78
|
+
.admin-subview .admin-modal-header h3 { margin: 0; font-size: 14px; }
|
|
79
|
+
.admin-subview .admin-modal-body { padding: 14px 16px; overflow: visible; max-height: none; }
|
|
80
|
+
.admin-subview .admin-modal-footer { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border-subtle); }
|
|
81
|
+
.avatar-positioner-inline .avatar-positioner-container { position: relative; display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 360px; padding: 16px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg); box-shadow: none; }
|
|
82
|
+
|
|
83
|
+
/* --- Narrow screens: tabs in the header, page select replaces the nav list --- */
|
|
84
|
+
@media (max-width: 800px) {
|
|
85
|
+
.settings-shell-header { padding-left: 10px; padding-right: 10px; gap: 8px; }
|
|
86
|
+
.settings-shell-close span, .settings-shell-close kbd { display: none; }
|
|
87
|
+
.settings-shell-close { width: 32px; padding: 0; justify-content: center; }
|
|
88
|
+
.settings-scope-tabs { flex: 1 1 auto; min-width: 0; }
|
|
89
|
+
.settings-scope-tab { flex: 1 1 0; min-width: 0; padding: 0 6px; }
|
|
90
|
+
.settings-shell-body { flex-direction: column; }
|
|
91
|
+
.settings-shell-nav { flex: 0 0 auto; width: 100%; max-height: 40%; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
|
|
92
|
+
.settings-shell-nav-inner { padding: 10px 12px; display: grid; gap: 8px; }
|
|
93
|
+
.settings-scope-head { display: none; }
|
|
94
|
+
.settings-project-picker { padding: 0; }
|
|
95
|
+
.settings-project-picker .settings-picker { display: none; }
|
|
96
|
+
.settings-project-picker select { height: 36px; }
|
|
97
|
+
.settings-shell-nav-items { display: none; }
|
|
98
|
+
.settings-shell-nav .settings-nav-dropdown { display: block; width: 100%; height: 36px; margin: 0; }
|
|
99
|
+
.settings-shell-content { padding: 18px 14px calc(var(--safe-bottom) + 40px); }
|
|
100
|
+
}
|
|
101
|
+
@media (prefers-reduced-motion: reduce) {
|
|
102
|
+
#settings-shell * { transition: none !important; animation: none !important; }
|
|
103
|
+
}
|
|
@@ -1392,6 +1392,13 @@ body:not(.home-active) #icon-strip-hint-mate { display: none; }
|
|
|
1392
1392
|
.user-island-profile:active { transform: translateY(1px); }
|
|
1393
1393
|
.user-island-profile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1394
1394
|
|
|
1395
|
+
.user-island-quick-controls {
|
|
1396
|
+
display: flex;
|
|
1397
|
+
align-items: center;
|
|
1398
|
+
justify-content: center;
|
|
1399
|
+
gap: 4px;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1395
1402
|
.cursor-share-toggle {
|
|
1396
1403
|
position: relative;
|
|
1397
1404
|
width: var(--account-rail-cursor-target, 28px);
|
|
@@ -93,6 +93,10 @@
|
|
|
93
93
|
right: 10px;
|
|
94
94
|
top: 50%;
|
|
95
95
|
transform: translateY(-50%);
|
|
96
|
+
/* The transform makes this group its own stacking context, so its popovers
|
|
97
|
+
are ordered by this value. Sit above chat layers but below contextual Clay
|
|
98
|
+
(160), the mobile overlays and modals. */
|
|
99
|
+
z-index: 150;
|
|
96
100
|
display: flex;
|
|
97
101
|
align-items: center;
|
|
98
102
|
gap: 2px;
|
|
@@ -906,3 +910,82 @@
|
|
|
906
910
|
.rate-limit-popover { font-size: 11px; padding: 6px 10px; }
|
|
907
911
|
.header-context { width: 50px; }
|
|
908
912
|
}
|
|
913
|
+
|
|
914
|
+
/* --- GitHub Star link (desktop only, beside the brand) --- */
|
|
915
|
+
.top-bar-star {
|
|
916
|
+
display: flex;
|
|
917
|
+
align-items: center;
|
|
918
|
+
gap: 6px;
|
|
919
|
+
flex: 0 0 auto;
|
|
920
|
+
white-space: nowrap;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
.top-bar-star-pill {
|
|
924
|
+
display: inline-flex;
|
|
925
|
+
align-items: stretch;
|
|
926
|
+
height: 20px;
|
|
927
|
+
border: 1px solid var(--border-subtle);
|
|
928
|
+
border-radius: 6px;
|
|
929
|
+
background: rgba(var(--overlay-rgb), 0.03);
|
|
930
|
+
color: var(--text-muted);
|
|
931
|
+
font-size: 11px;
|
|
932
|
+
font-weight: 600;
|
|
933
|
+
line-height: 18px;
|
|
934
|
+
text-decoration: none;
|
|
935
|
+
overflow: hidden;
|
|
936
|
+
transition: background 0.15s, border-color 0.15s, color 0.15s;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.top-bar-star-pill:hover {
|
|
940
|
+
background: rgba(var(--overlay-rgb), 0.08);
|
|
941
|
+
border-color: var(--border);
|
|
942
|
+
color: var(--text-secondary);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
.top-bar-star-pill:active { transform: translateY(1px); }
|
|
946
|
+
|
|
947
|
+
.top-bar-star-pill:focus-visible {
|
|
948
|
+
outline: 2px solid var(--accent);
|
|
949
|
+
outline-offset: 2px;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
.top-bar-star-mark {
|
|
953
|
+
align-self: center;
|
|
954
|
+
width: 12px;
|
|
955
|
+
height: 12px;
|
|
956
|
+
margin: 0 4px 0 6px;
|
|
957
|
+
fill: currentColor;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.top-bar-star-label { padding-right: 6px; }
|
|
961
|
+
|
|
962
|
+
.top-bar-star-count {
|
|
963
|
+
padding: 0 6px;
|
|
964
|
+
border-left: 1px solid var(--border-subtle);
|
|
965
|
+
font-variant-numeric: tabular-nums;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.top-bar-star-count.hidden { display: none; }
|
|
969
|
+
|
|
970
|
+
@media (max-width: 790px) {
|
|
971
|
+
.top-bar-star-long { display: none; }
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/* The CTA yields to functional controls sharing the left group: the install
|
|
975
|
+
pill shortens the label first (and takes the pill when space is tight); a
|
|
976
|
+
visible update notice takes the whole CTA. */
|
|
977
|
+
.top-bar-left-pills:has(.top-bar-install-btn:not(.hidden)) .top-bar-star-long { display: none; }
|
|
978
|
+
.top-bar-left-pills:has(#update-pill-wrap:not(.hidden)) .top-bar-star { display: none; }
|
|
979
|
+
|
|
980
|
+
@media (max-width: 1100px) {
|
|
981
|
+
.top-bar-left-pills:has(.top-bar-install-btn:not(.hidden)) .top-bar-star { display: none; }
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
@media (max-width: 768px) {
|
|
985
|
+
.top-bar-star { display: none; }
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
@media (prefers-reduced-motion: reduce) {
|
|
989
|
+
.top-bar-star-pill { transition: none; }
|
|
990
|
+
.top-bar-star-pill:active { transform: none; }
|
|
991
|
+
}
|
package/lib/public/index.html
CHANGED
|
@@ -60,6 +60,9 @@ body { background: transparent; color: inherit; }
|
|
|
60
60
|
<div id="top-bar">
|
|
61
61
|
<div class="top-bar-left-pills">
|
|
62
62
|
<a class="top-bar-brand-link" href="https://github.com/chadbyte/clay" target="_blank" rel="noopener noreferrer" aria-label="Clay Studio repository"><span class="top-bar-brand-wordmark" aria-hidden="true"></span></a>
|
|
63
|
+
<div class="top-bar-star" id="github-star">
|
|
64
|
+
<a class="top-bar-star-pill" id="github-star-link" href="https://github.com/chadbyte/clay" target="_blank" rel="noopener noreferrer" aria-label="Star Clay on GitHub"><svg class="top-bar-star-mark" viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg><span class="top-bar-star-label">Star<span class="top-bar-star-long"> on GitHub</span></span><span class="top-bar-star-count hidden" id="github-star-count"></span></a>
|
|
65
|
+
</div>
|
|
63
66
|
<button id="pwa-install-pill" class="top-bar-install-btn hidden" title="Open as app"><i data-lucide="download"></i> Open as app</button>
|
|
64
67
|
<div id="update-pill-wrap" class="top-bar-update hidden">
|
|
65
68
|
<button id="update-pill" class="top-bar-update-btn"><i data-lucide="arrow-up-circle"></i> <span id="update-version"></span> is available. Update now</button>
|
|
@@ -74,9 +77,8 @@ body { background: transparent; color: inherit; }
|
|
|
74
77
|
<!-- Pill badges -->
|
|
75
78
|
<div id="skip-perms-pill" class="top-bar-pill pill-error hidden"><i data-lucide="shield-off"></i> <span>Skip perms</span></div>
|
|
76
79
|
<div id="client-count" class="top-bar-pill pill-accent hidden"><i data-lucide="users"></i> <span id="client-count-text"></span></div>
|
|
77
|
-
<button id="share-pill" title="Share"><i data-lucide="share-2"></i></button>
|
|
78
80
|
<button id="notif-center-btn" title="Notifications"><i data-lucide="bell"></i><span id="notif-center-badge" class="notif-badge hidden">0</span></button>
|
|
79
|
-
<button id="server-settings-btn" title="
|
|
81
|
+
<button id="server-settings-btn" title="Settings" aria-label="Settings" aria-expanded="false"><i data-lucide="settings"></i></button>
|
|
80
82
|
</div>
|
|
81
83
|
</div>
|
|
82
84
|
|
|
@@ -657,13 +659,10 @@ body { background: transparent; color: inherit; }
|
|
|
657
659
|
</div>
|
|
658
660
|
</div>
|
|
659
661
|
<div id="project-settings" class="hidden">
|
|
660
|
-
<div class="ps-modal"
|
|
661
|
-
<header class="ps-modal-header"><div><h2 id="ps-modal-title">Project settings</h2><span id="ps-nav-title"></span></div><button class="settings-btn-sm" id="project-settings-close" aria-label="Close project settings"><i data-lucide="x"></i></button></header>
|
|
662
|
+
<div class="ps-modal">
|
|
662
663
|
<div class="project-settings-layout">
|
|
663
|
-
<nav class="project-settings-nav" aria-label="Project settings">
|
|
664
|
-
<div class="project-settings-nav-inner"><select id="ps-nav-dropdown" class="settings-nav-dropdown" aria-label="Settings page"></select><div class="server-settings-nav-items"></div></div>
|
|
665
|
-
</nav>
|
|
666
664
|
<div class="project-settings-content"><div class="project-settings-content-inner">
|
|
665
|
+
<div class="settings-empty" id="ps-empty" hidden><h2 tabindex="-1">No project selected</h2><p id="ps-empty-text" class="settings-hint"></p></div>
|
|
667
666
|
<section class="ps-section active" data-section="profile">
|
|
668
667
|
<h2>General</h2><p class="ps-section-desc">Identify this project in your workspace.</p>
|
|
669
668
|
<div class="ps-project-identity">
|
|
@@ -680,8 +679,8 @@ body { background: transparent; color: inherit; }
|
|
|
680
679
|
<div class="settings-field" id="ps-session-visibility-default-field" style="display:none">
|
|
681
680
|
<label class="settings-label" for="ps-session-visibility-default">New session visibility</label>
|
|
682
681
|
<div class="settings-hint">Applies to new project conversations and Issue Start work sessions. Existing sessions, hidden work, and delegated workflows keep their current visibility.</div>
|
|
682
|
+
<div class="settings-hint hidden" id="ps-session-visibility-default-owner-hint">Only the project owner can change this setting. Administrators can view it here but cannot change it.</div>
|
|
683
683
|
<div class="settings-hint hidden" id="ps-session-visibility-default-inherited-hint">This worktree inherits the setting from its parent project. Change it there.</div>
|
|
684
|
-
<div class="settings-hint hidden" id="ps-session-visibility-default-non-current-hint">Open this project to change this setting.</div>
|
|
685
684
|
<select class="ps-select" id="ps-session-visibility-default">
|
|
686
685
|
<option value="private">Private</option>
|
|
687
686
|
<option value="shared">Shared with project members</option>
|
|
@@ -737,11 +736,16 @@ body { background: transparent; color: inherit; }
|
|
|
737
736
|
<span class="user-island-cta hidden">Personalize your name</span>
|
|
738
737
|
</div>
|
|
739
738
|
</button>
|
|
740
|
-
<
|
|
741
|
-
<
|
|
742
|
-
|
|
739
|
+
<div class="user-island-quick-controls">
|
|
740
|
+
<button id="cursor-share-toggle" class="cursor-share-toggle" type="button" aria-pressed="false" aria-label="Cursor sharing unavailable" disabled>
|
|
741
|
+
<i data-lucide="mouse-pointer-2" class="cursor-share-icon" aria-hidden="true"></i>
|
|
742
|
+
</button>
|
|
743
|
+
<button id="appearance-mode-toggle" class="cursor-share-toggle" type="button" aria-label="Switch to light mode" title="Switch to light mode">
|
|
744
|
+
<i data-lucide="sun" class="cursor-share-icon" aria-hidden="true"></i>
|
|
745
|
+
</button>
|
|
746
|
+
</div>
|
|
743
747
|
<div class="user-island-actions">
|
|
744
|
-
<button id="user-settings-btn" title="
|
|
748
|
+
<button id="user-settings-btn" title="Personal settings" aria-label="Personal settings" aria-expanded="false"><i data-lucide="settings"></i></button>
|
|
745
749
|
</div>
|
|
746
750
|
</div>
|
|
747
751
|
|
|
@@ -780,19 +784,31 @@ body { background: transparent; color: inherit; }
|
|
|
780
784
|
</div>
|
|
781
785
|
</div>
|
|
782
786
|
|
|
783
|
-
<!-- ===
|
|
787
|
+
<!-- === Unified settings shell (full screen): Personal, Project and Server panes mount into it === -->
|
|
788
|
+
<div id="settings-shell" class="hidden" role="region" aria-label="Settings">
|
|
789
|
+
<header class="settings-shell-header">
|
|
790
|
+
<button type="button" id="settings-shell-close" class="settings-shell-close" aria-label="Close settings"><i data-lucide="arrow-left" aria-hidden="true"></i><span>Back</span><kbd>Esc</kbd></button>
|
|
791
|
+
<div class="settings-scope-tabs" id="settings-scope-tabs" role="group" aria-label="Settings scope"></div>
|
|
792
|
+
</header>
|
|
793
|
+
<div class="settings-shell-body">
|
|
794
|
+
<nav class="settings-shell-nav" aria-label="Settings navigation">
|
|
795
|
+
<div class="settings-shell-nav-inner">
|
|
796
|
+
<div class="settings-scope-head"><strong id="settings-scope-title">Settings</strong><small id="settings-server-name" hidden></small><span id="settings-scope-hint" class="settings-scope-hint"></span></div>
|
|
797
|
+
<div class="settings-project-picker" id="settings-project-picker" hidden><label class="settings-label" for="settings-project-select">Project</label><select id="settings-project-select" class="ps-select" aria-label="Project"></select></div>
|
|
798
|
+
<select id="settings-page-select" class="settings-nav-dropdown" aria-label="Settings page"></select>
|
|
799
|
+
<div class="settings-shell-nav-items" id="settings-page-nav"></div>
|
|
800
|
+
</div>
|
|
801
|
+
</nav>
|
|
802
|
+
<main class="settings-shell-content" id="settings-shell-content">
|
|
803
|
+
<p id="settings-shell-status" class="settings-shell-status" role="status" hidden></p>
|
|
804
|
+
</main>
|
|
805
|
+
</div>
|
|
806
|
+
</div>
|
|
807
|
+
|
|
808
|
+
<!-- === Personal settings pane === -->
|
|
784
809
|
<div id="user-settings" class="hidden">
|
|
785
|
-
<div class="confirm-backdrop" id="user-settings-backdrop"></div>
|
|
786
810
|
<div class="us-modal">
|
|
787
|
-
<div class="us-modal-header">
|
|
788
|
-
<span class="us-modal-title">User Settings</span>
|
|
789
|
-
<button class="us-modal-close" id="user-settings-close" title="Close"><i data-lucide="x"></i></button>
|
|
790
|
-
</div>
|
|
791
811
|
<div class="us-modal-body">
|
|
792
|
-
<nav class="us-modal-nav">
|
|
793
|
-
<select id="user-settings-nav-dropdown" class="settings-nav-dropdown"></select>
|
|
794
|
-
<div class="us-modal-nav-items"></div>
|
|
795
|
-
</nav>
|
|
796
812
|
<div class="us-modal-content">
|
|
797
813
|
|
|
798
814
|
<div class="us-section" data-section="us-notifications">
|
|
@@ -1031,16 +1047,8 @@ body { background: transparent; color: inherit; }
|
|
|
1031
1047
|
</div>
|
|
1032
1048
|
|
|
1033
1049
|
<!-- === Server Settings (full-screen overlay) === -->
|
|
1034
|
-
<div id="server-settings" class="hidden"
|
|
1050
|
+
<div id="server-settings" class="hidden">
|
|
1035
1051
|
<div class="server-settings-layout">
|
|
1036
|
-
<nav class="server-settings-nav" aria-label="Server settings pages">
|
|
1037
|
-
<div class="server-settings-nav-inner">
|
|
1038
|
-
<div class="server-settings-nav-header">Server settings<small id="settings-server-name"></small></div>
|
|
1039
|
-
<select id="settings-nav-dropdown" class="settings-nav-dropdown" aria-label="Settings page"></select>
|
|
1040
|
-
<div class="server-settings-nav-items" id="settings-page-nav"></div>
|
|
1041
|
-
<button class="settings-nav-item" id="settings-personal-link">Personal notifications ↗</button>
|
|
1042
|
-
</div>
|
|
1043
|
-
</nav>
|
|
1044
1052
|
<div class="server-settings-content"><div class="server-settings-content-inner">
|
|
1045
1053
|
<p id="settings-access-status" role="status">Checking administrator access…</p>
|
|
1046
1054
|
<div class="server-settings-section active" data-section="overview">
|
|
@@ -1248,7 +1256,7 @@ body { background: transparent; color: inherit; }
|
|
|
1248
1256
|
<div class="settings-hint settings-restart-error hidden" id="settings-restart-error" style="margin-top: 8px;"></div>
|
|
1249
1257
|
</div>
|
|
1250
1258
|
</div>
|
|
1251
|
-
</div><section class="settings-operation settings-danger-operation"><div class="settings-danger-entry"><div class="settings-danger-entry-copy"><h3>Danger zone</h3><p>Shut down Clay for everyone. Active work stops; restarting requires access to the host.</p></div><button type="button" class="settings-btn-sm settings-btn-danger" id="settings-shutdown-review" aria-expanded="false" aria-controls="settings-shutdown-flow"><i data-lucide="power" aria-hidden="true"></i>Review shutdown…</button></div><div id="settings-shutdown-flow" hidden role="group" aria-labelledby="settings-shutdown-title"><h4 id="settings-shutdown-title">Shut down server</h4><p class="settings-hint">Stops Clay, interrupts active work and disconnects everyone. You will need shell or service-manager access to start it again.</p><label class="settings-label" for="settings-shutdown-input">Type shutdown to continue</label><div class="settings-shutdown-input-row"><input type="text" id="settings-shutdown-input" autocomplete="off" spellcheck="false"><button class="settings-btn-sm settings-btn-danger" id="settings-shutdown-btn" disabled>Shut down…</button></div><p id="settings-shutdown-error" class="settings-hint hidden" role="status"></p><button type="button" class="settings-btn-sm" id="settings-shutdown-back">Back</button></div></section></div></div></div
|
|
1259
|
+
</div><section class="settings-operation settings-danger-operation"><div class="settings-danger-entry"><div class="settings-danger-entry-copy"><h3>Danger zone</h3><p>Shut down Clay for everyone. Active work stops; restarting requires access to the host.</p></div><button type="button" class="settings-btn-sm settings-btn-danger" id="settings-shutdown-review" aria-expanded="false" aria-controls="settings-shutdown-flow"><i data-lucide="power" aria-hidden="true"></i>Review shutdown…</button></div><div id="settings-shutdown-flow" hidden role="group" aria-labelledby="settings-shutdown-title"><h4 id="settings-shutdown-title">Shut down server</h4><p class="settings-hint">Stops Clay, interrupts active work and disconnects everyone. You will need shell or service-manager access to start it again.</p><label class="settings-label" for="settings-shutdown-input">Type shutdown to continue</label><div class="settings-shutdown-input-row"><input type="text" id="settings-shutdown-input" autocomplete="off" spellcheck="false"><button class="settings-btn-sm settings-btn-danger" id="settings-shutdown-btn" disabled>Shut down…</button></div><p id="settings-shutdown-error" class="settings-hint hidden" role="status"></p><button type="button" class="settings-btn-sm" id="settings-shutdown-back">Back</button></div></section></div></div></div></div></div>
|
|
1252
1260
|
|
|
1253
1261
|
<div id="paste-modal" class="hidden" role="dialog" aria-modal="true" aria-labelledby="paste-modal-title">
|
|
1254
1262
|
<div class="confirm-backdrop"></div>
|
|
@@ -1358,37 +1366,16 @@ body { background: transparent; color: inherit; }
|
|
|
1358
1366
|
</div>
|
|
1359
1367
|
</div>
|
|
1360
1368
|
|
|
1361
|
-
<div id="
|
|
1362
|
-
<div class="
|
|
1363
|
-
<div class="
|
|
1364
|
-
<
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
<button class="
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
<div class="add-project-body">
|
|
1372
|
-
<div class="add-project-panel active" data-panel="existing">
|
|
1373
|
-
<div class="add-project-input-wrap">
|
|
1374
|
-
<span id="add-project-prefix" class="add-project-prefix hidden"></span>
|
|
1375
|
-
<input type="text" id="add-project-input" placeholder="/" autocomplete="off" spellcheck="false">
|
|
1376
|
-
<div id="add-project-suggestions" class="hidden"></div>
|
|
1377
|
-
</div>
|
|
1378
|
-
</div>
|
|
1379
|
-
<div class="add-project-panel" data-panel="create">
|
|
1380
|
-
<input type="text" id="add-project-create-input" placeholder="Project name" autocomplete="off" spellcheck="false">
|
|
1381
|
-
</div>
|
|
1382
|
-
<div class="add-project-panel" data-panel="clone">
|
|
1383
|
-
<input type="text" id="add-project-clone-input" placeholder="https://github.com/user/repo" autocomplete="off" spellcheck="false">
|
|
1384
|
-
<div id="add-project-clone-progress" class="hidden"><span class="clone-spinner"></span><span id="add-project-clone-text">Cloning...</span></div>
|
|
1385
|
-
</div>
|
|
1386
|
-
<div id="add-project-error" class="hidden"></div>
|
|
1387
|
-
</div>
|
|
1388
|
-
<div class="confirm-actions">
|
|
1389
|
-
<button class="confirm-btn confirm-cancel" id="add-project-cancel">Cancel</button>
|
|
1390
|
-
<button class="confirm-btn confirm-ok" id="add-project-ok">Add</button>
|
|
1391
|
-
</div>
|
|
1369
|
+
<div id="project-start-modal" class="hidden">
|
|
1370
|
+
<div class="project-start-backdrop"></div>
|
|
1371
|
+
<div class="project-start-dialog" role="dialog" aria-modal="true" aria-labelledby="project-start-title" aria-describedby="project-start-subtitle" tabindex="-1">
|
|
1372
|
+
<header class="project-start-header">
|
|
1373
|
+
<button type="button" class="project-start-icon-btn" id="project-start-back" aria-label="Back to choices" hidden><i data-lucide="arrow-left"></i></button>
|
|
1374
|
+
<h2 id="project-start-title">Start a project</h2>
|
|
1375
|
+
<button type="button" class="project-start-icon-btn" id="project-start-close" aria-label="Close"><i data-lucide="x"></i></button>
|
|
1376
|
+
</header>
|
|
1377
|
+
<p class="project-start-subtitle" id="project-start-subtitle">Start something new, or pick up where you left off.</p>
|
|
1378
|
+
<div class="project-start-body" id="project-start-body"></div>
|
|
1392
1379
|
</div>
|
|
1393
1380
|
</div>
|
|
1394
1381
|
|
|
@@ -33,8 +33,14 @@ export function initAccountTransportSettings() {
|
|
|
33
33
|
'<div class="settings-form-actions"><button class="settings-btn-sm">Save connection settings</button></div></form><p class="settings-hint" role="status"></p>';
|
|
34
34
|
anchor.after(section);
|
|
35
35
|
section.querySelectorAll('[name=origin],[name=proxies]').forEach(function (input) { input.oninput = function () {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
// A draft is the form differing from the saved values, so a manual revert clears it.
|
|
37
|
+
var saved = store.get('accountTransport') || {};
|
|
38
|
+
var origin = section.querySelector('[name=origin]').value.trim();
|
|
39
|
+
var proxies = section.querySelector('[name=proxies]').value.split(/\s+/).filter(Boolean);
|
|
40
|
+
var dirty = origin !== (saved.origin || '') || proxies.join('\n') !== (saved.trustedProxies || []).join('\n');
|
|
41
|
+
var state = Object.assign({}, saved, { dirty: dirty, error: '' });
|
|
42
|
+
if (dirty) setSettingsDraft('accountTransport', true); else clearSettingsDraft('accountTransport');
|
|
43
|
+
store.set({ accountTransport: state }); render(state);
|
|
38
44
|
}; });
|
|
39
45
|
section.querySelector('form').onsubmit = async function (event) {
|
|
40
46
|
event.preventDefault(); var password = section.querySelector('[name=password]');
|
|
@@ -96,8 +96,13 @@ function renderSmtpTab(body, cfg) {
|
|
|
96
96
|
|
|
97
97
|
body.innerHTML = html;
|
|
98
98
|
clearSettingsDraft('smtp');
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
// The draft is the form differing from what was rendered, so reverting a field clears it.
|
|
100
|
+
var fields = Array.from(body.querySelectorAll('input, select, textarea'));
|
|
101
|
+
function fieldValue(field) { return field.type === 'checkbox' ? field.checked : field.value; }
|
|
102
|
+
var baseline = fields.map(fieldValue);
|
|
103
|
+
function syncDraft() { setSettingsDraft('smtp', fields.some(function (field, index) { return fieldValue(field) !== baseline[index]; })); }
|
|
104
|
+
body.oninput = syncDraft;
|
|
105
|
+
body.onchange = syncDraft;
|
|
101
106
|
refreshIcons(body);
|
|
102
107
|
|
|
103
108
|
var errorEl = body.querySelector("#smtp-error");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
2
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
3
3
|
import { showToast, copyToClipboard, escapeHtml } from './utils.js';
|
|
4
|
-
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal } from './admin-settings-ui.js';
|
|
4
|
+
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal, mountAdminSubview } from './admin-settings-ui.js';
|
|
5
5
|
// --- Invites ---
|
|
6
6
|
export function loadInvitesTab(body) {
|
|
7
7
|
apiGet("/api/admin/invites").then(function (data) {
|
|
@@ -138,7 +138,7 @@ function showEmailInvitePrompt(body) {
|
|
|
138
138
|
'<button class="admin-modal-cancel">Cancel</button>' +
|
|
139
139
|
'</div></div>';
|
|
140
140
|
modal.innerHTML = html;
|
|
141
|
-
|
|
141
|
+
mountAdminSubview(modal);
|
|
142
142
|
prepareAdminModal(modal);
|
|
143
143
|
refreshIcons(modal);
|
|
144
144
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
2
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
3
3
|
import { showToast, copyToClipboard, escapeHtml } from './utils.js';
|
|
4
|
-
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal } from './admin-settings-ui.js';
|
|
4
|
+
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal, mountAdminSubview } from './admin-settings-ui.js';
|
|
5
5
|
// --- Projects ---
|
|
6
6
|
export function loadProjectsTab(body) {
|
|
7
7
|
var projectList = store.get('projectsHubList') || [];
|
|
@@ -168,7 +168,7 @@ function showProjectUsersModal(slug, parentBody) {
|
|
|
168
168
|
html += '</div>';
|
|
169
169
|
|
|
170
170
|
modal.innerHTML = html;
|
|
171
|
-
|
|
171
|
+
mountAdminSubview(modal);
|
|
172
172
|
prepareAdminModal(modal);
|
|
173
173
|
refreshIcons(modal);
|
|
174
174
|
|
|
@@ -14,13 +14,29 @@ export function apiPost(url, body) { return request(url, 'POST', body || {}); }
|
|
|
14
14
|
export function apiPut(url, body) { return request(url, 'PUT', body); }
|
|
15
15
|
export function apiDelete(url) { return request(url, 'DELETE'); }
|
|
16
16
|
|
|
17
|
+
// Editors open inline in the active Server settings page (a subview with its
|
|
18
|
+
// own Back/Cancel path) instead of over the page. Only destructive
|
|
19
|
+
// confirmations remain overlay dialogs.
|
|
20
|
+
export function mountAdminSubview(modal) {
|
|
21
|
+
var host = document.querySelector('#server-settings .server-settings-section.active');
|
|
22
|
+
if (!host) { document.body.appendChild(modal); return; }
|
|
23
|
+
modal.className = 'admin-subview settings-subview';
|
|
24
|
+
host.classList.add('has-subview');
|
|
25
|
+
host.appendChild(modal);
|
|
26
|
+
var observer = new MutationObserver(function () {
|
|
27
|
+
if (!host.querySelector('.settings-subview')) { host.classList.remove('has-subview'); observer.disconnect(); }
|
|
28
|
+
});
|
|
29
|
+
observer.observe(host, { childList: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
export function prepareAdminModal(modal) {
|
|
18
33
|
if (modal.dataset.prepared) return;
|
|
19
34
|
modal.dataset.prepared = 'true';
|
|
20
35
|
var previous = document.activeElement;
|
|
21
|
-
var
|
|
36
|
+
var inline = modal.classList.contains('settings-subview');
|
|
37
|
+
var restore = inline ? function () {} : isolateSettingsDialog(modal);
|
|
22
38
|
var dialog = modal.querySelector('.admin-modal');
|
|
23
|
-
dialog.setAttribute('role', 'dialog'); dialog.setAttribute('aria-modal', 'true');
|
|
39
|
+
dialog.setAttribute('role', inline ? 'region' : 'dialog'); if (!inline) dialog.setAttribute('aria-modal', 'true');
|
|
24
40
|
var title = dialog.querySelector('h3'); dialog.setAttribute('aria-label', title ? title.textContent : 'Confirm action');
|
|
25
41
|
var dirty = false;
|
|
26
42
|
modal.addEventListener('input', function () { dirty = true; });
|
|
@@ -37,7 +53,7 @@ export function prepareAdminModal(modal) {
|
|
|
37
53
|
modal.addEventListener('keydown', function (event) {
|
|
38
54
|
event.stopPropagation();
|
|
39
55
|
if (event.key === 'Escape') { event.preventDefault(); if (dirty) cancel(event); else modal.remove(); }
|
|
40
|
-
trapSettingsFocus(event, modal);
|
|
56
|
+
if (!inline) trapSettingsFocus(event, modal);
|
|
41
57
|
});
|
|
42
58
|
modal.querySelectorAll('.admin-smtp-row').forEach(function (row) {
|
|
43
59
|
var label = row.querySelector('label'); var input = row.querySelector('input, select');
|
|
@@ -49,7 +65,7 @@ export function prepareAdminModal(modal) {
|
|
|
49
65
|
var closeObserver = new MutationObserver(function () {
|
|
50
66
|
if (!modal.isConnected) { closeObserver.disconnect(); restore(); if (previous && previous.isConnected) previous.focus(); }
|
|
51
67
|
});
|
|
52
|
-
closeObserver.observe(document.body, { childList: true });
|
|
68
|
+
closeObserver.observe(inline ? modal.parentElement : document.body, { childList: true });
|
|
53
69
|
var focus = modal.querySelector('input:not([type=hidden]), .admin-modal-cancel, button');
|
|
54
70
|
if (focus) focus.focus();
|
|
55
71
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { store } from './store.js';
|
|
2
2
|
import { iconHtml, refreshIcons } from './icons.js';
|
|
3
3
|
import { showToast, copyToClipboard, escapeHtml } from './utils.js';
|
|
4
|
-
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal } from './admin-settings-ui.js';
|
|
4
|
+
import { apiGet, apiPost, apiPut, apiDelete, showConfirmDialog, showConfirmResetPin, prepareAdminModal, mountAdminSubview } from './admin-settings-ui.js';
|
|
5
5
|
// --- Users ---
|
|
6
6
|
export function loadUsersTab(body) {
|
|
7
7
|
apiGet("/api/admin/users").then(function (data) {
|
|
@@ -163,7 +163,7 @@ function showPermissionsModal(user, body) {
|
|
|
163
163
|
'</div></div>';
|
|
164
164
|
|
|
165
165
|
modal.innerHTML = html;
|
|
166
|
-
|
|
166
|
+
mountAdminSubview(modal);
|
|
167
167
|
prepareAdminModal(modal);
|
|
168
168
|
refreshIcons(modal);
|
|
169
169
|
|
|
@@ -222,7 +222,7 @@ function showAddUserModal(body) {
|
|
|
222
222
|
'<button class="admin-modal-cancel">Cancel</button>' +
|
|
223
223
|
'</div></div>';
|
|
224
224
|
modal.innerHTML = html;
|
|
225
|
-
|
|
225
|
+
mountAdminSubview(modal);
|
|
226
226
|
prepareAdminModal(modal);
|
|
227
227
|
refreshIcons(modal);
|
|
228
228
|
|
|
@@ -299,7 +299,7 @@ function showTempPinModal(user, tempPin) {
|
|
|
299
299
|
'<button class="admin-modal-cancel">Close</button>' +
|
|
300
300
|
'</div></div>';
|
|
301
301
|
modal.innerHTML = html;
|
|
302
|
-
|
|
302
|
+
mountAdminSubview(modal);
|
|
303
303
|
prepareAdminModal(modal);
|
|
304
304
|
refreshIcons(modal);
|
|
305
305
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { showProjectsHub, hideProjectsHub } from './projects-hub.js';
|
|
4
4
|
import { store } from './store.js';
|
|
5
5
|
import { getWs } from './ws-ref.js';
|
|
6
|
-
import { getCachedProjects,
|
|
6
|
+
import { getCachedProjects, switchProject } from './app-projects.js';
|
|
7
|
+
import { openAddProjectModal } from './project-start-dialog.js';
|
|
7
8
|
import { chooseProjectActivationTarget, homeProjectCreationState } from './project-activation.js';
|
|
8
9
|
import { mateAvatarUrl } from './avatar.js';
|
|
9
10
|
import { exitDmMode } from './app-dm.js';
|