画廊添加
This commit is contained in:
@@ -428,6 +428,32 @@ Json make_amis_view_node(const View_Node& node, const Json& descriptor_json, std
|
||||
if(node.kind == View_Node_Kind::field) {
|
||||
return make_typed_amis_control_by_name(descriptor_json, descriptor, node.field, permission, prefix);
|
||||
}
|
||||
if(node.kind == View_Node_Kind::frontend) {
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "container");
|
||||
json_set(result, "body", make_amis_view_body<Json, T>(View_Node{View_Node_Kind::vertical, {}, {}, {}, {}, 0, false, false, node.children}, descriptor_json, permission, prefix));
|
||||
json_set(result, "className", "adminive-frontend-placement");
|
||||
apply_view_node_options(result, node, prefix);
|
||||
return result;
|
||||
}
|
||||
if(node.kind == View_Node_Kind::list) {
|
||||
Json body = json_array<Json>();
|
||||
for(const auto& child : node.children) {
|
||||
Json item = json_object<Json>();
|
||||
json_set(item, "type", "container");
|
||||
json_set(item, "body", make_amis_view_body<Json, T>(child, descriptor_json, permission, prefix));
|
||||
Json style = json_object<Json>();
|
||||
json_set(style, "padding", "10px 0");
|
||||
json_set(style, "borderBottom", "1px solid #e5e7eb");
|
||||
json_set(item, "style", std::move(style));
|
||||
json_append(body, std::move(item));
|
||||
}
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "container");
|
||||
json_set(result, "body", std::move(body));
|
||||
apply_view_node_options(result, node, prefix);
|
||||
return result;
|
||||
}
|
||||
if(node.kind == View_Node_Kind::group) {
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "fieldset");
|
||||
@@ -571,6 +597,32 @@ Json make_amis_composition_node(const Composition_Node& node, const std::map<std
|
||||
apply_composition_node_options(result, node);
|
||||
return result;
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::frontend) {
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "container");
|
||||
json_set(result, "body", make_amis_composition_body<Json>(Composition_Node{Composition_Node_Kind::vertical, {}, {}, {}, {}, {}, 0, false, false, node.children}, slots));
|
||||
json_set(result, "className", "adminive-frontend-placement");
|
||||
apply_composition_node_options(result, node);
|
||||
return result;
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::list) {
|
||||
Json body = json_array<Json>();
|
||||
for(const auto& child : node.children) {
|
||||
Json item = json_object<Json>();
|
||||
json_set(item, "type", "container");
|
||||
json_set(item, "body", make_amis_composition_body<Json>(child, slots));
|
||||
Json style = json_object<Json>();
|
||||
json_set(style, "padding", "10px 0");
|
||||
json_set(style, "borderBottom", "1px solid #e5e7eb");
|
||||
json_set(item, "style", std::move(style));
|
||||
json_append(body, std::move(item));
|
||||
}
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "container");
|
||||
json_set(result, "body", std::move(body));
|
||||
apply_composition_node_options(result, node);
|
||||
return result;
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::group) {
|
||||
Json result = json_object<Json>();
|
||||
json_set(result, "type", "panel");
|
||||
@@ -943,5 +995,64 @@ Json to_amis_table_schema(std::string base_api, const Table_View& view, const Js
|
||||
json_set(result, "body", std::move(page_body));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <Json_Type Json>
|
||||
Json amis_collection_actions(const Json& crud) {
|
||||
const auto& columns = Json_Adapter<Json>::at(crud, "columns");
|
||||
return Json_Adapter<Json>::at(Json_Adapter<Json>::at(columns, Json_Adapter<Json>::size(columns) - 1), "buttons");
|
||||
}
|
||||
template <Json_Type Json>
|
||||
void replace_amis_reload_target(Json& value, std::string_view old_target, std::string_view new_target) {
|
||||
if(Json_Adapter<Json>::is_object(value)) {
|
||||
if(Json_Adapter<Json>::contains(value, "reload")) {
|
||||
auto& reload = Json_Adapter<Json>::at(value, "reload");
|
||||
if(Json_Adapter<Json>::is_string(reload) && json_get<Json, std::string>(reload) == old_target) {
|
||||
json_set(value, "reload", new_target);
|
||||
}
|
||||
}
|
||||
for(const auto& key : Json_Adapter<Json>::keys(value)) {
|
||||
replace_amis_reload_target<Json>(Json_Adapter<Json>::at(value, key), old_target, new_target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(Json_Adapter<Json>::is_array(value)) {
|
||||
for(std::size_t index = 0; index < Json_Adapter<Json>::size(value); ++index) {
|
||||
replace_amis_reload_target<Json>(Json_Adapter<Json>::at(value, index), old_target, new_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
template <Json_Type Json>
|
||||
Json make_amis_collection_variant(Json schema, std::string mode, std::string item_key, Json item, std::size_t columns_count = 0) {
|
||||
auto& body = Json_Adapter<Json>::at(schema, "body");
|
||||
auto& crud = Json_Adapter<Json>::at(body, Json_Adapter<Json>::size(body) - 1);
|
||||
const std::string old_id = json_get<Json, std::string>(Json_Adapter<Json>::at(crud, "id"));
|
||||
const std::string id = old_id + "_" + mode;
|
||||
if(!Json_Adapter<Json>::contains(item, "actions")) {
|
||||
json_set(item, "actions", amis_collection_actions<Json>(crud));
|
||||
}
|
||||
const auto& old_toolbar = Json_Adapter<Json>::at(crud, "headerToolbar");
|
||||
Json toolbar = json_array<Json>();
|
||||
for(std::size_t index = 1; index < Json_Adapter<Json>::size(old_toolbar); ++index) {
|
||||
json_append(toolbar, Json_Adapter<Json>::at(old_toolbar, index));
|
||||
}
|
||||
Json_Adapter<Json>::erase(crud, "columns");
|
||||
json_set(crud, "id", id);
|
||||
json_set(crud, "headerToolbar", std::move(toolbar));
|
||||
json_set(crud, "mode", std::move(mode));
|
||||
json_set(crud, item_key, std::move(item));
|
||||
if(columns_count != 0) {
|
||||
json_set(crud, "columnsCount", columns_count);
|
||||
}
|
||||
replace_amis_reload_target<Json>(crud, old_id, id);
|
||||
return schema;
|
||||
}
|
||||
template <Json_Type Json, class T>
|
||||
requires Described_Type<Object_Model_Type<T>>
|
||||
Json to_amis_list_schema(std::string base_api, const Table_View& view, Json list_item, const Json* item_status_descriptor = nullptr, std::uint64_t item_status_interval = 2000, const Json* overview_status_descriptor = nullptr, std::string overview_status_api = {}, std::uint64_t overview_status_interval = 2000) {
|
||||
return make_amis_collection_variant<Json>(to_amis_table_schema<Json, T>(std::move(base_api), view, item_status_descriptor, item_status_interval, overview_status_descriptor, std::move(overview_status_api), overview_status_interval), "list", "listItem", std::move(list_item));
|
||||
}
|
||||
template <Json_Type Json, class T>
|
||||
requires Described_Type<Object_Model_Type<T>>
|
||||
Json to_amis_cards_schema(std::string base_api, const Table_View& view, Json card, std::size_t columns_count = 3, const Json* item_status_descriptor = nullptr, std::uint64_t item_status_interval = 2000, const Json* overview_status_descriptor = nullptr, std::string overview_status_api = {}, std::uint64_t overview_status_interval = 2000) {
|
||||
return make_amis_collection_variant<Json>(to_amis_table_schema<Json, T>(std::move(base_api), view, item_status_descriptor, item_status_interval, overview_status_descriptor, std::move(overview_status_api), overview_status_interval), "cards", "card", std::move(card), columns_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@ namespace adminive {
|
||||
enum class Composition_Node_Kind {
|
||||
slot,
|
||||
heading,
|
||||
frontend,
|
||||
vertical,
|
||||
horizontal,
|
||||
flow,
|
||||
grid,
|
||||
list,
|
||||
group,
|
||||
card,
|
||||
tabs,
|
||||
@@ -77,6 +79,10 @@ Composition_Node make_container(Composition_Node_Kind kind, Children&&... childr
|
||||
return result;
|
||||
}
|
||||
template <class... Children>
|
||||
Composition_Node frontend(Children&&... children) {
|
||||
return make_container(Composition_Node_Kind::frontend, std::forward<Children>(children)...);
|
||||
}
|
||||
template <class... Children>
|
||||
Composition_Node vertical(Children&&... children) {
|
||||
return make_container(Composition_Node_Kind::vertical, std::forward<Children>(children)...);
|
||||
}
|
||||
@@ -95,6 +101,10 @@ Composition_Node grid(std::size_t columns, Children&&... children) {
|
||||
return result;
|
||||
}
|
||||
template <class... Children>
|
||||
Composition_Node list(Children&&... children) {
|
||||
return make_container(Composition_Node_Kind::list, std::forward<Children>(children)...);
|
||||
}
|
||||
template <class... Children>
|
||||
Composition_Node group(std::string title, Children&&... children) {
|
||||
auto result = make_container(Composition_Node_Kind::group, std::forward<Children>(children)...);
|
||||
result.title = std::move(title);
|
||||
@@ -130,13 +140,16 @@ struct Composition_View {
|
||||
inline Composition_View composition_view(std::string name, Composition_Node body) {
|
||||
return Composition_View{std::move(name), {}, std::move(body)};
|
||||
}
|
||||
inline void validate_composition_node(const Composition_Node& node) {
|
||||
inline void validate_composition_node_impl(const Composition_Node& node, bool tab_allowed) {
|
||||
if(node.kind == Composition_Node_Kind::slot && node.slot.empty()) {
|
||||
throw std::invalid_argument("composition slot name must not be empty");
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::grid && node.columns == 0) {
|
||||
throw std::invalid_argument("composition grid requires at least one column");
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::tab && !tab_allowed) {
|
||||
throw std::invalid_argument("composition tab can only be used inside tabs");
|
||||
}
|
||||
if(node.kind == Composition_Node_Kind::tabs) {
|
||||
for(const auto& child : node.children) {
|
||||
if(child.kind != Composition_Node_Kind::tab) {
|
||||
@@ -145,9 +158,12 @@ inline void validate_composition_node(const Composition_Node& node) {
|
||||
}
|
||||
}
|
||||
for(const auto& child : node.children) {
|
||||
validate_composition_node(child);
|
||||
validate_composition_node_impl(child, node.kind == Composition_Node_Kind::tabs);
|
||||
}
|
||||
}
|
||||
inline void validate_composition_node(const Composition_Node& node) {
|
||||
validate_composition_node_impl(node, false);
|
||||
}
|
||||
inline void validate_composition_view(const Composition_View& view) {
|
||||
if(view.name.empty()) {
|
||||
throw std::invalid_argument("composition view name must not be empty");
|
||||
|
||||
@@ -12,10 +12,12 @@ namespace adminive {
|
||||
enum class View_Node_Kind {
|
||||
all_fields,
|
||||
field,
|
||||
frontend,
|
||||
vertical,
|
||||
horizontal,
|
||||
flow,
|
||||
grid,
|
||||
list,
|
||||
group,
|
||||
card,
|
||||
tabs,
|
||||
@@ -107,6 +109,10 @@ View_Node make_view_container(View_Node_Kind kind, Children&&... children) {
|
||||
return result;
|
||||
}
|
||||
template <class... Children>
|
||||
View_Node frontend(Children&&... children) {
|
||||
return make_view_container(View_Node_Kind::frontend, std::forward<Children>(children)...);
|
||||
}
|
||||
template <class... Children>
|
||||
View_Node vertical(Children&&... children) {
|
||||
return make_view_container(View_Node_Kind::vertical, std::forward<Children>(children)...);
|
||||
}
|
||||
@@ -125,6 +131,10 @@ View_Node grid(std::size_t columns, Children&&... children) {
|
||||
return result;
|
||||
}
|
||||
template <class... Children>
|
||||
View_Node list(Children&&... children) {
|
||||
return make_view_container(View_Node_Kind::list, std::forward<Children>(children)...);
|
||||
}
|
||||
template <class... Children>
|
||||
View_Node group(std::string title, Children&&... children) {
|
||||
auto result = make_view_container(View_Node_Kind::group, std::forward<Children>(children)...);
|
||||
result.title = std::move(title);
|
||||
@@ -380,7 +390,7 @@ bool descriptor_has_field(const Descriptor& descriptor, std::string_view name) {
|
||||
return found;
|
||||
}
|
||||
template <Described_Type T>
|
||||
void validate_view_node(const View_Node& node) {
|
||||
void validate_view_node_impl(const View_Node& node, bool tab_allowed) {
|
||||
const auto descriptor = describe<T>();
|
||||
if(node.kind == View_Node_Kind::field && !descriptor_has_field(descriptor, node.field)) {
|
||||
throw std::invalid_argument("view field does not exist: " + node.field);
|
||||
@@ -388,6 +398,9 @@ void validate_view_node(const View_Node& node) {
|
||||
if(node.kind == View_Node_Kind::grid && node.columns == 0) {
|
||||
throw std::invalid_argument("grid view requires at least one column");
|
||||
}
|
||||
if(node.kind == View_Node_Kind::tab && !tab_allowed) {
|
||||
throw std::invalid_argument("tab view can only be used inside tabs");
|
||||
}
|
||||
if(node.kind == View_Node_Kind::tabs) {
|
||||
for(const auto& child : node.children) {
|
||||
if(child.kind != View_Node_Kind::tab) {
|
||||
@@ -396,10 +409,14 @@ void validate_view_node(const View_Node& node) {
|
||||
}
|
||||
}
|
||||
for(const auto& child : node.children) {
|
||||
validate_view_node<T>(child);
|
||||
validate_view_node_impl<T>(child, node.kind == View_Node_Kind::tabs);
|
||||
}
|
||||
}
|
||||
template <Described_Type T>
|
||||
void validate_view_node(const View_Node& node) {
|
||||
validate_view_node_impl<T>(node, false);
|
||||
}
|
||||
template <Described_Type T>
|
||||
void validate_form_view(const Form_View& view) {
|
||||
if(view.name.empty()) {
|
||||
throw std::invalid_argument("form view name must not be empty");
|
||||
|
||||
@@ -9,6 +9,8 @@ inline std::string_view composition_node_kind_name(Composition_Node_Kind value)
|
||||
return "slot";
|
||||
case Composition_Node_Kind::heading:
|
||||
return "heading";
|
||||
case Composition_Node_Kind::frontend:
|
||||
return "frontend";
|
||||
case Composition_Node_Kind::vertical:
|
||||
return "vertical";
|
||||
case Composition_Node_Kind::horizontal:
|
||||
@@ -17,6 +19,8 @@ inline std::string_view composition_node_kind_name(Composition_Node_Kind value)
|
||||
return "flow";
|
||||
case Composition_Node_Kind::grid:
|
||||
return "grid";
|
||||
case Composition_Node_Kind::list:
|
||||
return "list";
|
||||
case Composition_Node_Kind::group:
|
||||
return "group";
|
||||
case Composition_Node_Kind::card:
|
||||
@@ -83,6 +87,8 @@ inline std::string_view view_node_kind_name(View_Node_Kind value) noexcept {
|
||||
return "all_fields";
|
||||
case View_Node_Kind::field:
|
||||
return "field";
|
||||
case View_Node_Kind::frontend:
|
||||
return "frontend";
|
||||
case View_Node_Kind::vertical:
|
||||
return "vertical";
|
||||
case View_Node_Kind::horizontal:
|
||||
@@ -91,6 +97,8 @@ inline std::string_view view_node_kind_name(View_Node_Kind value) noexcept {
|
||||
return "flow";
|
||||
case View_Node_Kind::grid:
|
||||
return "grid";
|
||||
case View_Node_Kind::list:
|
||||
return "list";
|
||||
case View_Node_Kind::group:
|
||||
return "group";
|
||||
case View_Node_Kind::card:
|
||||
|
||||
Reference in New Issue
Block a user