CCM NG:
* List of PageModels for the PageModelEditor * Implementation of Bebop ContextBar for the PagesAdminPage git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5463 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
d20ff5f711
commit
c0cc56f727
|
|
@ -65,14 +65,13 @@ public class WorkspaceContextBar extends ContextBar {
|
|||
final ApplicationRepository appRepo = cdiUtil.findBean(
|
||||
ApplicationRepository.class);
|
||||
final List<CcmApplication> apps = appRepo.findByType(
|
||||
CmsConstants.CONTENT_SECTION_APP_TYPE);
|
||||
CmsConstants.CONTENT_CENTER_APP_TYPE);
|
||||
|
||||
final String centerPath = apps.get(0).getPrimaryUrl();
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Got Url: " + centerPath);
|
||||
}
|
||||
final URL url = URL.there(state.getRequest(), centerPath);
|
||||
|
||||
entries.add(new Entry(centerTitle, url));
|
||||
|
||||
return entries;
|
||||
|
|
|
|||
|
|
@ -43,14 +43,12 @@ import com.arsdigita.cms.ui.CMSApplicationPage;
|
|||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||
import com.arsdigita.ui.ReactApp;
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
import com.arsdigita.ui.admin.categories.CategoriesTreeModel;
|
||||
import com.arsdigita.util.LockableImpl;
|
||||
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.CategoryRepository;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.core.CoreConstants;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
|
|
@ -84,6 +82,7 @@ public class PagesAdminPage extends CMSApplicationPage {
|
|||
private final SaveCancelSection saveCancelSection;
|
||||
|
||||
private Pages pagesInstance;
|
||||
private PagesContextBar pagesContextBar;
|
||||
|
||||
public PagesAdminPage() {
|
||||
|
||||
|
|
@ -160,7 +159,10 @@ public class PagesAdminPage extends CMSApplicationPage {
|
|||
// "admin:pageModelsManager", AdminUiConstants.ADMIN_XML_NS);
|
||||
// pageModelsManager.add(new Text("Placeholder page models editor"));
|
||||
final ReactApp pageModelsManager = new ReactApp(
|
||||
"page-models-editor", "dist/ccm-pagemodelseditor.js");
|
||||
"page-models-editor", "scripts/dist/ccm-cms.js");
|
||||
|
||||
pagesContextBar = new PagesContextBar();
|
||||
super.add(pagesContextBar);
|
||||
|
||||
final TabbedPane tabbedPane = new TabbedPane();
|
||||
tabbedPane.addTab(new Label(new GlobalizedMessage(
|
||||
|
|
@ -183,6 +185,7 @@ public class PagesAdminPage extends CMSApplicationPage {
|
|||
|
||||
public void setPagesInstance(final Pages pagesInstance) {
|
||||
this.pagesInstance = pagesInstance;
|
||||
pagesContextBar.setPagesInstance(pagesInstance);
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ public class ReactApp extends SimpleComponent {
|
|||
|
||||
reactAppElem
|
||||
.addAttribute("ccmApplication", primaryUrl);
|
||||
|
||||
reactAppElem
|
||||
.addAttribute("dispatcherPrefix", Web.getWebappContextPath());
|
||||
}
|
||||
|
||||
private String getPrimaryUrl() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import * as React from "react";
|
||||
import { PageModel, PageModelVersion } from "./datatypes";
|
||||
|
||||
export { PageModelEditor };
|
||||
export {
|
||||
PageModelEditor,
|
||||
// PageModelEditorProps,
|
||||
// PageModelEditorState,
|
||||
};
|
||||
|
||||
/**
|
||||
* To render the PageModelEditor create a Typescript file with the following
|
||||
|
|
@ -17,34 +22,154 @@ export { PageModelEditor };
|
|||
* );
|
||||
*/
|
||||
|
||||
class PageModelEditor extends React.Component<{}, {}> {
|
||||
interface PageModelsListProps {
|
||||
|
||||
private getCcmApplication(): string {
|
||||
ccmApplication: string;
|
||||
dispatcherPrefix: string;
|
||||
}
|
||||
|
||||
const dataElem: HTMLElement | null = document
|
||||
.querySelector("#page-models-editor.react-data");
|
||||
interface PageModelsListState {
|
||||
|
||||
if (dataElem === null) {
|
||||
return "???";
|
||||
} else {
|
||||
const value: string | null = dataElem.getAttribute("data-ccm-application");
|
||||
if (value === null) {
|
||||
return "???";
|
||||
} else {
|
||||
return value;
|
||||
errorMsg: string | null;
|
||||
pageModels: PageModel[];
|
||||
}
|
||||
|
||||
class PageModelsList
|
||||
extends React.Component<PageModelsListProps, PageModelsListState> {
|
||||
|
||||
constructor(props: PageModelsListProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
errorMsg: null,
|
||||
pageModels: [],
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
|
||||
const init: RequestInit = {
|
||||
credentials: "same-origin",
|
||||
method: "GET",
|
||||
};
|
||||
|
||||
const url: string = `${this.props.dispatcherPrefix}`
|
||||
+ `/page-models/${this.props.ccmApplication}`;
|
||||
|
||||
fetch(url, init)
|
||||
.then((response: Response) => {
|
||||
if (response.ok) {
|
||||
response
|
||||
.json()
|
||||
.then((pageModels: PageModel[]) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
pageModels,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMsg: `Failed to retrieve PageModels from `
|
||||
+ `${url}: ${error.message}`,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMsg: `Failed to retrieve PageModels from `
|
||||
+ `\"${url}\": HTTP Status Code: `
|
||||
+ `${response.status}; `
|
||||
+ `message: ${response.statusText}`,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
errorMsg: `Failed to retrieve PageModels from `
|
||||
+ `${url}: ${error.message}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
|
||||
return <div className="pageModelsList">
|
||||
{this.state.errorMsg !== null &&
|
||||
<div className="errorPanel">
|
||||
{this.state.errorMsg}
|
||||
</div>
|
||||
}
|
||||
{this.state.pageModels.length > 0 &&
|
||||
<ul>
|
||||
{this.state.pageModels.map((pageModel: PageModel) =>
|
||||
<PageModelListItem pageModel={pageModel} />,
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
interface PageModelListItemProps {
|
||||
pageModel: PageModel;
|
||||
}
|
||||
|
||||
// interface PageModelListItemState {
|
||||
//
|
||||
// }
|
||||
|
||||
class PageModelListItem
|
||||
extends React.Component<PageModelListItemProps, {}> {
|
||||
|
||||
public render() {
|
||||
return <li>
|
||||
<a>
|
||||
{this.props.pageModel.title}
|
||||
</a>
|
||||
</li>;
|
||||
}
|
||||
}
|
||||
|
||||
// interface PageModelEditorProps {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// interface PageModelEditorState {
|
||||
//
|
||||
// }
|
||||
|
||||
class PageModelEditor
|
||||
extends React.Component<{}, {}> {
|
||||
|
||||
public render() {
|
||||
|
||||
return <React.Fragment>
|
||||
<div id="left">
|
||||
<div className="column-head"></div>
|
||||
<div className="column-content">
|
||||
List of available page models placeholder
|
||||
<div className="bebop-left">
|
||||
<div className="bebop-segmented-panel">
|
||||
<div className="bebop-segment">
|
||||
<h3 className="bebop-segment-header">
|
||||
Available PageModels
|
||||
</h3>
|
||||
<div className="bebop-segment-body">
|
||||
<button className="pagemodels addbutton">
|
||||
<span>+</span> Create new PageModel
|
||||
</button>
|
||||
<PageModelsList
|
||||
ccmApplication={this.getCcmApplication()}
|
||||
dispatcherPrefix={this
|
||||
.getDispatcherPrefix()} />
|
||||
<button className="pagemodels addbutton">
|
||||
<span>+</span> Create new PageModel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="right">
|
||||
|
|
@ -59,4 +184,40 @@ class PageModelEditor extends React.Component<{}, {}> {
|
|||
</div>
|
||||
</React.Fragment>;
|
||||
}
|
||||
|
||||
private getDispatcherPrefix(): string {
|
||||
|
||||
const dataElem: HTMLElement | null = document
|
||||
.querySelector("#page-models-editor.react-data");
|
||||
|
||||
if (dataElem === null) {
|
||||
return "";
|
||||
} else {
|
||||
const value: string | null
|
||||
= dataElem.getAttribute("data-dispatcher-prefix");
|
||||
if (value === null) {
|
||||
return "";
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getCcmApplication(): string {
|
||||
|
||||
const dataElem: HTMLElement | null = document
|
||||
.querySelector("#page-models-editor.react-data");
|
||||
|
||||
if (dataElem === null) {
|
||||
return "???";
|
||||
} else {
|
||||
const value: string | null
|
||||
= dataElem.getAttribute("data-ccm-application");
|
||||
if (value === null) {
|
||||
return "???";
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
export { PageModel, PageModelVersion };
|
||||
|
||||
interface PageModel {
|
||||
|
||||
description: string;
|
||||
modelUuid: string;
|
||||
name: string;
|
||||
pageModelId: number;
|
||||
title: string;
|
||||
type: string;
|
||||
uuid: string;
|
||||
version: PageModelVersion;
|
||||
}
|
||||
|
||||
enum PageModelVersion {
|
||||
|
||||
DRAFT,
|
||||
LIVE,
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
|
||||
devtool: "inline-source-map",
|
||||
|
||||
entry: {
|
||||
pagemodeleditor: "./src/main/typescript/ccm-pagemodelseditor/index.tsx"
|
||||
},
|
||||
|
||||
output: {
|
||||
//path: path.resolve(__dirname, "src/main/resources/dist"),
|
||||
path: path.resolve(__dirname, "target/generated-resources/dist"),
|
||||
filename: "ccm-pagemodelseditor.js"
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: [".webpack.js", "web.js", ".ts", ".tsx", ".js"]
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.tsx?$/, loader: "ts-loader"}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
@ -168,7 +168,8 @@
|
|||
<xsl:if test="$data-tree//bebop:reactApp">
|
||||
<div class="react-data"
|
||||
id="{$data-tree//bebop:reactApp/@appId}"
|
||||
data-ccm-application="{$data-tree//bebop:reactApp/@ccmApplication}">
|
||||
data-ccm-application="{$data-tree//bebop:reactApp/@ccmApplication}"
|
||||
data-dispatcher-prefix="{$data-tree//bebop:reactApp/@dispatcherPrefix}">
|
||||
</div>
|
||||
<script src="{$data-tree//bebop:reactApp/@scriptPath}"></script>
|
||||
</xsl:if>
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ div.bebop-segment {
|
|||
}
|
||||
|
||||
#left div.bebop-segment-body {
|
||||
padding-left: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
div.bebop-left div.bebop-panel-row {
|
||||
|
|
@ -1977,3 +1977,36 @@ span#quickLinksCascade {
|
|||
.preformatted-text {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
button.pagemodels.addbutton {
|
||||
|
||||
border: none;
|
||||
border-radius: 0.25em;
|
||||
|
||||
background-color: #383838;
|
||||
|
||||
color: #fff;
|
||||
|
||||
padding: 0.2em 0.33em;
|
||||
}
|
||||
|
||||
button.pagemodels.addbutton > span {
|
||||
|
||||
border-right: 1px solid #eee;
|
||||
|
||||
font-weight: bold;
|
||||
|
||||
padding-right: 0.2em;
|
||||
|
||||
}
|
||||
|
||||
div.pageModelsList {
|
||||
|
||||
margin-top: 0.66em;
|
||||
margin-bottom: 0.66em;
|
||||
border-top: 1px solid #0776A0;
|
||||
padding-top: 0.66em;
|
||||
border-bottom: 1px solid #0776A0;
|
||||
padding-bottom: 0.66em;
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue