domma-cms 0.75.0 → 0.77.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/CLAUDE.md +1 -1
- package/admin/js/api.js +1 -1
- package/admin/js/app.js +4 -4
- package/admin/js/lib/action-editor-arrange.js +1 -0
- package/admin/js/lib/api-endpoint-editor-arrange.js +2 -0
- package/admin/js/lib/api-tokens-arrange.js +3 -0
- package/admin/js/lib/block-editor-arrange.js +2 -0
- package/admin/js/lib/collection-editor-arrange.js +3 -0
- package/admin/js/lib/collection-entries-arrange.js +1 -0
- package/admin/js/lib/component-editor-arrange.js +27 -0
- package/admin/js/lib/context-menu-editor-arrange.js +1 -0
- package/admin/js/lib/dashboard-arrange.js +1 -0
- package/admin/js/lib/effects-arrange.js +3 -0
- package/admin/js/lib/form-editor-arrange.js +1 -0
- package/admin/js/lib/form-submissions-arrange.js +2 -0
- package/admin/js/lib/layouts-arrange.js +1 -0
- package/admin/js/lib/menu-editor-arrange.js +2 -0
- package/admin/js/lib/my-profile-arrange.js +1 -0
- package/admin/js/lib/notifications-arrange.js +1 -0
- package/admin/js/lib/page-editor-arrange.js +1 -0
- package/admin/js/lib/plugin-code-arrange.js +1 -0
- package/admin/js/lib/plugins-arrange.js +2 -0
- package/admin/js/lib/project-page-arrange.js +1 -0
- package/admin/js/lib/role-editor-arrange.js +3 -0
- package/admin/js/lib/roles-arrange.js +1 -0
- package/admin/js/lib/search-settings-arrange.js +1 -0
- package/admin/js/lib/sidebar-renderer.js +2 -2
- package/admin/js/lib/site-settings-arrange.js +1 -0
- package/admin/js/lib/user-editor-arrange.js +1 -0
- package/admin/js/lib/users-arrange.js +1 -0
- package/admin/js/lib/view-editor-arrange.js +14 -0
- package/admin/js/templates/action-editor.html +223 -147
- package/admin/js/templates/api-endpoint-editor.html +172 -117
- package/admin/js/templates/api-tokens.html +83 -10
- package/admin/js/templates/block-editor.html +194 -203
- package/admin/js/templates/collection-editor.html +191 -113
- package/admin/js/templates/collection-entries.html +99 -36
- package/admin/js/templates/component-editor.html +128 -126
- package/admin/js/templates/context-menu-editor.html +208 -148
- package/admin/js/templates/dashboard.html +184 -22
- package/admin/js/templates/effects.html +155 -72
- package/admin/js/templates/form-editor.html +41 -26
- package/admin/js/templates/form-submissions.html +78 -26
- package/admin/js/templates/layouts.html +126 -43
- package/admin/js/templates/menu-editor.html +57 -17
- package/admin/js/templates/menu-locations.html +54 -11
- package/admin/js/templates/my-profile.html +100 -12
- package/admin/js/templates/notifications.html +70 -10
- package/admin/js/templates/page-editor.html +47 -26
- package/admin/js/templates/plugin-code.html +91 -73
- package/admin/js/templates/plugins.html +100 -28
- package/admin/js/templates/project-detail.html +83 -145
- package/admin/js/templates/project-settings.html +88 -53
- package/admin/js/templates/role-editor.html +158 -83
- package/admin/js/templates/roles.html +78 -7
- package/admin/js/templates/search.html +193 -216
- package/admin/js/templates/settings.html +404 -472
- package/admin/js/templates/user-editor.html +150 -14
- package/admin/js/templates/users.html +69 -9
- package/admin/js/templates/view-editor.html +203 -180
- package/admin/js/templates/view-preview.html +45 -45
- package/admin/js/views/action-editor.js +7 -1
- package/admin/js/views/api-endpoint-editor.js +2 -3
- package/admin/js/views/api-tokens.js +62 -8
- package/admin/js/views/block-editor.js +14 -8
- package/admin/js/views/collection-editor.js +64 -5
- package/admin/js/views/collection-entries.js +50 -1
- package/admin/js/views/component-editor.js +2 -28
- package/admin/js/views/context-menu-editor.js +54 -55
- package/admin/js/views/dashboard.js +7 -1
- package/admin/js/views/effects.js +31 -1
- package/admin/js/views/form-editor.js +7 -7
- package/admin/js/views/form-submissions.js +11 -1
- package/admin/js/views/index.js +1 -1
- package/admin/js/views/layouts.js +81 -1
- package/admin/js/views/login.js +2 -2
- package/admin/js/views/menu-editor.js +21 -43
- package/admin/js/views/menu-locations.js +16 -1
- package/admin/js/views/my-profile.js +1 -1
- package/admin/js/views/notifications.js +18 -1
- package/admin/js/views/page-editor.js +26 -26
- package/admin/js/views/plugin-code.js +23 -4
- package/admin/js/views/plugins.js +97 -39
- package/admin/js/views/project-detail.js +9 -1
- package/admin/js/views/project-settings.js +1 -1
- package/admin/js/views/role-editor.js +11 -3
- package/admin/js/views/roles.js +49 -4
- package/admin/js/views/search.js +7 -1
- package/admin/js/views/settings.js +13 -3
- package/admin/js/views/user-editor.js +1 -1
- package/admin/js/views/users.js +13 -4
- package/admin/js/views/view-editor.js +1 -1
- package/admin/js/views/view-preview.js +1 -1
- package/package.json +1 -1
- package/plugins/_lib/admin/mail/compose-window.js +97 -40
- package/plugins/_lib/admin/mail/contacts.js +4 -1
- package/plugins/_lib/admin/mail/diagnostics-section.js +4 -1
- package/plugins/_lib/admin/mail/folder-tree.js +1 -1
- package/plugins/_lib/admin/mail/image-senders-section.js +69 -90
- package/plugins/_lib/admin/mail/mail.css +1 -1
- package/plugins/_lib/admin/mail/mail.html +1 -1
- package/plugins/_lib/admin/mail/reader-view.js +303 -44
- package/plugins/_lib/admin/mail/when-closed.js +26 -0
- package/plugins/_lib/mail/readRoutes.js +43 -1
- package/plugins/_lib/mail/unreadBadge.js +42 -0
- package/plugins/free-tier.lock.json +5 -5
- package/plugins/mail-reader/CLAUDE.md +1 -0
- package/plugins/mail-reader/plugin.js +3 -1
- package/plugins/mail-reader/plugin.json +5 -4
- package/server/routes/api/api-tokens.js +56 -0
- package/server/routes/api/auth.js +7 -1
- package/server/routes/api/collections.js +13 -1
- package/server/routes/api/dashboard.js +32 -4
- package/server/routes/api/effects.js +68 -13
- package/server/routes/api/forms.js +104 -13
- package/server/routes/api/layouts.js +93 -2
- package/server/routes/api/notifications.js +140 -14
- package/server/routes/api/plugins.js +135 -4
- package/server/routes/api/roles.js +111 -0
- package/server/routes/api/search.js +38 -4
- package/server/routes/api/settings.js +52 -0
- package/server/routes/api/users.js +65 -3
- package/server/routes/api/views.js +55 -1
- package/server/server.js +12 -0
- package/server/services/components.js +9 -0
- package/server/services/plugins.js +7 -0
- package/server/services/roles.js +3 -0
- package/server/services/search.js +58 -0
- package/server/services/users.js +16 -2
- package/server/services/views.js +14 -0
- package/admin/js/templates/dashboard/activity-feed.html +0 -3
- package/admin/js/templates/dashboard/cache.html +0 -32
- package/admin/js/templates/dashboard/health-detail.html +0 -2
- package/admin/js/templates/dashboard/journeys.html +0 -17
- package/admin/js/templates/dashboard/kpi-strip.html +0 -34
- package/admin/js/templates/dashboard/spike-feed.html +0 -3
- package/admin/js/templates/dashboard/top-pages.html +0 -3
- package/admin/js/templates/dashboard/traffic-chart.html +0 -3
- package/admin/js/templates/plugin-marketplace.html +0 -29
- package/admin/js/views/block-editor-enhance.js +0 -1
- package/admin/js/views/dashboard/lib/escape.js +0 -1
- package/admin/js/views/dashboard/widgets/activity-feed.js +0 -1
- package/admin/js/views/dashboard/widgets/cache.js +0 -1
- package/admin/js/views/dashboard/widgets/health-detail.js +0 -1
- package/admin/js/views/dashboard/widgets/journeys.js +0 -1
- package/admin/js/views/dashboard/widgets/kpi-strip.js +0 -1
- package/admin/js/views/dashboard/widgets/spike-feed.js +0 -6
- package/admin/js/views/dashboard/widgets/top-pages.js +0 -1
- package/admin/js/views/dashboard/widgets/traffic-chart.js +0 -1
- package/admin/js/views/plugin-marketplace.js +0 -1
|
@@ -1,82 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
padding: .3rem .5rem .3rem 1rem; border: 0; background: none; cursor: pointer;
|
|
13
|
-
border-radius: var(--dm-radius-md, 6px); text-align: left;
|
|
14
|
-
color: var(--dm-text, inherit); font-size: .82rem;
|
|
15
|
-
font-family: var(--dm-font-mono, ui-monospace, Menlo, Consolas, monospace);
|
|
16
|
-
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
17
|
-
}
|
|
18
|
-
.pcode-file:hover { background: var(--dm-hover-bg, rgba(128,128,128,.12)); }
|
|
19
|
-
.pcode-file.active { background: var(--dm-primary, #2563eb); color: #fff; }
|
|
20
|
-
.pcode-file .pcode-dirty { margin-left: auto; font-weight: 700; }
|
|
21
|
-
.pcode-editor-card { flex: 1; display: flex; flex-direction: column; min-width: 0; }
|
|
22
|
-
.pcode-editor-card .card-body { flex: 1; display: flex; flex-direction: column; padding: 0; }
|
|
23
|
-
.pcode-toolbar {
|
|
24
|
-
display: flex; align-items: center; gap: .5rem;
|
|
25
|
-
padding: .5rem .75rem; border-bottom: 1px solid var(--dm-border, rgba(128,128,128,.25));
|
|
26
|
-
}
|
|
27
|
-
.pcode-current {
|
|
28
|
-
font-family: var(--dm-font-mono, ui-monospace, Menlo, Consolas, monospace);
|
|
29
|
-
font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
30
|
-
}
|
|
31
|
-
#pcode-editor { flex: 1; display: flex; min-height: 55vh; }
|
|
32
|
-
#pcode-editor > .dm-edit-wrap { flex: 1; }
|
|
33
|
-
.pcode-statusbar {
|
|
34
|
-
display: flex; align-items: center; gap: .75rem; padding: .4rem .75rem;
|
|
35
|
-
border-top: 1px solid var(--dm-border, rgba(128,128,128,.25));
|
|
36
|
-
font-size: .78rem; color: var(--dm-text-muted, #6b7280);
|
|
37
|
-
}
|
|
38
|
-
#pcode-cursor { margin-left: auto; font-family: var(--dm-font-mono, ui-monospace, Menlo, Consolas, monospace); }
|
|
39
|
-
</style>
|
|
40
|
-
|
|
41
|
-
<div class="view-header d-flex justify-content-between align-items-center mb-4">
|
|
42
|
-
<div>
|
|
43
|
-
<h1 class="view-title"><span data-icon="code"></span> <span id="pcode-title">Plugin Code</span></h1>
|
|
44
|
-
<p class="view-subtitle text-muted" style="margin:0;font-size:.875rem">
|
|
45
|
-
<code>admin/</code> files apply on a hard refresh; everything else needs a server restart.
|
|
46
|
-
</p>
|
|
47
|
-
</div>
|
|
48
|
-
<div class="d-flex gap-2">
|
|
49
|
-
<button id="pcode-back" class="btn btn-ghost"><span data-icon="arrow-left"></span> Plugins</button>
|
|
50
|
-
<button id="pcode-restart" class="btn btn-warning"><span data-icon="refresh-cw"></span> Restart Server</button>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
1
|
+
<!-- Plugin code editor. Bound with M.applyBindings - see admin/js/views/plugin-code.js, which also inserts
|
|
2
|
+
the file-row template (the router renders a templateUrl through _.render, eating any {{…}}).
|
|
3
|
+
No page heading: the Tool banner ("Marketplace › <plugin>") is the heading; Back, New file, Save all
|
|
4
|
+
and Restart server are banner actions. -->
|
|
5
|
+
<div class="pcx">
|
|
6
|
+
<p class="pcx-alert is-bad" data-bind-hidden="!loadError.value" data-bind-text="loadError.value"></p>
|
|
7
|
+
<p class="pcx-alert" data-bind-hidden="!restartPending.value">
|
|
8
|
+
<span data-icon="alert-triangle" data-icon-size="16"></span>
|
|
9
|
+
<span>Server files were saved - they apply when the server restarts.</span>
|
|
10
|
+
<button type="button" class="btn btn-sm btn-warning" data-on-click="restart">Restart server</button>
|
|
11
|
+
</p>
|
|
53
12
|
|
|
54
|
-
<div class="
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<
|
|
59
|
-
<
|
|
13
|
+
<div class="pcx-layout">
|
|
14
|
+
<div class="pcx-card pcx-files">
|
|
15
|
+
<div class="pcx-card-title">Files
|
|
16
|
+
<span class="pcx-count" data-bind-text="files.value.length"></span>
|
|
17
|
+
<span data-help-title="Files" data-help="Every editable file in the plugin (.js, .json, .md, .html, .css, .txt, .svg). Click one to open it - unsaved edits are kept per file while you switch, and a ● marks them. Right-click a file (or ⋮, or Shift+F10) to save, revert, copy its path, rename, duplicate or delete it. plugin.json, plugin.js and config.js cannot be deleted or renamed."></span>
|
|
18
|
+
<span class="pcx-spacer"></span>
|
|
19
|
+
<button type="button" class="btn btn-sm btn-ghost" data-on-click="newFile" title="New file" aria-label="New file"><span data-icon="plus" data-icon-size="14"></span></button>
|
|
60
20
|
</div>
|
|
61
|
-
<
|
|
21
|
+
<input type="search" class="form-input pcx-search" placeholder="Filter files…" aria-label="Filter files" data-model="query.value">
|
|
22
|
+
<p class="pcx-note" data-bind-hidden="!loading.value">Loading…</p>
|
|
23
|
+
<p class="pcx-note" data-bind-hidden="loading.value || rows.value.length" data-bind-text="emptyText.value"></p>
|
|
24
|
+
<div class="pcx-list" data-each="rows.value key=key"></div>
|
|
62
25
|
</div>
|
|
63
|
-
</div>
|
|
64
26
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<span class="
|
|
69
|
-
<span
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
<button
|
|
73
|
-
<button
|
|
27
|
+
<div class="pcx-card pcx-editor-card">
|
|
28
|
+
<div class="pcx-toolbar">
|
|
29
|
+
<span class="pcx-current" data-bind-text="currentText.value">Select a file</span>
|
|
30
|
+
<span class="pcx-chip" data-bind-hidden="!openPath.value" data-bind-class="scopeCls.value" data-bind-text="scopeLabel.value" data-bind-title="scopeHint.value"></span>
|
|
31
|
+
<span class="pcx-chip is-warn" data-bind-hidden="!currentDirty.value">Unsaved</span>
|
|
32
|
+
<span data-help-title="Saving" data-help="Ctrl+S saves the open file, Ctrl+Shift+S every unsaved file. An admin/ file applies when the admin tab is refreshed; anything else (plugin.js, config.js, public snippets…) is read when the server starts, so it needs a restart - Restart server is in the banner. Leaving with unsaved files asks first and keeps them as a draft for your next visit."></span>
|
|
33
|
+
<span class="pcx-spacer"></span>
|
|
34
|
+
<button type="button" class="btn btn-sm btn-ghost" data-on-click="revert" data-bind-hidden="!currentDirty.value" title="Put the open file back as it was saved">Revert</button>
|
|
35
|
+
<button type="button" class="btn btn-sm btn-primary" data-on-click="save" data-bind-disabled="!currentDirty.value || saving.value">
|
|
36
|
+
<span data-icon="save" data-icon-size="14"></span> Save</button>
|
|
37
|
+
<button type="button" class="pcx-kebab pcx-more" data-bind-hidden="!openPath.value" aria-label="More for this file" title="More">⋮</button>
|
|
74
38
|
</div>
|
|
75
|
-
<div id="pcode-editor"></div>
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
<span
|
|
39
|
+
<div class="pcx-editor" id="pcode-editor"></div>
|
|
40
|
+
<p class="pcx-empty" data-bind-hidden="openPath.value">Choose a file on the left to edit it.</p>
|
|
41
|
+
<div class="pcx-statusbar">
|
|
42
|
+
<span data-bind-text="status.value"></span>
|
|
43
|
+
<span class="pcx-spacer"></span>
|
|
44
|
+
<span data-bind-hidden="!dirtyCount.value" data-bind-text="dirtyText.value"></span>
|
|
45
|
+
<span class="pcx-cursor" data-bind-text="cursor.value"></span>
|
|
79
46
|
</div>
|
|
80
47
|
</div>
|
|
81
48
|
</div>
|
|
82
49
|
</div>
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
.pcx { display: flex; flex-direction: column; gap: .75rem; }
|
|
53
|
+
.pcx [hidden], .pcx-form [hidden] { display: none !important; }
|
|
54
|
+
.pcx-alert { margin: 0; display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; padding: .55rem .8rem; border-radius: var(--dm-radius-md);
|
|
55
|
+
background: color-mix(in srgb, var(--dm-warning) 16%, transparent); color: var(--dm-text); }
|
|
56
|
+
.pcx-alert.is-bad { background: color-mix(in srgb, var(--dm-danger) 14%, transparent); color: var(--dm-danger); }
|
|
57
|
+
.pcx-layout { display: flex; gap: .75rem; align-items: stretch; min-height: 70vh; }
|
|
58
|
+
.pcx-card { border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); display: flex; flex-direction: column; min-width: 0; }
|
|
59
|
+
.pcx-files { flex: 0 0 270px; padding: .6rem; gap: .5rem; overflow-y: auto; max-height: 80vh; }
|
|
60
|
+
.pcx-card-title { display: flex; align-items: center; gap: .3rem; font-weight: 600; }
|
|
61
|
+
.pcx-count { opacity: .6; font-size: var(--dm-text-xs); font-weight: 400; }
|
|
62
|
+
.pcx-spacer { flex: 1; }
|
|
63
|
+
.pcx-search { width: 100%; }
|
|
64
|
+
.pcx-note { margin: 0; color: var(--dm-text-muted); font-size: var(--dm-text-sm); }
|
|
65
|
+
.pcx-list { display: flex; flex-direction: column; }
|
|
66
|
+
.pcx-dir { padding: .5rem .35rem .15rem; font-size: var(--dm-text-xs); font-weight: 700; letter-spacing: .03em; color: var(--dm-text-muted);
|
|
67
|
+
font-family: var(--dm-font-mono, monospace); }
|
|
68
|
+
.pcx-file { display: flex; align-items: center; gap: .35rem; padding: .28rem .35rem; border-radius: var(--dm-radius-sm); cursor: pointer;
|
|
69
|
+
color: var(--dm-text); font-size: var(--dm-text-sm); font-family: var(--dm-font-mono, monospace); min-width: 0; }
|
|
70
|
+
.pcx-file.is-nested { padding-left: 1rem; }
|
|
71
|
+
.pcx-file:hover, .pcx-file:focus-visible { background: var(--dm-table-hover-bg, color-mix(in srgb, var(--dm-text) 6%, transparent)); outline: none; }
|
|
72
|
+
.pcx-file.is-open { background: color-mix(in srgb, var(--dm-primary) 16%, transparent); box-shadow: inset 3px 0 0 var(--dm-primary); }
|
|
73
|
+
.pcx-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
74
|
+
.pcx-dirty { color: var(--dm-warning); font-weight: 700; }
|
|
75
|
+
.pcx-kebab { border: 0; background: none; cursor: pointer; font-size: var(--dm-text-lg); line-height: 1; color: var(--dm-text-muted);
|
|
76
|
+
border-radius: var(--dm-radius-sm); padding: 0 .3rem; }
|
|
77
|
+
.pcx-kebab:hover { color: var(--dm-primary); }
|
|
78
|
+
.pcx-editor-card { flex: 1; }
|
|
79
|
+
.pcx-toolbar { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; padding: .5rem .75rem; border-bottom: 1px solid var(--dm-border); }
|
|
80
|
+
.pcx-toolbar .btn { display: inline-flex; align-items: center; gap: .3rem; }
|
|
81
|
+
.pcx-current { font-family: var(--dm-font-mono, monospace); font-size: var(--dm-text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
|
82
|
+
.pcx-chip { display: inline-flex; align-items: center; font-size: var(--dm-text-xs); font-weight: 600; padding: .1rem .5rem; border-radius: 999px; white-space: nowrap;
|
|
83
|
+
background: color-mix(in srgb, var(--dm-text) 10%, transparent); color: var(--dm-text-muted); }
|
|
84
|
+
.pcx-chip.is-info { background: color-mix(in srgb, var(--dm-info, var(--dm-primary)) 14%, transparent); color: var(--dm-info, var(--dm-primary)); }
|
|
85
|
+
.pcx-chip.is-warn { background: color-mix(in srgb, var(--dm-warning) 18%, transparent); color: var(--dm-warning); }
|
|
86
|
+
.pcx-editor { flex: 1; display: flex; min-height: 55vh; }
|
|
87
|
+
.pcx-editor > .dm-edit-wrap { flex: 1; }
|
|
88
|
+
.pcx-empty { margin: 0; padding: 2rem; color: var(--dm-text-muted); text-align: center; }
|
|
89
|
+
.pcx-statusbar { display: flex; align-items: center; gap: .75rem; padding: .4rem .75rem; border-top: 1px solid var(--dm-border);
|
|
90
|
+
font-size: var(--dm-text-xs); color: var(--dm-text-muted); }
|
|
91
|
+
.pcx-cursor { font-family: var(--dm-font-mono, monospace); }
|
|
92
|
+
/* The path slideover */
|
|
93
|
+
.pcx-form { display: flex; flex-direction: column; gap: .85rem; }
|
|
94
|
+
.pcx-form .form-label { display: flex; align-items: center; gap: .3rem; }
|
|
95
|
+
.pcx-err { display: block; color: var(--dm-danger); font-size: var(--dm-text-xs); margin-top: .25rem; }
|
|
96
|
+
.pcx-hint { display: block; color: var(--dm-text-muted); font-size: var(--dm-text-xs); margin-top: .25rem; }
|
|
97
|
+
.pcx-actions { display: flex; align-items: center; gap: .4rem; padding-top: .6rem; border-top: 1px solid var(--dm-border); }
|
|
98
|
+
.pcx-actions .btn { display: inline-flex; align-items: center; gap: .3rem; }
|
|
99
|
+
@media (max-width: 800px) { .pcx-layout { flex-direction: column; } .pcx-files { flex-basis: auto; max-height: 40vh; } }
|
|
100
|
+
</style>
|
|
@@ -1,35 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<span data-icon="upload"></span> Install from File
|
|
9
|
-
</button>
|
|
10
|
-
<button id="new-plugin-btn" class="btn btn-primary">
|
|
11
|
-
<span data-icon="plus"></span> New Plugin
|
|
12
|
-
</button>
|
|
13
|
-
</div>
|
|
14
|
-
<input type="file" id="install-file-input" accept=".dcmsplugin" hidden>
|
|
15
|
-
</div>
|
|
1
|
+
<!-- The Marketplace (System › Plugins). Bound with M.applyBindings - see admin/js/views/plugins.js, which
|
|
2
|
+
also inserts the row templates (the router renders a templateUrl through _.render, eating any {{…}}).
|
|
3
|
+
No page heading: the Tool banner is the heading; New plugin and Install from file are banner actions. -->
|
|
4
|
+
<div class="plx">
|
|
5
|
+
<p class="plx-note">Install plugins to add features. Once switched on, a plugin is a Tool and appears in the sidebar.
|
|
6
|
+
<span data-help-title="The Marketplace" data-help="Installed lists what is on this site; Browse lists what this site can get from its manager (a site that is not managed installs from a .dcmsplugin file instead - Install from file in the banner). Switching a plugin on or off restarts the server, because a plugin's routes and screens are only read at start-up. Licensed plugins carry their licence with them: one that is switched on but not licensed does not run, and says so here."></span></p>
|
|
7
|
+
<input type="file" class="plx-file" accept=".dcmsplugin" hidden>
|
|
16
8
|
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
</div>
|
|
9
|
+
<p class="plx-alert" data-bind-hidden="!restarting.value">
|
|
10
|
+
<span class="plx-spinner" aria-hidden="true"></span>
|
|
11
|
+
<span data-bind-text="restarting.value"></span>
|
|
12
|
+
</p>
|
|
22
13
|
|
|
23
|
-
<div class="
|
|
24
|
-
<div
|
|
25
|
-
<
|
|
26
|
-
|
|
14
|
+
<div class="tabs plx-tabs">
|
|
15
|
+
<div class="tab-list">
|
|
16
|
+
<button type="button" class="tab-item active">Installed <span class="plx-count" data-bind-text="plugins.value.length"></span></button>
|
|
17
|
+
<button type="button" class="tab-item">Browse <span class="plx-count" data-bind-hidden="!updateCount.value" data-bind-text="updateCountText.value"></span></button>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- Installed -->
|
|
21
|
+
<div class="tab-panel active">
|
|
22
|
+
<div class="plx-card">
|
|
23
|
+
<div class="plx-bar">
|
|
24
|
+
<div class="plx-seg" role="group" aria-label="Show">
|
|
25
|
+
<button type="button" data-on-click="showAll" data-bind-class="filter.value === 'all' && 'is-on'">All <b data-bind-text="counts.value.all"></b></button>
|
|
26
|
+
<button type="button" data-on-click="showOn" data-bind-class="filter.value === 'on' && 'is-on'">On <b data-bind-text="counts.value.on"></b></button>
|
|
27
|
+
<button type="button" data-on-click="showOff" data-bind-class="filter.value === 'off' && 'is-on'">Off <b data-bind-text="counts.value.off"></b></button>
|
|
28
|
+
<button type="button" data-on-click="showAttention" data-bind-class="filter.value === 'attention' && 'is-on'" data-bind-hidden="!counts.value.attention">Needs attention <b data-bind-text="counts.value.attention"></b></button>
|
|
29
|
+
</div>
|
|
30
|
+
<input type="search" class="form-input plx-search" placeholder="Search plugins…" aria-label="Search plugins" data-model="query.value">
|
|
31
|
+
<span data-help-title="Installed plugins" data-help="Click a plugin for its details and settings. Right-click it (or ⋮, or Shift+F10) to switch it on or off, configure it, update it, view its source, export it as a .dcmsplugin file or uninstall it. Built-in plugins are part of the CMS and always on. Licensed plugins cannot be viewed or exported here."></span>
|
|
32
|
+
</div>
|
|
33
|
+
<p class="plx-note" data-bind-hidden="!loading.value">Loading…</p>
|
|
34
|
+
<p class="plx-note is-bad" data-bind-hidden="!loadError.value" data-bind-text="loadError.value"></p>
|
|
35
|
+
<p class="plx-note" data-bind-hidden="loading.value || loadError.value || rows.value.length" data-bind-text="emptyText.value"></p>
|
|
36
|
+
<div class="plx-list plx-installed" data-each="rows.value key=name"></div>
|
|
27
37
|
</div>
|
|
28
38
|
</div>
|
|
29
|
-
<div id="plugins-grid" class="plugins-grid"></div>
|
|
30
|
-
</div>
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
<div
|
|
40
|
+
<!-- Browse -->
|
|
41
|
+
<div class="tab-panel">
|
|
42
|
+
<div class="plx-browse"></div>
|
|
43
|
+
</div>
|
|
34
44
|
</div>
|
|
35
45
|
</div>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
.plx { display: flex; flex-direction: column; gap: .75rem; }
|
|
49
|
+
.plx [hidden], .plx-form [hidden] { display: none !important; }
|
|
50
|
+
.plx-note { margin: 0; color: var(--dm-text-muted); font-size: var(--dm-text-sm); }
|
|
51
|
+
.plx-note.is-bad { color: var(--dm-danger); }
|
|
52
|
+
.plx-alert { margin: 0; display: flex; gap: .5rem; align-items: center; padding: .6rem .8rem; border-radius: var(--dm-radius-md);
|
|
53
|
+
background: color-mix(in srgb, var(--dm-primary) 14%, transparent); color: var(--dm-text); }
|
|
54
|
+
.plx-spinner { width: 14px; height: 14px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--dm-primary) 30%, transparent);
|
|
55
|
+
border-top-color: var(--dm-primary); animation: plx-spin .8s linear infinite; flex-shrink: 0; }
|
|
56
|
+
@keyframes plx-spin { to { transform: rotate(360deg); } }
|
|
57
|
+
.plx-count { opacity: .65; font-size: var(--dm-text-xs); margin-left: .2rem; }
|
|
58
|
+
.plx-card { border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); padding: .75rem .9rem; display: flex; flex-direction: column; gap: .6rem; margin-top: .75rem; }
|
|
59
|
+
.plx-bar { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
|
|
60
|
+
.plx-search { flex: 1; min-width: 10rem; max-width: 22rem; }
|
|
61
|
+
.plx-seg { display: inline-flex; border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); overflow: hidden; }
|
|
62
|
+
.plx-seg button { border: 0; background: none; color: var(--dm-text); padding: .3rem .7rem; cursor: pointer; font: inherit; font-size: var(--dm-text-sm); }
|
|
63
|
+
.plx-seg button + button { border-left: 1px solid var(--dm-border); }
|
|
64
|
+
.plx-seg button b { font-weight: 500; opacity: .65; margin-left: .2rem; }
|
|
65
|
+
.plx-seg button:hover { background: var(--dm-table-hover-bg, color-mix(in srgb, var(--dm-text) 6%, transparent)); }
|
|
66
|
+
.plx-seg button.is-on { background: var(--dm-primary); color: var(--dm-primary-text); }
|
|
67
|
+
.plx-list { display: flex; flex-direction: column; }
|
|
68
|
+
.plx-row { display: flex; align-items: center; gap: .75rem; padding: .55rem .35rem; border-bottom: 1px solid var(--dm-border); cursor: pointer; }
|
|
69
|
+
.plx-row:last-child { border-bottom: 0; }
|
|
70
|
+
.plx-row:hover, .plx-row:focus-visible { background: var(--dm-table-hover-bg, color-mix(in srgb, var(--dm-text) 6%, transparent)); outline: none; }
|
|
71
|
+
.plx-row.is-attention { box-shadow: inset 3px 0 0 var(--dm-warning); }
|
|
72
|
+
.plx-icon { display: inline-flex; align-items: center; justify-content: center; width: 2.1rem; height: 2.1rem; flex-shrink: 0;
|
|
73
|
+
border-radius: var(--dm-radius-md); color: var(--plugin-accent, var(--dm-primary));
|
|
74
|
+
background: color-mix(in srgb, var(--plugin-accent, var(--dm-primary)) 14%, transparent); }
|
|
75
|
+
.plx-row.is-off .plx-icon { color: var(--dm-text-muted); background: color-mix(in srgb, var(--dm-text-muted) 12%, transparent); }
|
|
76
|
+
.plx-row.is-off .plx-main strong { color: var(--dm-text-muted); }
|
|
77
|
+
.plx-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
78
|
+
.plx-main strong, .plx-main small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
79
|
+
.plx-main small { color: var(--dm-text-muted); font-size: var(--dm-text-xs); }
|
|
80
|
+
.plx-chips { display: inline-flex; gap: .3rem; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
|
|
81
|
+
.plx-chip { display: inline-flex; align-items: center; font-size: var(--dm-text-xs); font-weight: 600; padding: .1rem .5rem; border-radius: 999px; white-space: nowrap;
|
|
82
|
+
background: color-mix(in srgb, var(--dm-text) 10%, transparent); color: var(--dm-text-muted); }
|
|
83
|
+
.plx-chip.is-ok { background: color-mix(in srgb, var(--dm-success) 16%, transparent); color: var(--dm-success); }
|
|
84
|
+
.plx-chip.is-info { background: color-mix(in srgb, var(--dm-info, var(--dm-primary)) 16%, transparent); color: var(--dm-info, var(--dm-primary)); }
|
|
85
|
+
.plx-chip.is-warn { background: color-mix(in srgb, var(--dm-warning) 18%, transparent); color: var(--dm-warning); }
|
|
86
|
+
.plx-chip.is-danger { background: color-mix(in srgb, var(--dm-danger) 16%, transparent); color: var(--dm-danger); }
|
|
87
|
+
.plx-kebab { border: 0; background: none; cursor: pointer; font-size: var(--dm-text-lg); color: var(--dm-text-muted); border-radius: var(--dm-radius-sm); padding: 0 .3rem; }
|
|
88
|
+
.plx-kebab:hover { color: var(--dm-primary); }
|
|
89
|
+
.plx-act { flex-shrink: 0; }
|
|
90
|
+
/* Slideovers */
|
|
91
|
+
.plx-form { display: flex; flex-direction: column; gap: .85rem; }
|
|
92
|
+
.plx-form .form-label { display: flex; align-items: center; gap: .3rem; }
|
|
93
|
+
.plx-facts { display: grid; grid-template-columns: max-content 1fr; gap: .3rem .9rem; margin: 0; font-size: var(--dm-text-sm); }
|
|
94
|
+
.plx-facts dt { color: var(--dm-text-muted); }
|
|
95
|
+
.plx-facts dd { margin: 0; }
|
|
96
|
+
.plx-desc { margin: 0; }
|
|
97
|
+
.plx-sub { margin: .25rem 0 0; font-size: var(--dm-text-sm); font-weight: 600; }
|
|
98
|
+
.plx-err { display: block; color: var(--dm-danger); font-size: var(--dm-text-xs); margin-top: .25rem; }
|
|
99
|
+
.plx-hint { display: block; color: var(--dm-text-muted); font-size: var(--dm-text-xs); margin-top: .25rem; }
|
|
100
|
+
.plx-setting { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
|
|
101
|
+
.plx-setting .form-label { margin: 0; }
|
|
102
|
+
.plx-json { font-family: var(--dm-font-mono, monospace); font-size: var(--dm-text-sm); }
|
|
103
|
+
.plx-actions { display: flex; align-items: center; gap: .4rem; padding-top: .6rem; border-top: 1px solid var(--dm-border); flex-wrap: wrap; }
|
|
104
|
+
.plx-actions .btn { display: inline-flex; align-items: center; gap: .3rem; }
|
|
105
|
+
.plx-spacer { flex: 1; }
|
|
106
|
+
@media (max-width: 640px) { .plx-main small { white-space: normal; } .plx-chips { display: none; } }
|
|
107
|
+
</style>
|
|
@@ -1,152 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var(--dm-card-bg, rgba(255,255,255,.04));
|
|
15
|
-
position: relative;
|
|
16
|
-
overflow: hidden;
|
|
17
|
-
}
|
|
18
|
-
.pd-hero::before {
|
|
19
|
-
content: '';
|
|
20
|
-
position: absolute;
|
|
21
|
-
top: 0; bottom: 0; left: 0;
|
|
22
|
-
width: 4px;
|
|
23
|
-
background: linear-gradient(180deg, var(--dm-primary), var(--dm-primary-dark));
|
|
24
|
-
}
|
|
25
|
-
.pd-hero-icon {
|
|
26
|
-
width: 64px; height: 64px;
|
|
27
|
-
flex-shrink: 0;
|
|
28
|
-
border-radius: 16px;
|
|
29
|
-
display: flex; align-items: center; justify-content: center;
|
|
30
|
-
background: linear-gradient(135deg, color-mix(in srgb, var(--dm-primary) 28%, transparent), color-mix(in srgb, var(--dm-primary-dark) 28%, transparent));
|
|
31
|
-
color: var(--dm-primary);
|
|
32
|
-
box-shadow: 0 6px 18px color-mix(in srgb, var(--dm-primary) 18%, transparent);
|
|
33
|
-
}
|
|
34
|
-
.pd-hero-icon svg, .pd-hero-icon span[data-icon] { width: 32px; height: 32px; }
|
|
35
|
-
.pd-hero-main { flex: 1; min-width: 0; }
|
|
36
|
-
.pd-hero-top {
|
|
37
|
-
display: flex; align-items: flex-start; justify-content: space-between;
|
|
38
|
-
gap: 1rem; flex-wrap: wrap;
|
|
39
|
-
}
|
|
40
|
-
.pd-title { font-size: 1.6rem; font-weight: 700; margin: 0; line-height: 1.15; }
|
|
41
|
-
.pd-actions { display: flex; gap: .5rem; flex-shrink: 0; }
|
|
42
|
-
.pd-desc { color: var(--dm-text-muted, #888); margin: .5rem 0 0; max-width: 64ch; }
|
|
43
|
-
.pd-desc:empty { display: none; }
|
|
44
|
-
|
|
45
|
-
/* ── Meta badges ──────────────────────────────────────────────────── */
|
|
46
|
-
.pd-meta { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.1rem; }
|
|
47
|
-
.pd-meta-badge {
|
|
48
|
-
display: inline-flex; align-items: center; gap: .45rem;
|
|
49
|
-
padding: .4rem .7rem;
|
|
50
|
-
border-radius: 999px;
|
|
51
|
-
font-size: .8rem; line-height: 1;
|
|
52
|
-
border: 1px solid transparent;
|
|
53
|
-
}
|
|
54
|
-
.pd-meta-badge svg, .pd-meta-badge span[data-icon] { width: 14px; height: 14px; }
|
|
55
|
-
.pd-meta-k { color: var(--dm-text-muted, #999); font-weight: 500; }
|
|
56
|
-
.pd-meta-v { font-weight: 600; }
|
|
57
|
-
|
|
58
|
-
/* ── Section header ───────────────────────────────────────────────── */
|
|
59
|
-
.pd-section-head {
|
|
60
|
-
display: flex; align-items: baseline; gap: .6rem;
|
|
61
|
-
margin: 0 0 .35rem;
|
|
62
|
-
}
|
|
63
|
-
.pd-section-title {
|
|
64
|
-
font-size: 1rem; font-weight: 600; margin: 0;
|
|
65
|
-
display: flex; align-items: center; gap: .5rem;
|
|
66
|
-
}
|
|
67
|
-
.pd-section-title svg, .pd-section-title span[data-icon] {
|
|
68
|
-
width: 17px; height: 17px; color: var(--dm-text-muted, #888);
|
|
69
|
-
}
|
|
70
|
-
.pd-total { font-size: .8rem; color: var(--dm-text-muted, #888); }
|
|
71
|
-
.pd-hint { color: var(--dm-text-muted, #888); margin: 0 0 .9rem; font-size: .82rem; }
|
|
72
|
-
|
|
73
|
-
/* ── Artefact stat tiles (each with a + to create one) ────────────── */
|
|
74
|
-
.pd-tiles {
|
|
75
|
-
display: grid;
|
|
76
|
-
grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
|
|
77
|
-
gap: .85rem;
|
|
78
|
-
}
|
|
79
|
-
.pd-tile {
|
|
80
|
-
position: relative;
|
|
81
|
-
border: 1px solid var(--dm-border, rgba(255,255,255,.08));
|
|
82
|
-
border-left: 3px solid var(--c, #5b8cff);
|
|
83
|
-
border-radius: 11px;
|
|
84
|
-
background: var(--dm-card-bg, rgba(255,255,255,.04));
|
|
85
|
-
transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
|
|
86
|
-
}
|
|
87
|
-
.pd-tile--link:hover {
|
|
88
|
-
transform: translateY(-2px);
|
|
89
|
-
box-shadow: var(--dm-shadow-lg);
|
|
90
|
-
border-color: var(--c, #5b8cff);
|
|
91
|
-
}
|
|
92
|
-
.pd-tile-link {
|
|
93
|
-
display: flex; align-items: center; gap: .85rem;
|
|
94
|
-
padding: .9rem 1rem; padding-right: 2.6rem; /* room for the + */
|
|
95
|
-
text-decoration: none; color: inherit;
|
|
96
|
-
}
|
|
97
|
-
.pd-tile-link--empty { opacity: .55; }
|
|
98
|
-
.pd-tile-chip {
|
|
99
|
-
width: 40px; height: 40px; flex-shrink: 0;
|
|
100
|
-
border-radius: 10px;
|
|
101
|
-
display: flex; align-items: center; justify-content: center;
|
|
102
|
-
}
|
|
103
|
-
.pd-tile-chip svg, .pd-tile-chip span[data-icon] { width: 20px; height: 20px; }
|
|
104
|
-
.pd-tile-body { display: flex; flex-direction: column; min-width: 0; }
|
|
105
|
-
.pd-tile-count { font-size: 1.5rem; font-weight: 700; line-height: 1; }
|
|
106
|
-
.pd-tile-label {
|
|
107
|
-
font-size: .78rem; color: var(--dm-text-muted, #888);
|
|
108
|
-
margin-top: .2rem; text-transform: uppercase; letter-spacing: .03em;
|
|
109
|
-
}
|
|
110
|
-
.pd-tile-add {
|
|
111
|
-
position: absolute; top: 8px; right: 8px;
|
|
112
|
-
width: 26px; height: 26px; border-radius: 7px;
|
|
113
|
-
display: flex; align-items: center; justify-content: center;
|
|
114
|
-
border: 1px solid var(--dm-border, rgba(255,255,255,.12));
|
|
115
|
-
background: var(--dm-card-bg, rgba(255,255,255,.05));
|
|
116
|
-
color: var(--c, #5b8cff);
|
|
117
|
-
cursor: pointer; opacity: .7;
|
|
118
|
-
transition: opacity .14s ease, background .14s ease, border-color .14s ease, transform .14s ease;
|
|
119
|
-
}
|
|
120
|
-
.pd-tile-add:hover {
|
|
121
|
-
opacity: 1; transform: scale(1.08);
|
|
122
|
-
border-color: var(--c, #5b8cff);
|
|
123
|
-
background: var(--dm-hover-bg);
|
|
124
|
-
}
|
|
125
|
-
.pd-tile-add svg, .pd-tile-add span[data-icon] { width: 15px; height: 15px; }
|
|
126
|
-
</style>
|
|
1
|
+
<!-- A project's overview. Bound with M.applyBindings - see admin/js/views/project-detail.js, which also
|
|
2
|
+
inserts the tile template (the router renders a templateUrl through _.render, eating any {{…}}).
|
|
3
|
+
No page heading: the Tool banner is the heading ("Projects › <name>"), with Settings in it. -->
|
|
4
|
+
<div class="pdx">
|
|
5
|
+
<p class="pdx-alert" data-bind-hidden="!off.value">
|
|
6
|
+
<span data-icon="alert-triangle" data-icon-size="16"></span>
|
|
7
|
+
<span>This project is <strong>disabled</strong>: its public pages 404 and its external API does not answer. Editing it here carries on.</span>
|
|
8
|
+
<button type="button" class="btn btn-sm btn-primary" data-on-click="enable" data-bind-disabled="busy.value">Enable</button>
|
|
9
|
+
</p>
|
|
10
|
+
<p class="pdx-alert is-bad" data-bind-hidden="!loadError.value">
|
|
11
|
+
<span data-bind-text="loadError.value"></span>
|
|
12
|
+
<button type="button" class="btn btn-sm btn-ghost" data-on-click="retry">Try again</button>
|
|
13
|
+
</p>
|
|
127
14
|
|
|
128
|
-
<div class="
|
|
129
|
-
|
|
130
|
-
<div class="
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
15
|
+
<div class="pdx-hero">
|
|
16
|
+
<div class="pdx-hero-icon" aria-hidden="true"><span data-icon="folder" data-icon-size="32"></span></div>
|
|
17
|
+
<div class="pdx-hero-main">
|
|
18
|
+
<strong class="pdx-name" data-bind-text="name.value"></strong>
|
|
19
|
+
<p class="pdx-desc" data-bind-hidden="!description.value" data-bind-text="description.value"></p>
|
|
20
|
+
<div class="pdx-chips">
|
|
21
|
+
<span class="pdx-chip is-warn" data-bind-hidden="!off.value">Disabled</span>
|
|
22
|
+
<span class="pdx-chip is-ok" data-bind-hidden="off.value || loading.value">Enabled</span>
|
|
23
|
+
<span class="pdx-chip" data-bind-hidden="!builtIn.value" title="Built in - cannot be deleted">Built in</span>
|
|
24
|
+
<span class="pdx-chip" data-bind-text="rootText.value"></span>
|
|
25
|
+
<span data-help-title="Root URL" data-help="Pages whose address starts with the project's root URL are filed under it without being tagged one by one. Change it, or the name, icon and order, on the project's Settings (banner)."></span>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="pdx-meta">
|
|
28
|
+
<span data-bind-hidden="!created.value"><span data-icon="calendar" data-icon-size="13"></span> Created <b data-bind-text="created.value"></b></span>
|
|
29
|
+
<span data-bind-hidden="!creator.value"><span data-icon="user" data-icon-size="13"></span> by <b data-bind-text="creator.value"></b></span>
|
|
30
|
+
<span data-bind-hidden="!updated.value" data-bind-title="updatedTitle.value"><span data-icon="clock" data-icon-size="13"></span> Changed <b data-bind-text="updated.value"></b></span>
|
|
138
31
|
</div>
|
|
139
|
-
<p id="pd-desc" class="pd-desc"></p>
|
|
140
|
-
<div id="pd-meta" class="pd-meta"></div>
|
|
141
32
|
</div>
|
|
142
33
|
</div>
|
|
143
34
|
|
|
144
|
-
<
|
|
145
|
-
<div class="
|
|
146
|
-
<
|
|
147
|
-
<
|
|
35
|
+
<div class="pdx-card">
|
|
36
|
+
<div class="pdx-card-title">
|
|
37
|
+
<span data-icon="layers" data-icon-size="16"></span> Artefacts in this project
|
|
38
|
+
<small class="pdx-muted" data-bind-text="totalText.value"></small>
|
|
39
|
+
<span data-help-title="Artefacts" data-help="Everything filed under this project, by type. Click a type to open its list (or, when there are none, to make the first). The + makes a new one filed under this project - pages, collections, menus and blocks in a quick panel here, the rest in their own editor. Right-click a type (or ⋮, or Shift+F10) for both."></span>
|
|
148
40
|
</div>
|
|
149
|
-
<p class="
|
|
150
|
-
<div
|
|
151
|
-
</
|
|
41
|
+
<p class="pdx-note" data-bind-hidden="!loading.value">Loading…</p>
|
|
42
|
+
<div class="pdx-tiles" data-each="tiles.value key=key"></div>
|
|
43
|
+
</div>
|
|
152
44
|
</div>
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
.pdx { display: flex; flex-direction: column; gap: .9rem; }
|
|
48
|
+
.pdx [hidden] { display: none !important; }
|
|
49
|
+
.pdx-alert { margin: 0; display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; padding: .6rem .8rem; border-radius: var(--dm-radius-md);
|
|
50
|
+
background: color-mix(in srgb, var(--dm-warning, var(--dm-primary)) 16%, transparent); color: var(--dm-text); }
|
|
51
|
+
.pdx-alert.is-bad { background: color-mix(in srgb, var(--dm-danger) 14%, transparent); }
|
|
52
|
+
.pdx-alert > span:not([data-icon]) { flex: 1; min-width: 12rem; }
|
|
53
|
+
.pdx-hero { display: flex; gap: 1.1rem; align-items: flex-start; padding: 1.1rem 1.25rem; border: 1px solid var(--dm-border);
|
|
54
|
+
border-left: 4px solid var(--dm-primary); border-radius: var(--dm-radius-md);
|
|
55
|
+
background: radial-gradient(120% 160% at 0% 0%, color-mix(in srgb, var(--dm-primary) 10%, transparent), transparent 55%), var(--dm-surface); }
|
|
56
|
+
.pdx-hero-icon { width: 56px; height: 56px; flex-shrink: 0; border-radius: var(--dm-radius-md); display: flex; align-items: center; justify-content: center;
|
|
57
|
+
color: var(--dm-primary); background: color-mix(in srgb, var(--dm-primary) 16%, transparent); }
|
|
58
|
+
.pdx-hero-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .4rem; }
|
|
59
|
+
.pdx-name { font-size: var(--dm-text-xl, 1.4rem); line-height: 1.2; }
|
|
60
|
+
.pdx-desc { margin: 0; color: var(--dm-text-muted); max-width: 64ch; }
|
|
61
|
+
.pdx-chips { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
|
|
62
|
+
.pdx-chip { display: inline-flex; align-items: center; font-size: var(--dm-text-xs); font-weight: 600; padding: .1rem .55rem; border-radius: 999px; white-space: nowrap;
|
|
63
|
+
background: color-mix(in srgb, var(--dm-text) 10%, transparent); color: var(--dm-text-muted); }
|
|
64
|
+
.pdx-chip.is-ok { background: color-mix(in srgb, var(--dm-success) 16%, transparent); color: var(--dm-success); }
|
|
65
|
+
.pdx-chip.is-warn { background: color-mix(in srgb, var(--dm-warning, var(--dm-danger)) 18%, transparent); color: var(--dm-warning, var(--dm-danger)); }
|
|
66
|
+
.pdx-meta { display: flex; flex-wrap: wrap; gap: .9rem; color: var(--dm-text-muted); font-size: var(--dm-text-sm); }
|
|
67
|
+
.pdx-meta > span { display: inline-flex; align-items: center; gap: .3rem; }
|
|
68
|
+
.pdx-meta b { color: var(--dm-text); font-weight: 600; }
|
|
69
|
+
.pdx-card { border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); padding: .8rem .95rem; display: flex; flex-direction: column; gap: .7rem; }
|
|
70
|
+
.pdx-card-title { display: flex; align-items: center; gap: .45rem; font-weight: 600; }
|
|
71
|
+
.pdx-muted { color: var(--dm-text-muted); font-weight: 400; font-size: var(--dm-text-sm); }
|
|
72
|
+
.pdx-note { margin: 0; color: var(--dm-text-muted); font-size: var(--dm-text-sm); }
|
|
73
|
+
.pdx-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: .7rem; }
|
|
74
|
+
.pdx-tile { position: relative; display: flex; align-items: center; gap: .75rem; padding: .75rem .8rem; cursor: pointer;
|
|
75
|
+
border: 1px solid var(--dm-border); border-left: 3px solid var(--c, var(--dm-primary)); border-radius: var(--dm-radius-md); background: var(--dm-surface);
|
|
76
|
+
transition: border-color .14s ease, background .14s ease; }
|
|
77
|
+
.pdx-tile:hover, .pdx-tile:focus-visible { border-color: var(--c, var(--dm-primary)); background: var(--dm-table-hover-bg, var(--dm-surface-raised)); outline: none; }
|
|
78
|
+
.pdx-tile.is-empty .pdx-tile-chip, .pdx-tile.is-empty .pdx-tile-body { opacity: .55; }
|
|
79
|
+
.pdx-tile-chip { width: 38px; height: 38px; flex-shrink: 0; border-radius: var(--dm-radius-md); display: flex; align-items: center; justify-content: center;
|
|
80
|
+
color: var(--c, var(--dm-primary)); background: color-mix(in srgb, var(--c, var(--dm-primary)) 14%, transparent); }
|
|
81
|
+
.pdx-tile-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
82
|
+
.pdx-tile-body strong { font-size: 1.4rem; line-height: 1; font-variant-numeric: tabular-nums; }
|
|
83
|
+
.pdx-tile-body small { color: var(--dm-text-muted); font-size: var(--dm-text-xs); text-transform: uppercase; letter-spacing: .03em; margin-top: .2rem; }
|
|
84
|
+
.pdx-tile-actions { display: flex; flex-direction: column; gap: .2rem; align-self: flex-start; }
|
|
85
|
+
.pdx-add, .pdx-kebab { border: 1px solid transparent; background: none; cursor: pointer; color: var(--dm-text-muted); border-radius: var(--dm-radius-sm);
|
|
86
|
+
width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; font-size: var(--dm-text-base); line-height: 1; padding: 0; }
|
|
87
|
+
.pdx-add { color: var(--c, var(--dm-primary)); border-color: var(--dm-border); font-weight: 700; }
|
|
88
|
+
.pdx-add:hover, .pdx-kebab:hover { color: var(--dm-primary); border-color: var(--c, var(--dm-primary)); }
|
|
89
|
+
@media (max-width: 640px) { .pdx-hero { flex-direction: column; } }
|
|
90
|
+
</style>
|