Skip to content

Commit 28a30c6

Browse files
committed
Added experimental simple entity table.
Internal API updates. Fix for map fields with an error. Added pages template
1 parent bc2ecc8 commit 28a30c6

35 files changed

+795
-159
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { EntityCollection } from "@firecms/core";
2+
3+
export const pagesCollection: EntityCollection = {
4+
id: "pages",
5+
path: "pages",
6+
name: "Pages",
7+
singularName: "Page",
8+
icon: "insert_drive_file",
9+
description: "List of website pages that can be edited here",
10+
properties: {
11+
title: {
12+
dataType: "string",
13+
name: "Page Title",
14+
validation: { required: true }
15+
},
16+
slug: {
17+
dataType: "string",
18+
name: "URL Slug",
19+
validation: {
20+
required: true,
21+
unique: true,
22+
matches: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,
23+
matchesMessage: "Must be lowercase, alphanumeric, and hyphenated"
24+
}
25+
},
26+
hero_section: {
27+
dataType: "map",
28+
name: "Hero Section",
29+
properties: {
30+
headline: {
31+
dataType: "string",
32+
name: "Headline",
33+
validation: { required: true }
34+
},
35+
subhead: {
36+
dataType: "string",
37+
name: "Subheadline"
38+
},
39+
background_image: {
40+
dataType: "string",
41+
name: "Background Image",
42+
storage: {
43+
storagePath: "page_hero/images",
44+
acceptedFiles: ["image/*"],
45+
}
46+
},
47+
call_to_action: {
48+
dataType: "string",
49+
name: "Call to Action"
50+
},
51+
call_to_action_link: {
52+
dataType: "string",
53+
name: "CTA Link",
54+
url: true
55+
}
56+
}
57+
},
58+
content: {
59+
dataType: "array",
60+
name: "Content",
61+
oneOf: {
62+
properties: {
63+
section: {
64+
dataType: "map",
65+
name: "Section",
66+
properties: {
67+
title: {
68+
dataType: "string",
69+
name: "Section Title",
70+
validation: { required: true }
71+
},
72+
content: {
73+
dataType: "string",
74+
name: "Section Content",
75+
markdown: true
76+
},
77+
image: {
78+
dataType: "string",
79+
name: "Section Image",
80+
storage: {
81+
storagePath: "page_sections/images",
82+
acceptedFiles: ["image/*"]
83+
}
84+
},
85+
link: {
86+
dataType: "string",
87+
name: "Section Link",
88+
url: true
89+
}
90+
}
91+
},
92+
image: {
93+
dataType: "string",
94+
name: "Image",
95+
storage: {
96+
storagePath: "page_sections/images",
97+
acceptedFiles: ["image/*"]
98+
}
99+
},
100+
slider: {
101+
dataType: "array",
102+
name: "Slider",
103+
of: {
104+
dataType: "map",
105+
properties: {
106+
title: {
107+
dataType: "string",
108+
name: "Title",
109+
validation: { required: true }
110+
},
111+
image: {
112+
dataType: "string",
113+
storage: {
114+
storagePath: "page_sections/images",
115+
acceptedFiles: ["image/*"]
116+
}
117+
}
118+
}
119+
}
120+
},
121+
}
122+
}
123+
},
124+
sidebar: {
125+
dataType: "map",
126+
name: "Sidebar",
127+
properties: {
128+
title: {
129+
dataType: "string",
130+
name: "Sidebar Title",
131+
validation: { required: false }
132+
},
133+
content: {
134+
dataType: "string",
135+
name: "Sidebar Content",
136+
markdown: true
137+
}
138+
}
139+
},
140+
seo_metadata: {
141+
dataType: "map",
142+
name: "SEO Metadata",
143+
properties: {
144+
meta_title: {
145+
dataType: "string",
146+
name: "Meta Title"
147+
},
148+
meta_description: {
149+
dataType: "string",
150+
name: "Meta Description"
151+
},
152+
focus_keywords: {
153+
dataType: "array",
154+
name: "Focus Keywords",
155+
of: {
156+
dataType: "string"
157+
}
158+
}
159+
}
160+
},
161+
footer_override: {
162+
dataType: "string",
163+
name: "Footer Override",
164+
markdown: true
165+
},
166+
publish_date: {
167+
dataType: "date",
168+
name: "Publish Date",
169+
validation: { required: true }
170+
},
171+
last_updated: {
172+
dataType: "date",
173+
name: "Last Updated",
174+
autoValue: "on_update"
175+
},
176+
is_published: {
177+
dataType: "boolean",
178+
name: "Is Published",
179+
columnWidth: 100,
180+
description: "Should this page be live on the site?"
181+
},
182+
author_uid: {
183+
dataType: "reference",
184+
name: "Author",
185+
path: "users"
186+
}
187+
}
188+
};

examples/example_v3/src/index.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import { SampleEntityView } from "./custom_entity_view/SampleEntityView";
55
import { colorPropertyConfig } from "./property_configs/color_property_config";
66
import { pricePropertyConfig } from "./property_configs/property_config_builder";
77
import { usersCollection } from "./collections/users_collection";
8+
import { pagesCollection } from "./collections/pages";
89

910
const appConfig: FireCMSAppConfig = {
1011
version: "1",
1112
collections: async (props) => {
1213
return ([
1314
testCollection,
1415
productsCollection,
15-
usersCollection
16+
usersCollection,
17+
pagesCollection
1618
// showcaseCollection
1719
]);
1820
},

packages/collection_editor/src/ui/collection_editor/CollectionEditorWelcomeView.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { productsCollectionTemplate } from "./templates/products_template";
1919
import { blogCollectionTemplate } from "./templates/blog_template";
2020
import { usersCollectionTemplate } from "./templates/users_template";
2121
import { ImportFileUpload } from "@firecms/data_import_export";
22+
import { pagesCollectionTemplate } from "./templates/pages_template";
2223

2324
export function CollectionEditorWelcomeView({
2425
path,
@@ -125,18 +126,25 @@ export function CollectionEditorWelcomeView({
125126
setValues(productsCollectionTemplate);
126127
onContinue();
127128
}}/>
129+
<TemplateButton title={"Users"}
130+
subtitle={"A collection of users with emails, names and roles"}
131+
icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon!}/>}
132+
onClick={() => {
133+
setValues(usersCollectionTemplate);
134+
onContinue();
135+
}}/>
128136
<TemplateButton title={"Blog posts"}
129137
subtitle={"A collection of blog posts with images, authors and complex content"}
130138
icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon!}/>}
131139
onClick={() => {
132140
setValues(blogCollectionTemplate);
133141
onContinue();
134142
}}/>
135-
<TemplateButton title={"Users"}
136-
subtitle={"A collection of users with emails, names and roles"}
137-
icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon!}/>}
143+
<TemplateButton title={"Pages"}
144+
subtitle={"A collection of pages with images, authors and complex content"}
145+
icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon!}/>}
138146
onClick={() => {
139-
setValues(usersCollectionTemplate);
147+
setValues(pagesCollectionTemplate);
140148
onContinue();
141149
}}/>
142150
</div>

packages/collection_editor/src/ui/collection_editor/templates/pages_template.ts

+56-21
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export const pagesCollectionTemplate: EntityCollection = {
1919
validation: {
2020
required: true,
2121
unique: true,
22-
matches: /^[a-z0-9]+(?:-[a-z0-9]+)*$/
22+
matches: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,
23+
matchesMessage: "Must be lowercase, alphanumeric, and hyphenated"
2324
}
2425
},
2526
hero_section: {
@@ -54,35 +55,69 @@ export const pagesCollectionTemplate: EntityCollection = {
5455
}
5556
}
5657
},
57-
sections: {
58+
content: {
5859
dataType: "array",
59-
name: "Content Sections",
60-
of: {
61-
dataType: "map",
60+
name: "Content",
61+
oneOf: {
6262
properties: {
63-
title: {
64-
dataType: "string",
65-
name: "Section Title",
66-
validation: { required: true }
67-
},
68-
content: {
69-
dataType: "string",
70-
name: "Section Content",
71-
markdown: true
63+
section: {
64+
dataType: "map",
65+
name: "Section",
66+
properties: {
67+
title: {
68+
dataType: "string",
69+
name: "Section Title",
70+
validation: { required: true }
71+
},
72+
content: {
73+
dataType: "string",
74+
name: "Section Content",
75+
markdown: true
76+
},
77+
image: {
78+
dataType: "string",
79+
name: "Section Image",
80+
storage: {
81+
storagePath: "page_sections/images",
82+
acceptedFiles: ["image/*"]
83+
}
84+
},
85+
link: {
86+
dataType: "string",
87+
name: "Section Link",
88+
url: true
89+
}
90+
}
7291
},
7392
image: {
7493
dataType: "string",
75-
name: "Section Image",
94+
name: "Image",
7695
storage: {
7796
storagePath: "page_sections/images",
78-
acceptedFiles: ["image/*"],
97+
acceptedFiles: ["image/*"]
98+
}
99+
},
100+
slider: {
101+
dataType: "array",
102+
name: "Slider",
103+
of: {
104+
dataType: "map",
105+
properties: {
106+
title: {
107+
dataType: "string",
108+
name: "Title",
109+
validation: { required: true }
110+
},
111+
image: {
112+
dataType: "string",
113+
storage: {
114+
storagePath: "page_sections/images",
115+
acceptedFiles: ["image/*"]
116+
}
117+
}
118+
}
79119
}
80120
},
81-
link: {
82-
dataType: "string",
83-
name: "Section Link",
84-
url: true
85-
}
86121
}
87122
}
88123
},

packages/collection_editor/src/ui/collection_editor/templates/users_template.ts

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export const usersCollectionTemplate: EntityCollection = {
2525
name: "Phone",
2626
dataType: "string"
2727
},
28+
favourite_products: {
29+
name: "Favourite products",
30+
dataType: "array",
31+
of: {
32+
dataType: "reference",
33+
path: "products"
34+
}
35+
},
2836
photoURL: {
2937
name: "Photo URL",
3038
dataType: "string",

packages/firebase_firecms_pro/src/FireCMSProApp.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ function FireCMSProInternal({ firebaseApp, fireCMSBackend, configError, firebase
268268
const modeController = useBuildModeController();
269269

270270
if (configError) {
271-
return <CenteredView fullScreen={true}>{configError}</CenteredView>;
271+
return <CenteredView>{configError}</CenteredView>;
272272
}
273273

274274
return (

0 commit comments

Comments
 (0)