@axium/server 0.28.3 → 0.28.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/server",
3
- "version": "0.28.3",
3
+ "version": "0.28.4",
4
4
  "author": "James Prevett <axium@jamespre.dev>",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -77,9 +77,9 @@
77
77
  <p>{user.id}</p>
78
78
  <ClipboardCopy value={user.id} --size="16px" />
79
79
  </div>
80
- <span>
81
- <button class="signout" command="show-modal" commandfor="logout">Sign Out</button>
82
- <button style:cursor="pointer" command="show-modal" commandfor="delete" class="danger">Delete Account</button>
80
+ <div class="inline-button-container">
81
+ <button command="show-modal" commandfor="logout" class="inline-button signout">Sign Out</button>
82
+ <button command="show-modal" commandfor="delete" class="inline-button danger">Delete Account</button>
83
83
  <Logout />
84
84
  <FormDialog
85
85
  id="delete"
@@ -89,7 +89,7 @@
89
89
  >
90
90
  <p>Are you sure you want to delete your account?<br />This action can't be undone.</p>
91
91
  </FormDialog>
92
- </span>
92
+ </div>
93
93
  </div>
94
94
 
95
95
  <div class="section main">
@@ -140,11 +140,10 @@
140
140
  <p>Are you sure you want to delete this passkey?<br />This action can't be undone.</p>
141
141
  </FormDialog>
142
142
  {/each}
143
- <span>
144
- <button onclick={() => createPasskey(user.id).then(passkeys.push.bind(passkeys))} class="icon-text">
145
- <Icon i="plus" /> Create
146
- </button>
147
- </span>
143
+
144
+ <button onclick={() => createPasskey(user.id).then(passkeys.push.bind(passkeys))} class="inline-button icon-text">
145
+ <Icon i="plus" /> Create
146
+ </button>
148
147
  </div>
149
148
 
150
149
  <div class="section main">
@@ -181,8 +180,4 @@
181
180
  .greeting {
182
181
  font-size: 2em;
183
182
  }
184
-
185
- .signout {
186
- margin-top: 2em;
187
- }
188
183
  </style>
@@ -65,6 +65,7 @@
65
65
 
66
66
  #admin-content {
67
67
  padding-bottom: 4em;
68
+ grid-column: 1;
68
69
  }
69
70
 
70
71
  #admin-sidebar {
@@ -77,6 +78,7 @@
77
78
  justify-content: space-around;
78
79
  gap: 1em;
79
80
  padding: 0.5em;
81
+ z-index: 6;
80
82
  }
81
83
 
