Skip to content

Commit 381b3db

Browse files
committed
Add page definitions module
1 parent 81e288e commit 381b3db

File tree

17 files changed

+323
-6
lines changed

17 files changed

+323
-6
lines changed

app/assets/builds/alchemy/admin.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/components/alchemy/admin/list_filter.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ module Admin
2121
class ListFilter < ViewComponent::Base
2222
erb_template <<~ERB
2323
<alchemy-list-filter items-selector="<%= items_selector %>" name-attribute="<%= name_attribute %>">
24-
<input type="text" class="js_filter_field" />
24+
<input type="search" class="js_filter_field" />
2525
<alchemy-icon name="search"></alchemy-icon>
26-
<button type="button" class="js_filter_field_clear icon_button">
26+
<button type="reset" class="js_filter_field_clear icon_button">
2727
<alchemy-icon name="close" size="1x"></alchemy-icon>
2828
</button>
2929
</alchemy-list-filter>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module Alchemy
2+
module Admin
3+
class PageDefinitionsController < ResourcesController
4+
def index
5+
@page_definitions = PageDefinition.all
6+
end
7+
8+
private
9+
10+
def resource_handler
11+
@_resource_handler ||= ::Alchemy::Resource.new(controller_path, alchemy_module, PageDefinition)
12+
end
13+
end
14+
end
15+
end

app/javascript/alchemy_admin/components/list_filter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ class ListFilter extends HTMLElement {
4949
}
5050

5151
get clearButton() {
52-
return this.querySelector('button[type="button"]')
52+
return this.querySelector('button[type="reset"]')
5353
}
5454

5555
get filterField() {
56-
return this.querySelector('input[type="text"]')
56+
return this.querySelector('input[type="search"]')
5757
}
5858

5959
get items() {

app/stylesheets/alchemy/admin.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
@use "admin/nodes";
3030
@use "admin/notices";
3131
@use "admin/pagination";
32+
@use "admin/page_definitions";
3233
@use "admin/preview_window";
3334
@use "admin/resource_info";
3435
@use "admin/search";

app/stylesheets/alchemy/admin/base.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ html {
44
box-sizing: border-box;
55
height: 100%;
66
font-size: var(--font-size_medium);
7+
scroll-padding-top: calc(var(--top-menu-height) + var(--spacing-2));
8+
scroll-behavior: smooth;
79

810
&.turbo-progress-bar::before,
911
.turbo-progress-bar {

app/stylesheets/alchemy/admin/list_filter.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ alchemy-list-filter {
99
transform: translateY(-50%);
1010
}
1111

12+
input[type="search"],
1213
.js_filter_field {
1314
width: 100%;
1415
padding-left: var(--spacing-7);
@@ -21,6 +22,7 @@ alchemy-list-filter {
2122
}
2223
}
2324

25+
button[type="reset"],
2426
.js_filter_field_clear {
2527
display: flex;
2628
visibility: hidden;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
.page-definitions {
2+
align-items: self-start;
3+
position: relative;
4+
display: grid;
5+
grid-template-columns: 400px 1fr;
6+
gap: var(--spacing-2);
7+
grid-template-rows: auto;
8+
9+
h2 {
10+
display: flex;
11+
justify-content: space-between;
12+
align-items: center;
13+
margin-top: 0;
14+
15+
small {
16+
font-weight: normal;
17+
font-size: var(--font-size_medium);
18+
}
19+
}
20+
21+
aside {
22+
position: sticky;
23+
top: calc(var(--top-menu-height) + var(--spacing-2));
24+
background-color: var(--sidebar-background-color);
25+
border-radius: var(--border-radius_medium);
26+
padding: var(--spacing-4);
27+
margin-bottom: var(--spacing-2);
28+
29+
ol {
30+
display: flex;
31+
flex-direction: column;
32+
gap: var(--spacing-2);
33+
list-style-position: outside;
34+
margin-left: var(--spacing-1);
35+
}
36+
37+
li {
38+
padding: var(--spacing-1);
39+
font-weight: bold;
40+
}
41+
}
42+
43+
details {
44+
padding: var(--spacing-2);
45+
margin: var(--spacing-2) 0;
46+
background-color: var(--element-header-bg-color);
47+
border-radius: var(--border-radius_medium);
48+
49+
summary {
50+
display: flex;
51+
align-items: center;
52+
justify-content: start;
53+
padding: var(--spacing-1) 0;
54+
font-weight: bold;
55+
gap: var(--spacing-1);
56+
57+
header {
58+
display: flex;
59+
width: 100%;
60+
align-items: center;
61+
justify-content: space-between;
62+
gap: var(--spacing-1);
63+
64+
.label {
65+
padding: var(--spacing-0) var(--spacing-2);
66+
background-color: hsla(0, 0%, 45%, 0.15);
67+
margin-left: auto;
68+
font-weight: normal;
69+
70+
&.usage:before {
71+
content: "x";
72+
}
73+
}
74+
}
75+
76+
&:before {
77+
content: "";
78+
display: flex;
79+
align-items: center;
80+
justify-content: center;
81+
width: var(--spacing-4);
82+
height: var(--spacing-4);
83+
}
84+
}
85+
86+
&[open] > summary:before {
87+
content: "";
88+
}
89+
90+
> div {
91+
padding: var(--spacing-1) 0 var(--spacing-1) var(--spacing-5);
92+
}
93+
94+
ol {
95+
list-style-type: none;
96+
padding-left: 0;
97+
98+
li {
99+
margin: var(--spacing-4) 0;
100+
101+
header {
102+
gap: var(--spacing-2);
103+
}
104+
}
105+
}
106+
107+
details {
108+
padding-left: var(--spacing-1);
109+
background-color: hsla(0, 0%, 45%, 0.05);
110+
}
111+
}
112+
113+
.page-definition {
114+
padding: var(--spacing-4);
115+
margin-bottom: var(--spacing-2);
116+
background-color: var(--sidebar-background-color);
117+
border-radius: var(--border-radius_medium);
118+
119+
p {
120+
margin: var(--spacing-4) 0;
121+
}
122+
}
123+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<% element = Alchemy::ElementDefinition.get(element_name) %>
2+
<% if element %>
3+
<details>
4+
<summary>
5+
<header>
6+
<span class="icon element">
7+
<%= element.icon_file %>
8+
</span>
9+
<%= Alchemy::Element.display_name_for(element.name) %>
10+
<small class="label usage">
11+
<%= Alchemy::Element.named(element.name).count %>
12+
</small>
13+
</header>
14+
</summary>
15+
<div>
16+
<% if element.deprecated %>
17+
<alchemy-message type="warning">
18+
<%= element.deprecation_notice %>
19+
</alchemy-message>
20+
<% end %>
21+
<% if element.has_hint? %>
22+
<p><%= element.hint %></p>
23+
<% end %>
24+
<% if element.unique %>
25+
<sl-tooltip content="This element can only be used once per page">
26+
<small class="label">
27+
<%= Alchemy::Element.human_attribute_name(:unique) %>
28+
</small>
29+
</sl-tooltip>
30+
<% end %>
31+
<% if element.fixed %>
32+
<sl-tooltip content="This element has a fixed position one the page">
33+
<small class="label">
34+
<%= Alchemy::Element.human_attribute_name(:fixed) %>
35+
</small>
36+
</sl-tooltip>
37+
<% end %>
38+
<% if element.ingredients.any? %>
39+
<ol>
40+
<%= render collection: element.ingredients, partial: "ingredient", locals: {element_name: element_name} %>
41+
</ol>
42+
<% end %>
43+
<%= render collection: element.nestable_elements, partial: "element", as: "element_name" %>
44+
</div>
45+
</details>
46+
<% end %>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<li>
2+
<header>
3+
<strong><%= Alchemy::Ingredient.translated_label_for(ingredient.role, element_name) %></strong>
4+
<small><%= Alchemy::Ingredient.normalize_type(ingredient.type).constantize.model_name.human %></small>
5+
</header>
6+
<% if ingredient.has_hint? %>
7+
<p><%== ingredient.hint %></p>
8+
<% end %>
9+
</li>

0 commit comments

Comments
 (0)