CCM NG: PageModels Editor Alpha finished
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5670 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: 1b96a3c4e0
pull/2/head
parent
9848878d94
commit
9a38b8fcdf
|
|
@ -77,7 +77,7 @@ class CategoryTreeComponentEditorDialog
|
|||
pageModelName={this.props.pageModelName}>
|
||||
|
||||
<label htmlFor={`${idPrefix}showFullTree`}>Show full tree?</label>
|
||||
<input checked={this.props.component.showFullTree}
|
||||
<input checked={this.state.showFullTree}
|
||||
id={`${idPrefix}showFullTree`}
|
||||
onChange={this.handleChange}
|
||||
type="checkbox" />
|
||||
|
|
@ -637,41 +637,45 @@ interface ItemListComponent extends ComponentModel {
|
|||
}
|
||||
|
||||
ComponentModelEditor.registerEditorComponents(
|
||||
"org.librecms.pagemodel.CategoryTreeComponent",
|
||||
{
|
||||
componentTitle: "Category Tree",
|
||||
componentType: "org.librecms.pagemodel.CategoryTreeComponent",
|
||||
editorDialog:
|
||||
CategoryTreeComponentEditorDialog as typeof React.Component,
|
||||
propertiesList:
|
||||
CategoryTreeComponentPropertiesList as typeof React.Component,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
ComponentModelEditor.registerEditorComponents(
|
||||
"org.librecms.pagemodel.ItemListComponent",
|
||||
{
|
||||
componentTitle: "Item List",
|
||||
componentType: "org.librecms.pagemodel.ItemListComponent",
|
||||
editorDialog:
|
||||
ItemListComponentEditorDialog as typeof React.Component,
|
||||
propertiesList:
|
||||
ItemListComponentPropertiesList as typeof React.Component,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
ComponentModelEditor.registerEditorComponents(
|
||||
"org.librecms.pagemodel.FixedContentItemComponent",
|
||||
{
|
||||
componentTitle: "Fixed Content Item",
|
||||
componentType: "org.librecms.pagemodel.FixedContentItemComponent",
|
||||
editorDialog:
|
||||
FixedContentItemComponentEditorDialog as typeof React.Component,
|
||||
propertiesList:
|
||||
FixedContentItemComponentPropertiesList as typeof React.Component,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
ComponentModelEditor.registerEditorComponents(
|
||||
"org.librecms.pagemodel.GreetingItemComponent",
|
||||
{
|
||||
componentTitle: "Greeting Item",
|
||||
componentType: "org.librecms.pagemodel.GreetingItemComponent",
|
||||
editorDialog:
|
||||
GreetingItemComponentEditorDialog as typeof React.Component,
|
||||
propertiesList:
|
||||
GreetingItemComponentPropertiesList as typeof React.Component
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class CategoryTreeComponentJsonConverter
|
|||
|
||||
readBasePropertiesFromJson(jsonObject, categoryTree);
|
||||
|
||||
if (!jsonObject.isNull(SHOW_FULL_TREE)) {
|
||||
if (jsonObject.containsKey(SHOW_FULL_TREE)) {
|
||||
categoryTree.setShowFullTree(jsonObject.getBoolean(SHOW_FULL_TREE));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,22 +83,25 @@ public abstract class AbstractComponentModelJsonConverter
|
|||
Objects.requireNonNull(jsonObject);
|
||||
Objects.requireNonNull(componentModel);
|
||||
|
||||
componentModel.setComponentModelId(
|
||||
jsonObject.getInt("componentModelId"));
|
||||
componentModel.setUuid(jsonObject.getString("uuid"));
|
||||
componentModel.setModelUuid(jsonObject.getString("modelUuid"));
|
||||
//UUIDs are solely managed by the server!
|
||||
// if (jsonObject.containsKey("uuid")) {
|
||||
// componentModel.setUuid(jsonObject.getString("uuid"));
|
||||
// }
|
||||
// if (jsonObject.containsKey("modelUuid")) {
|
||||
// componentModel.setModelUuid(jsonObject.getString("modelUuid"));
|
||||
// }
|
||||
componentModel.setKey(jsonObject.getString("key"));
|
||||
|
||||
if (jsonObject.getString("idAttribute") != null) {
|
||||
if (jsonObject.getString("idAttribute", null) != null) {
|
||||
componentModel.setIdAttribute(jsonObject.getString("idAttribute"));
|
||||
}
|
||||
|
||||
if (jsonObject.getString("classAttribute") != null) {
|
||||
if (jsonObject.getString("classAttribute", null) != null) {
|
||||
componentModel
|
||||
.setClassAttribute(jsonObject.getString("classAttribute"));
|
||||
}
|
||||
|
||||
if (jsonObject.getString("styleAttribute") != null) {
|
||||
if (jsonObject.getString("styleAttribute", null) != null) {
|
||||
componentModel
|
||||
.setStyleAttribute(jsonObject.getString("styleAttribute"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package org.libreccm.pagemodel.rs;
|
||||
|
||||
import org.libreccm.core.CoreConstants;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.pagemodel.ComponentModel;
|
||||
import org.libreccm.pagemodel.ComponentModelJsonConverter;
|
||||
import org.libreccm.pagemodel.ComponentModelRepository;
|
||||
|
|
@ -31,9 +30,6 @@ import org.libreccm.security.AuthorizationRequired;
|
|||
import org.libreccm.security.RequiresPrivilege;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -53,7 +49,6 @@ import javax.json.Json;
|
|||
import javax.json.JsonArray;
|
||||
import javax.json.JsonArrayBuilder;
|
||||
import javax.json.JsonObject;
|
||||
import javax.json.JsonObjectBuilder;
|
||||
import javax.json.JsonValue;
|
||||
import javax.transaction.Transactional;
|
||||
import javax.ws.rs.BadRequestException;
|
||||
|
|
@ -243,7 +238,9 @@ public class Components {
|
|||
|
||||
componentRepo.save(componentModel);
|
||||
|
||||
return mapComponentModelToJson(componentModel);
|
||||
final ComponentModel saved = controller
|
||||
.findComponentModel(app, pageModel, container, componentKey);
|
||||
return mapComponentModelToJson(saved);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -427,7 +424,7 @@ public class Components {
|
|||
try {
|
||||
final Class<?> clazz = Class.forName(type);
|
||||
|
||||
if (clazz.isAssignableFrom(ComponentModel.class)) {
|
||||
if (ComponentModel.class.isAssignableFrom(clazz)) {
|
||||
return (Class<? extends ComponentModel>) clazz;
|
||||
} else {
|
||||
throw new BadRequestException(String.format(
|
||||
|
|
|
|||
|
|
@ -775,6 +775,8 @@ interface ContainerModelComponentProps {
|
|||
|
||||
interface ContainerModelComponentState {
|
||||
|
||||
addComponentOfType: string;
|
||||
addComponentWithKey: string;
|
||||
components: ComponentModel[];
|
||||
errorMessages: string[];
|
||||
}
|
||||
|
|
@ -789,9 +791,15 @@ class ContainerModelComponent
|
|||
|
||||
this.state = {
|
||||
|
||||
addComponentOfType: "",
|
||||
addComponentWithKey: "",
|
||||
components: [],
|
||||
errorMessages: [],
|
||||
};
|
||||
|
||||
this.handleKeyChange = this.handleKeyChange.bind(this);
|
||||
this.handleTypeSelectChange = this.handleTypeSelectChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
|
|
@ -812,7 +820,41 @@ class ContainerModelComponent
|
|||
Delete
|
||||
</button>
|
||||
</div>
|
||||
{this.state.errorMessages.length > 0
|
||||
&& <div className="errorPanel">
|
||||
<ul>
|
||||
{this.state.errorMessages.map((msg, index) =>
|
||||
<li key={index}>{msg}</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
<div className="components-list">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label htmlFor={`${this.props.container.key}_add_component_type`}>
|
||||
Add component of type
|
||||
</label>
|
||||
<select id={`${this.props.container.key}_add_component_type`}
|
||||
onChange={this.handleTypeSelectChange}>
|
||||
<option value=""></option>
|
||||
{ComponentModelEditor.getAvailableComponents()
|
||||
.map((component) =>
|
||||
<option key={component.componentType}
|
||||
value={component.componentType}>
|
||||
{component.componentTitle}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
<label htmlFor={`${this.props.container.key}_add_component_key`}>
|
||||
with key
|
||||
</label>
|
||||
<input id={`${this.props.container.key}_add_component_key`}
|
||||
onChange={this.handleKeyChange}
|
||||
type="text" />
|
||||
<button>
|
||||
Add component
|
||||
</button>
|
||||
</form>
|
||||
<ul>
|
||||
{this.state.components.map((component: ComponentModel) =>
|
||||
<ComponentModelEditor
|
||||
|
|
@ -829,6 +871,15 @@ class ContainerModelComponent
|
|||
</li>;
|
||||
}
|
||||
|
||||
private deleteContainer(
|
||||
event: React.MouseEvent<HTMLButtonElement>,
|
||||
containerKey: string): void {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.props.deleteContainer(containerKey);
|
||||
}
|
||||
|
||||
private fetchComponents(): void {
|
||||
|
||||
const componentsUrl = `${this.props.dispatcherPrefix}`
|
||||
|
|
@ -893,13 +944,126 @@ class ContainerModelComponent
|
|||
});
|
||||
}
|
||||
|
||||
private deleteContainer(
|
||||
event: React.MouseEvent<HTMLButtonElement>,
|
||||
containerKey: string): void {
|
||||
private handleKeyChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
|
||||
const target: HTMLInputElement = event.currentTarget;
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
addComponentWithKey: target.value,
|
||||
});
|
||||
}
|
||||
|
||||
private handleTypeSelectChange(
|
||||
event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||
|
||||
const target: HTMLSelectElement = event.currentTarget;
|
||||
|
||||
this.setState({
|
||||
|
||||
...this.state,
|
||||
addComponentOfType: target.value,
|
||||
});
|
||||
}
|
||||
|
||||
private handleSubmit(event: React.FormEvent<HTMLFormElement>): void {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.props.deleteContainer(containerKey);
|
||||
if (this.state.addComponentOfType === ""
|
||||
|| this.state.addComponentWithKey === "") {
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMessages: [
|
||||
...this.state.errorMessages,
|
||||
`Type and key are mandantory!`,
|
||||
],
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const headers: Headers = new Headers();
|
||||
headers.append("Content-Type", "application/json");
|
||||
|
||||
const init: RequestInit = {
|
||||
|
||||
body: JSON.stringify({
|
||||
type: this.state.addComponentOfType,
|
||||
key: this.state.addComponentWithKey,
|
||||
}),
|
||||
credentials: "same-origin",
|
||||
headers,
|
||||
method: "PUT",
|
||||
}
|
||||
|
||||
const url: string = `${this.props.dispatcherPrefix}`
|
||||
+ `/page-models/${this.props.ccmApplication}/`
|
||||
+ `${this.props.pageModelName}`
|
||||
+ `/containers/`
|
||||
+ `${this.props.container.key}`
|
||||
+ `/components/`
|
||||
+ `${this.state.addComponentWithKey}`;
|
||||
|
||||
fetch(url, init)
|
||||
.then((response: Response) => {
|
||||
|
||||
if (response.ok) {
|
||||
|
||||
response
|
||||
.json()
|
||||
.then((newComponent) => {
|
||||
|
||||
const components = [
|
||||
...this.state.components,
|
||||
newComponent,
|
||||
];
|
||||
components.sort((component1, component2) => {
|
||||
const key1: string = component1.key;
|
||||
const key2: string = component2.key;
|
||||
|
||||
return key1.localeCompare(key2);
|
||||
});
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
addComponentWithKey: "",
|
||||
addComponentOfType: "",
|
||||
components,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMessages: [
|
||||
...this.state.errorMessages,
|
||||
`Failed to parse response: `
|
||||
+ `${error.message}`,
|
||||
],
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMessages: [
|
||||
...this.state.errorMessages,
|
||||
`Failed to add component to container`
|
||||
+ `${response.status} ${response.statusText}`,
|
||||
]
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMessages: [
|
||||
...this.state.errorMessages,
|
||||
`Failed to add component to container`
|
||||
+ ` ${this.props.container.key}: ${error.message}`
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1104,6 +1268,8 @@ class BasicComponentModelEditorDialog
|
|||
|
||||
interface EditorComponents {
|
||||
|
||||
componentType: string;
|
||||
componentTitle: string;
|
||||
editorDialog: typeof React.Component;
|
||||
propertiesList: typeof React.Component;
|
||||
}
|
||||
|
|
@ -1120,10 +1286,30 @@ interface ComponentModelEditorProps {
|
|||
class ComponentModelEditor
|
||||
extends React.Component<ComponentModelEditorProps, {}> {
|
||||
|
||||
public static registerEditorComponents(type: string,
|
||||
components: EditorComponents) {
|
||||
public static getAvailableComponents(): EditorComponents[] {
|
||||
|
||||
ComponentModelEditor.editorComponents.set(type, components);
|
||||
const components: EditorComponents[] = [];
|
||||
|
||||
for(let editorComponents
|
||||
of ComponentModelEditor.editorComponents.values()) {
|
||||
|
||||
components.push(editorComponents);
|
||||
}
|
||||
|
||||
components.sort((component1, component2) => {
|
||||
|
||||
return component1
|
||||
.componentTitle
|
||||
.localeCompare(component2.componentTitle);
|
||||
});
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
public static registerEditorComponents(components: EditorComponents) {
|
||||
|
||||
ComponentModelEditor.editorComponents.set(components.componentType,
|
||||
components);
|
||||
}
|
||||
|
||||
private static editorComponents: Map<string, EditorComponents>
|
||||
|
|
@ -1162,6 +1348,8 @@ class ComponentModelEditor
|
|||
.editorComponents.get(type) as EditorComponents;
|
||||
} else {
|
||||
const basicComponents: EditorComponents = {
|
||||
componentType: type,
|
||||
componentTitle: "",
|
||||
editorDialog:
|
||||
BasicComponentModelEditorDialog as typeof React.Component,
|
||||
propertiesList:
|
||||
|
|
|
|||
Loading…
Reference in New Issue