82
84
  .sidebar-text {
@@ -25,82 +25,103 @@
25
25
 
26
26
  <form id="filter" method="dialog">
27
27
  <h4>Filters</h4>
28
- <span>Minimum Severity:</span>
29
- <select name="severity" value={data.filter.severity}>
30
- {#each severityNames as value}
31
- <option {value} selected={value == 'info'}>{capitalize(value)}</option>
32
- {/each}
33
- </select>
34
- <span>Since:</span>
35
- <input type="date" name="since" value={data.filter.since} />
36
-
37
- <span>Until:</span>
38
- <input type="date" name="until" value={data.filter.until} />
39
-
40
- <span>Tags:</span>
41
- <input type="text" name="tags" value={data.filter.tags} />
42
-
43
- <span>Event Name:</span>
44
- {#if data.configured}
45
- <select name="event">
46
- <option value="">Any</option>
47
- {#each data.configured.name as name}
48
- <option value={name} selected={data.filter.event == name}>{name}</option>
49
- {/each}
50
- </select>
51
- {:else}
52
- <input type="text" name="event" value={data.filter.event} />
53
- {/if}
54
-
55
- <span>Source:</span>
56
- {#if data.configured}
57
- <select name="source">
58
- <option value="">Any</option>
59
- {#each data.configured.source as source}
60
- <option value={source} selected={data.filter.source == source}>{source}</option>
28
+
29
+ <div class="filter-field">
30
+ <span>Minimum Severity:</span>
31
+ <select name="severity" value={data.filter.severity}>
32
+ {#each severityNames as value}
33
+ <option {value} selected={value == 'info'}>{capitalize(value)}</option>
61
34
  {/each}
62
35
  </select>
63
- {:else}
64
- <input type="text" name="source" value={data.filter.source} />
65
- {/if}
66
-
67
- <span>User UUID:</span>
68
- <input type="text" name="user" size="36" value={data.filter.user} />
69
- <button
70
- onclick={e => {
71
- e.preventDefault();
72
- const fd = new FormData(e.currentTarget.form!);
73
- const params = new URLSearchParams();
74
- for (let [key, value] of fd.entries()) {
75
- if (!value) continue;
76
- switch (key) {
77
- case 'severity':
78
- if (value != 'info') params.set(key, value as string);
79
- break;
80
- case 'since':
81
- case 'until':
82
- params.set(key, new Date(value as string).toISOString());
83
- break;
84
- case 'tags':
85
- for (const tag of value
86
- .toString()
87
- .split(',')
88
- .map(t => t.trim()))
89
- params.append(key, tag);
90
- break;
91
- default:
92
- params.set(key, value as string);
36
+ </div>
37
+
38
+ <div class="filter-field">
39
+ <span>Since:</span>
40
+ <input type="date" name="since" value={data.filter.since} />
41
+ </div>
42
+
43
+ <div class="filter-field">
44
+ <span>Until:</span>
45
+ <input type="date" name="until" value={data.filter.until} />
46
+ </div>
47
+
48
+ <div class="filter-field">
49
+ <span>Tags:</span>
50
+ <input type="text" name="tags" value={data.filter.tags} />
51
+ </div>
52
+
53
+ <div class="filter-field">
54
+ <span>Event Name:</span>
55
+ {#if data.configured}
56
+ <select name="event">
57
+ <option value="">Any</option>
58
+ {#each data.configured.name as name}
59
+ <option value={name} selected={data.filter.event == name}>{name}</option>
60
+ {/each}
61
+ </select>
62
+ {:else}
63
+ <input type="text" name="event" value={data.filter.event} />
64
+ {/if}
65
+ </div>
66
+
67
+ <div class="filter-field">
68
+ <span>Source:</span>
69
+ {#if data.configured}
70
+ <select name="source">
71
+ <option value="">Any</option>
72
+ {#each data.configured.source as source}
73
+ <option value={source} selected={data.filter.source == source}>{source}</option>
74
+ {/each}
75
+ </select>
76
+ {:else}
77
+ <input type="text" name="source" value={data.filter.source} />
78
+ {/if}
79
+ </div>
80
+
81
+ <div class="filter-field">
82
+ <span>User UUID:</span>
83
+ <input type="text" name="user" size="36" value={data.filter.user} />
84
+ </div>
85
+
86
+ <div class="inline-button-container">
87
+ <button
88
+ class="inline-button"
89
+ onclick={e => {
90
+ e.preventDefault();
91
+ const fd = new FormData(e.currentTarget.form!);
92
+ const params = new URLSearchParams();
93
+ for (let [key, value] of fd.entries()) {
94
+ if (!value) continue;
95
+ switch (key) {
96
+ case 'severity':
97
+ if (value != 'info') params.set(key, value as string);
98
+ break;
99
+ case 'since':
100
+ case 'until':
101
+ params.set(key, new Date(value as string).toISOString());
102
+ break;
103
+ case 'tags':
104
+ for (const tag of value
105
+ .toString()
106
+ .split(',')
107
+ .map(t => t.trim()))
108
+ params.append(key, tag);
109
+ break;
110
+ default:
111
+ params.set(key, value as string);
112
+ }
93
113
  }
94
- }
95
- location.search = params ? '?' + params.toString() : '';
96
- }}>Apply</button
97
- >
98
- <button
99
- onclick={e => {
100
- e.preventDefault();
101
- location.search = '';
102
- }}>Reset</button
103
- >
114
+ location.search = params ? '?' + params.toString() : '';
115
+ }}>Apply</button
116
+ >
117
+ <button
118
+ class="inline-button"
119
+ onclick={e => {
120
+ e.preventDefault();
121
+ location.search = '';
122
+ }}>Reset</button
123
+ >
124
+ </div>
104
125
  </form>
105
126
 
106
127
  <div class="list-container">
@@ -146,13 +167,22 @@
146
167
  background-color: var(--bg-menu);
147
168
  padding: 1em;
148
169
  border-radius: 0.5em;
149
- display: grid;
150
- grid-template-columns: repeat(2, 1fr);
170
+ display: flex;
171
+ flex-wrap: wrap;
172
+ flex-direction: column;
151
173
  gap: 0.25em;
152
174
  width: fit-content;
175
+ }
176
+
177
+ .filter-field {
178
+ display: grid;
179
+ grid-template-columns: 1fr 1fr;
180
+ gap: 0.25em;
181
+ }
153
182
 
154
- h4 {
155
- grid-column: 1 / span 2;
183
+ @media (width < 700px) {
184
+ #filter {
185
+ width: calc(100%);
156
186
  }
157
187
  }
158
188
  </style>
@@ -26,7 +26,7 @@
26
26
  <div class="user list-item" onclick={e => e.currentTarget === e.target && (location.href = '/admin/users/' + user.id)}>
27
27
  <span>{user.name}</span>
28
28
  <span>{user.email}</span>
29
- <span>
29
+ <span class="mobile-hide">
30
30
  {#if user.isAdmin}
31
31
  {@render attr('crown', 'Admin', '#710')}
32
32
  {/if}
@@ -37,8 +37,14 @@
37
37
  {@render attr('at', role)}
38
38
  {/each}
39
39
  </span>
40
- <a href="/admin/audit?user={user.id}"><Icon i="file-shield" /></a>
41
- <a href="/admin/users/{user.id}"><Icon i="chevron-right" /></a>
40
+ <a class="icon-text mobile-button" href="/admin/audit?user={user.id}">
41
+ <Icon i="file-shield" />
42
+ <span class="mobile-only">Audit</span>
43
+ </a>
44
+ <a class="icon-text mobile-button" href="/admin/users/{user.id}">
45
+ <Icon i="chevron-right" />
46
+ <span class="mobile-only">Manage</span>
47
+ </a>
42
48
  </div>
43
49
  {:else}
44
50
  <div class="error">No users!</div>
@@ -46,10 +52,6 @@
46
52
  </div>
47
53
 
48
54
  <style>
49
- .list-item {
50
- grid-template-columns: 1fr 1fr 3fr repeat(2, 2em);
51
- }
52
-
53
55
  .attribute {
54
56
  border-radius: 1em;
55
57
  padding: 0.25em 0.75em;
@@ -57,4 +59,14 @@
57
59
  align-items: center;
58
60
  gap: 0.25em;
59
61
  }
62
+
63
+ .list-item {
64
+ grid-template-columns: 1fr 1fr 3fr repeat(2, 2em);
65
+ }
66
+
67
+ @media (width < 700px) {
68
+ .list-item {
69
+ grid-template-columns: 1fr 1fr;
70
+ }
71
+ }
60
72
  </style>