add-scidepartment-contenttype #1

Merged
jensp merged 16 commits from add-scidepartment-contenttype into master 2022-10-10 21:01:49 +02:00
87 changed files with 11873 additions and 33 deletions

2
.gitignore vendored
View File

@ -2,9 +2,11 @@
.settings
node
node_modules
/sci-types-department/target/
/sci-types-project/target/
/scientificcms/target/
/sci-publications/nbproject/
/sci-publications/target/
/scicms-bundle-devel-wildfly/target/
/sci-types-project/nbproject/
/sci-types-department/nbproject/

View File

@ -61,6 +61,7 @@
</repositories>
<modules>
<module>sci-types-department</module>
<module>sci-types-project</module>
<module>scientificcms</module>
<module>sci-publications</module>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
{
"name": "sci-types-department",
"version": "7.0.0",
"description": "JavaScript parts of the UI of sci-types-department",
"main": "index.js",
"scripts": {
"build": "npm-run-all build:*",
"build:js": "webpack"
},
"author": "Jens Pelzetter",
"license": "LGPL-3.0-or-later",
"devDependencies": {
"@types/sortablejs": "^1.10.7",
"npm-run-all": "^4.1.5",
"ts-loader": "^9.2.6",
"typescript": "^4.4.3",
"webpack": "^5.55.1",
"webpack-cli": "^4.8.0"
},
"dependencies": {
"sortablejs": "^1.14.0"
},
"targets": {
"main": false
}
}

View File

@ -0,0 +1,357 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
</properties>
<parent>
<groupId>org.scientificcms</groupId>
<artifactId>scientificcms-parent</artifactId>
<version>7.0.0-SNAPSHOT</version>
</parent>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-department</artifactId>
<version>7.0.0-SNAPSHOT</version>
<name>ScientificCMS SciDepartment Content Type</name>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.libreccm</groupId>
<artifactId>ccm-core</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.librecms</groupId>
<artifactId>ccm-cms</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-project</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.libreccm</groupId>
<artifactId>ccm-testutils</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-persistence-dbunit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>sci-types-department</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>./target/generated-resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>${project.build.directory}/generated-resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<optimize>true</optimize>
<debug>true</debug>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<configuration>
<installDirectory>../node</installDirectory>
</configuration>
<executions>
<execution>
<id>Install node.js and NPM</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v16.14.2</nodeVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>--userconfig ../libreccm.npmrc install</arguments>
</configuration>
</execution>
<execution>
<id>build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>org.libreccm.tests.categories.UnitTest</groups>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>de.jpdigital</groupId>
<artifactId>hibernate53-ddl-maven-plugin</artifactId>
<configuration>
<dialects>
<param>h2</param>
<param>oracle12c</param>
<param>postgresql9</param>
</dialects>
<packages>
<param>org.libreccm</param>
<param>org.librecms</param>
<param>org.scientificcms</param>
</packages>
<useEnvers>true</useEnvers>
<persistenceXml>${basedir}/src/main/resources/META-INF/persistence-ddl.xml</persistenceXml>
</configuration>
<executions>
<execution>
<goals>
<goal>gen-ddl</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<detectLinks>true</detectLinks>
<detectJavaApiLinks>true</detectJavaApiLinks>
<links>
<link>http://docs.oracle.com/javase/7/docs/api/</link>
<link>http://docs.oracle.com/javaee/7/api/</link>
<link>http://docs.jboss.org/hibernate/orm/4.3/javadocs/</link>
</links>
<show>private</show>
<docfilessubdirs>true</docfilessubdirs>
<charset>UTF-8</charset>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<breakiterator>true</breakiterator>
<version>true</version>
<author>true</author>
<keywords>true</keywords>
<failOnError>false</failOnError>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<linkXref>true</linkXref>
<sourceEncoding>utf-8</sourceEncoding>
<targetJdk>1.8</targetJdk>
<!-- <rulesets>
<ruleset>/rulesets/java/basic.xml</ruleset>
<ruleset>/rulesets/java/braces.xml</ruleset>
<ruleset>/rulesets/java/clone.xml</ruleset>
<ruleset>/rulesets/java/codesize.xml</ruleset>
<ruleset>/rulesets/java/design.xml</ruleset>
<ruleset>/rulesets/java/empty.xml</ruleset>
<ruleset>/rulesets/java/finalizers.xml</ruleset>
<ruleset>/rulesets/java/imports.xml</ruleset>
<ruleset>/rulesets/java/junit.xml</ruleset>
<ruleset>/rulesets/java/naming.xml</ruleset>
<ruleset>/rulesets/java/optimizations.xml</ruleset>
<ruleset>/rulesets/java/strictexception.xml</ruleset>
<ruleset>/rulesets/java/strings.xml</ruleset>
<ruleset>/rulesets/java/sunsecure.xml</ruleset>
<ruleset>/rulesets/java/typeresolution.xml</ruleset>
<ruleset>/rulesets/java/unnecessary.xml</ruleset>
<ruleset>/rulesets/java/unusedcode.xml</ruleset>
</rulesets>-->
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>javancss-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<reportSets>
<reportSet>
<reports>
<report>dependencies</report>
<report>licenses</report>
</reports>
</reportSet>
</reportSets>
<configuration>
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,194 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited;
import org.libreccm.core.CcmObjects;
import org.librecms.assets.ContactableEntity;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity(name = "DepartmentContact")
@Audited
@Table(name = "DEPARTMENT_CONTACTS", schema = DB_SCHEMA)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid"
)
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "CONTACT_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long contactId;
@Column(name = "CONTACT_TYPE", length = 255, nullable = true)
private String contactType;
@Column(name = "CONTACT_ORDER")
private long order;
@ManyToOne
@JoinColumn(name = "DEPARTMENT_ID")
@JsonIdentityReference(alwaysAsId = true)
private SciDepartment department;
@ManyToOne
@JoinColumn(name = "CONTACTABLE_ID")
@JsonIdentityReference(alwaysAsId = true)
private ContactableEntity contactable;
public long getContactId() {
return contactId;
}
protected void setContactId(final long contactId) {
this.contactId = contactId;
}
public String getContactType() {
return contactType;
}
public void setContactType(final String contactType) {
this.contactType = contactType;
}
public long getOrder() {
return order;
}
public void setOrder(final long order) {
this.order = order;
}
public SciDepartment getDepartment() {
return department;
}
protected void setDepartment(final SciDepartment department) {
this.department = department;
}
public ContactableEntity getContactable() {
return contactable;
}
protected void setContactable(final ContactableEntity contactable) {
this.contactable = contactable;
}
@Override
public int hashCode() {
int hash = 7;
hash = 41 * hash + (int) (contactId ^ (contactId >>> 32));
hash = 41 * hash + Objects.hashCode(contactType);
hash = 41 * hash + (int) (order ^ (order >>> 32));
hash = 41 * hash + CcmObjects.hashCodeUsingUuid(department);
hash = 41 * hash + CcmObjects.hashCodeUsingUuid(contactable);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Contact)) {
return false;
}
final Contact other = (Contact) obj;
if (!other.canEqual(this)) {
return false;
}
if (contactId != other.getContactId()) {
return false;
}
if (!Objects.equals(contactType, other.getContactType())) {
return false;
}
if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
return false;
}
if (!CcmObjects.equalsUsingUuid(contactable, other.getContactable())) {
return false;
}
return order == other.getOrder();
}
public boolean canEqual(final Object obj) {
return obj instanceof Contact;
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format(
"%s{ "
+ "contactId = %d, "
+ "contactType = \"%s\", "
+ "order = %d, "
+ "project = { %s } "
+ "contactableUuid = %s%s"
+ " }",
super.toString(),
contactId,
contactType,
order,
Optional
.ofNullable(department)
.map(
dep -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
dep.getObjectId(),
dep.getUuid(),
dep.getDisplayName()
)
)
.orElse(""),
Optional
.ofNullable(contactable)
.map(
entity -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
entity.getObjectId(),
entity.getUuid(),
entity.getDisplayName()
)
)
.orElse(""),
data
);
}
}

View File

@ -0,0 +1,42 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class ContactRepository
extends AbstractAuditedEntityRepository<Long, Contact> {
private static final long serialVersionUID = 1L;
@Override
public Long getEntityId(final Contact contact) {
return contact.getContactId();
}
@Override
public Class<Contact> getEntityClass() {
return Contact.class;
}
@Override
public String getIdAttributeName() {
return "contactId";
}
@Override
public Long getIdOfEntity(final Contact contact) {
return contact.getContactId();
}
@Override
public boolean isNew(final Contact contact) {
return contact.getContactId() == 0;
}
}

View File

@ -0,0 +1,157 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import org.hibernate.envers.Audited;
import org.libreccm.core.CcmObjects;
import org.scientificcms.contenttypes.sciproject.SciProject;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Audited
@Table(name = "DEPARTMENT_PROJECTS", schema = DB_SCHEMA)
public class DepartmentProject implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "DEPARTMENT_PROJECT_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long departmentProjectId;
@ManyToOne
@JoinColumn(name = "DEPARTMENT_ID")
@JsonIdentityReference(alwaysAsId = true)
private SciDepartment department;
@ManyToOne
@JoinColumn(name = "PROJECT_ID")
@JsonIdentityReference(alwaysAsId = true)
private SciProject project;
public long getDepartmentProjectId() {
return departmentProjectId;
}
protected void setDepartmentProjectId(final long departmentProjectId) {
this.departmentProjectId = departmentProjectId;
}
public SciDepartment getDepartment() {
return department;
}
protected void setDepartment(final SciDepartment department) {
this.department = department;
}
public SciProject getProject() {
return project;
}
protected void setProject(final SciProject project) {
this.project = project;
}
@Override
public int hashCode() {
int hash = 7;
hash
= 59 * hash + (int) (departmentProjectId ^ (departmentProjectId
>>> 32));
hash = 59 * hash + CcmObjects.hashCodeUsingUuid(department);
hash = 59 * hash + CcmObjects.hashCodeUsingUuid(project);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof DepartmentProject)) {
return false;
}
final DepartmentProject other = (DepartmentProject) obj;
if (!other.canEqual(this)) {
return false;
}
if (departmentProjectId != other.getDepartmentProjectId()) {
return false;
}
if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
return false;
}
return CcmObjects.equalsUsingUuid(project, other.getProject());
}
public boolean canEqual(final Object obj) {
return obj instanceof DepartmentProject;
}
@Override
public String toString() {
return toString("");
}
public String toString(final String data) {
return String.format(
"%s{ "
+ "departmentProjectId = %d, "
+ "department = { %s }, "
+ "project = { %s}%s"
+ " }",
super.toString(),
departmentProjectId,
Optional
.ofNullable(department)
.map(
dep -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
dep.getObjectId(),
dep.getUuid(),
dep.getDisplayName()
)
)
.orElse(""),
Optional
.ofNullable(project)
.map(
proj -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
project.getObjectId(),
project.getUuid(),
project.getDisplayName()
)
)
.orElse(""),
data
);
}
}

View File

@ -0,0 +1,42 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class DepartmentProjectRepository
extends AbstractAuditedEntityRepository<Long, DepartmentProject> {
private static final long serialVersionUID = 1L;
@Override
public Long getEntityId(final DepartmentProject project) {
return project.getDepartmentProjectId();
}
@Override
public Class<DepartmentProject> getEntityClass() {
return DepartmentProject.class;
}
@Override
public String getIdAttributeName() {
return "departmentProjectId";
}
@Override
public Long getIdOfEntity(final DepartmentProject project) {
return project.getDepartmentProjectId();
}
@Override
public boolean isNew(final DepartmentProject project) {
return project.getDepartmentProjectId() == 0;
}
}

View File

@ -0,0 +1,185 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import org.hibernate.envers.Audited;
import org.libreccm.core.CcmObjects;
import org.libreccm.l10n.LocalizedString;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.AssociationOverride;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Audited
@Table(name = "DEPARTMENT_TEXTS", schema = DB_SCHEMA)
public class DepartmentText implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "TEXT_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long textId;
@Column(name = "key", length = 255, nullable = false)
private String key;
@Column(name = "CONTACT_ORDER")
private long order;
@ManyToOne
@JoinColumn(name = "DEPARTMENT_ID")
@JsonIdentityReference(alwaysAsId = true)
private SciDepartment department;
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(
name = "DEPARTMENT_TEXT_VALUES",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")
}
)
)
private LocalizedString text;
public long getTextId() {
return textId;
}
protected void setTextId(final long textId) {
this.textId = textId;
}
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
public long getOrder() {
return order;
}
public void setOrder(final long order) {
this.order = order;
}
public SciDepartment getDepartment() {
return department;
}
public void setDepartment(final SciDepartment department) {
this.department = department;
}
public LocalizedString getText() {
return text;
}
public void setText(final LocalizedString text) {
this.text = text;
}
@Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + (int) (textId ^ (textId >>> 32));
hash = 67 * hash + Objects.hashCode(key);
hash = 67 * hash + (int) (order ^ (order >>> 32));
hash = 67 * hash + CcmObjects.hashCodeUsingUuid(department);
hash = 67 * hash + Objects.hashCode(text);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof DepartmentText)) {
return false;
}
final DepartmentText other = (DepartmentText) obj;
if (!other.canEqual(this)) {
return false;
}
if (textId != other.getTextId()) {
return false;
}
if (order != other.getOrder()) {
return false;
}
if (!Objects.equals(key, other.getKey())) {
return false;
}
if (!Objects.equals(department, other.getDepartment())) {
return false;
}
return Objects.equals(text, other.getText());
}
public boolean canEqual(final Object obj) {
return obj instanceof DepartmentText;
}
@Override
public String toString() {
return toString("");
}
public String toString(final String data) {
return String.format(
"textId = %d, "
+ "key = %s, "
+ "order = %d, "
+ "department = { %s }, "
+ "text = { %s }%s",
textId,
key,
order,
Optional
.ofNullable(department)
.map(
dep -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
dep.getObjectId(),
dep.getUuid(),
dep.getDisplayName()
)
)
.orElse(""),
Objects.toString(text),
data
);
}
}

View File

@ -0,0 +1,40 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class DepartmentTextRepository
extends AbstractAuditedEntityRepository<Long, DepartmentText> {
@Override
public Long getEntityId(final DepartmentText text) {
return text.getTextId();
}
@Override
public Class<DepartmentText> getEntityClass() {
return DepartmentText.class;
}
@Override
public String getIdAttributeName() {
return "textId";
}
@Override
public Long getIdOfEntity(final DepartmentText text) {
return text.getTextId();
}
@Override
public boolean isNew(final DepartmentText text) {
return text.getTextId() == 0;
}
}

View File

@ -0,0 +1,207 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited;
import org.libreccm.core.CcmObjects;
import org.librecms.assets.Person;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity(name = "DepartmentMembership")
@Audited
@Table(name = "DEPARTMENT_MEMBERSHIPS", schema = DB_SCHEMA)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid"
)
public class Membership implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "MEMBERSHIP_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long membershipId;
@Column(name = "MEMBER_ROLE", length = 255, nullable = true)
private String role;
@Column(name = "STATUS")
@Enumerated(EnumType.STRING)
private MembershipStatus status;
@ManyToOne
@JoinColumn(name = "DEPARTMENT_ID")
@JsonIdentityReference(alwaysAsId = true)
private SciDepartment department;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
@JsonIdentityReference(alwaysAsId = true)
private Person member;
public long getMembershipId() {
return membershipId;
}
protected void setMembershipId(final long membershipId) {
this.membershipId = membershipId;
}
public String getRole() {
return role;
}
public void setRole(final String role) {
this.role = role;
}
public MembershipStatus getStatus() {
return status;
}
public void setStatus(final MembershipStatus status) {
this.status = status;
}
public SciDepartment getDepartment() {
return department;
}
protected void setDepartment(final SciDepartment department) {
this.department = department;
}
public Person getMember() {
return member;
}
protected void setMember(final Person member) {
this.member = member;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash
+ (int) (membershipId ^ (membershipId >>> 32));
hash = 37 * hash + Objects.hashCode(role);
hash = 37 * hash + Objects.hashCode(status);
hash = 37 * hash + CcmObjects.hashCodeUsingUuid(department);
hash = 37 * hash + CcmObjects.hashCodeUsingUuid(member);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Membership)) {
return false;
}
final Membership other = (Membership) obj;
if (!other.canEqual(this)) {
return false;
}
if (membershipId != other.getMembershipId()) {
return false;
}
if (!Objects.equals(role, other.getRole())) {
return false;
}
if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
return false;
}
if (!CcmObjects.equalsUsingUuid(member, other.getMember())) {
return false;
}
return status == other.getStatus();
}
public boolean canEqual(final Object obj) {
return obj instanceof Membership;
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format(
"%s{ "
+ "membershipId = %d, "
+ "role = \"%s\", "
+ "status = \"%s\","
+ "project = { %s }, "
+ "member = { %s }%s"
+ " }",
super.toString(),
membershipId,
role,
Objects.toString(status),
Optional
.ofNullable(department)
.map(
dep -> String.format(
"objectId = %d,"
+ "uuid = \"%s\", "
+ "name = \"%s\"",
dep.getObjectId(),
dep.getUuid(),
dep.getDisplayName()
)
)
.orElse(""),
Optional
.ofNullable(member)
.map(
person -> String.format(
"objectId = %d, "
+ "uuid = \"%s\", "
+ "name = \"%s\", "
+ "surname = \"%s\", "
+ "givenName = \"%s\", "
+ "prefix = \"%s\", "
+ "suffix = \"%s\"",
person.getObjectId(),
person.getUuid(),
person.getDisplayName(),
person.getPersonName().getSurname(),
person.getPersonName().getGivenName(),
person.getPersonName().getPrefix(),
person.getPersonName().getSuffix())
)
.orElse(""),
data
);
}
}

View File

@ -0,0 +1,40 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class MembershipRepository
extends AbstractAuditedEntityRepository<Long, Membership> {
@Override
public Long getEntityId(final Membership membership) {
return membership.getMembershipId();
}
@Override
public Class<Membership> getEntityClass() {
return Membership.class;
}
@Override
public String getIdAttributeName() {
return "membershipId";
}
@Override
public Long getIdOfEntity(final Membership membership) {
return membership.getMembershipId();
}
@Override
public boolean isNew(final Membership membership) {
return membership.getMembershipId() == 0;
}
}

View File

@ -0,0 +1,13 @@
package org.scientificcms.contenttypes.scidepartment;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public enum MembershipStatus {
ACTIVE,
ASSOCIATED,
FORMER,
}

View File

@ -0,0 +1,308 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited;
import org.libreccm.l10n.LocalizedString;
import org.librecms.contentsection.ContentItem;
import org.librecms.contenttypes.ContentTypeDescription;
import org.librecms.ui.contentsections.documents.MvcAuthoringKit;
import org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentCreateStep;
import org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentDescriptionStep;
import org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentPropertiesStep;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.persistence.AssociationOverride;
import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Audited
@Table(name = "DEPARTMENTS", schema = DB_SCHEMA)
@ContentTypeDescription(
labelBundle = "org.scientificcms.contenttypes.SciDepartment",
descriptionBundle = "org.scientificcms.contenttypes.SciDepartment"
)
@MvcAuthoringKit(
createStep = SciDepartmentCreateStep.class,
authoringSteps = {
SciDepartmentPropertiesStep.class,
SciDepartmentDescriptionStep.class
}
)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = SciDepartmentIdResolver.class,
property = "uuid"
)
public class SciDepartment extends ContentItem implements Serializable {
private static final long serialVersionUID = 1L;
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(
name = "DEPARTMENT_SHORT_DESCS",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")
}
)
)
private LocalizedString shortDescription;
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(
name = "DEPARTMENT_DESCS",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")
}
)
)
private LocalizedString departmentDescription;
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(
name = "DEPARTMENT_ADDENDUM",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")
}
)
)
private LocalizedString addendum;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
@OrderBy("order ASC")
@JsonIgnore
private Map<String, DepartmentText> additionalTexts;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
@OrderBy("order ASC")
@JsonIgnore
private List<Contact> contacts;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
@OrderBy("member ASC")
@JsonIgnore
private List<Membership> members;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
@OrderBy("project ASC")
@JsonIgnore
private List<DepartmentProject> projects;
public SciDepartment() {
super();
shortDescription = new LocalizedString();
departmentDescription = new LocalizedString();
addendum = new LocalizedString();
additionalTexts = new HashMap<>();
contacts = new ArrayList<>();
members = new ArrayList<>();
projects = new ArrayList<>();
}
public LocalizedString getShortDescription() {
return shortDescription;
}
public void setShortDescription(final LocalizedString shortDescription) {
this.shortDescription = shortDescription;
}
public LocalizedString getDepartmentDescription() {
return departmentDescription;
}
public void setDepartmentDescription(
final LocalizedString departmentDescription
) {
this.departmentDescription = departmentDescription;
}
public LocalizedString getAddendum() {
return addendum;
}
public void setAddendum(final LocalizedString addendum) {
this.addendum = addendum;
}
public Map<String, DepartmentText> getAdditionalTexts() {
return Collections.unmodifiableMap(additionalTexts);
}
protected void putAdditionalText(
final String key, final DepartmentText text
) {
additionalTexts.put(key, text);
}
protected void removeAdditionalText(final String key) {
additionalTexts.remove(key);
}
protected void setAdditionalTexts(
final Map<String, DepartmentText> additionalTexts
) {
this.additionalTexts = new HashMap<>(additionalTexts);
}
public List<Contact> getContacts() {
return Collections.unmodifiableList(contacts);
}
protected void addContact(final Contact contact) {
contacts.add(contact);
}
protected void removeContact(final Contact contact) {
contacts.remove(contact);
}
protected void setContacts(final List<Contact> contacts) {
this.contacts = new ArrayList<>(contacts);
}
public List<Membership> getMembers() {
return Collections.unmodifiableList(members);
}
protected void addMember(final Membership member) {
members.add(member);
}
protected void removeMember(final Membership member) {
members.remove(member);
}
protected void setMembers(final List<Membership> members) {
this.members = new ArrayList<>(members);
}
public List<DepartmentProject> getProjects() {
return Collections.unmodifiableList(projects);
}
protected void addProject(final DepartmentProject project) {
projects.add(project);
}
protected void removeProject(final DepartmentProject project) {
projects.remove(project);
}
protected void setProjects(final List<DepartmentProject> projects) {
this.projects = new ArrayList<>(projects);
}
@Override
public int hashCode() {
int hash = 3;
hash = 83 * hash + Objects.hashCode(shortDescription);
hash = 83 * hash + Objects.hashCode(departmentDescription);
hash = 83 * hash + Objects.hashCode(addendum);
hash = 83 * hash + Objects.hashCode(additionalTexts);
hash = 83 * hash + Objects.hashCode(contacts);
hash = 83 * hash + Objects.hashCode(members);
hash = 83 * hash + Objects.hashCode(projects);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof SciDepartment)) {
return false;
}
final SciDepartment other = (SciDepartment) obj;
if (!other.canEqual(this)) {
return false;
}
if (!Objects.equals(shortDescription, other.getShortDescription())) {
return false;
}
if (!Objects.equals(
departmentDescription,
other.getDepartmentDescription()
)) {
return false;
}
if (!Objects.equals(addendum, other.getAddendum())) {
return false;
}
if (!Objects.equals(additionalTexts, other.getAdditionalTexts())) {
return false;
}
if (!Objects.equals(contacts, other.getContacts())) {
return false;
}
if (!Objects.equals(members, other.getMembers())) {
return false;
}
return Objects.equals(projects, other.getProjects());
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof SciDepartment;
}
@Override
public String toString(final String data) {
return super.toString(
String.format(
"shortDescription = %s, "
+ "departmentDescription = %s, "
+ "addendum = %s, "
+ "additionalTexts = %s, "
+ "contacts = %s, "
+ "members = %s, "
+ "projects = %s%s",
Objects.toString(shortDescription),
Objects.toString(departmentDescription),
Objects.toString(addendum),
Objects.toString(additionalTexts),
Objects.toString(contacts),
Objects.toString(members),
Objects.toString(projects),
data
)
);
}
}

View File

@ -0,0 +1,63 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.Configuration;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.Setting;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Configuration
public class SciDepartmentConfig {
@Setting
private String contactTypesBundleName
= "org.scientificcms.contenttypes.scidepartment.DefaultContactTypes";
@Setting
private String memberRolesBundleName
= "org.scientificcms.contenttypes.scidepartment.DefaultMemberRoles";
@Setting
private String textKeysBundleName
= "org.scientificcms.contenttypes.scidepartment.DefaultTextKeys";
public static SciDepartmentConfig getConfig() {
final ConfigurationManager confManager = CdiUtil
.createCdiUtil()
.findBean(ConfigurationManager.class);
return confManager.findConfiguration(SciDepartmentConfig.class);
}
public SciDepartmentConfig() {
super();
}
public String getContactTypesBundleName() {
return contactTypesBundleName;
}
public void setContactTypesBundleName(final String contactTypesBundleName) {
this.contactTypesBundleName = contactTypesBundleName;
}
public String getMemberRolesBundleName() {
return memberRolesBundleName;
}
public void setMemberRolesBundleName(final String memberRolesBundleName) {
this.memberRolesBundleName = memberRolesBundleName;
}
public String getTextKeysBundleName() {
return textKeysBundleName;
}
public void setTextKeysBundleName(final String textKeysBundleName) {
this.textKeysBundleName = textKeysBundleName;
}
}

View File

@ -0,0 +1,18 @@
package org.scientificcms.contenttypes.scidepartment;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class SciDepartmentConstants {
public static final String DB_SCHEMA = "SCI_TYPES_DEPARTMENT";
public static final String SCI_PROJECT_BUNDLE
= "org.scientificcms.contenttypes.SciDepartmentResources";
private SciDepartmentConstants() {
// Nothing
}
}

View File

@ -0,0 +1,57 @@
package org.scientificcms.contenttypes.scidepartment;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.ContentItemRepository;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class SciDepartmentIdResolver implements Serializable, ObjectIdResolver {
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey idKey,
final Object object
) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(ContentItemRepository.class)
.findByUuid(id.key.toString(), SciDepartment.class)
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No SciDepartment with UUID %s found in the datbase.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new SciDepartmentIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof SciDepartmentIdResolver;
}
}

View File

@ -0,0 +1,22 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.imexport.Processes;
import org.librecms.contentsection.AbstractContentItemImExporter;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Processes(SciDepartment.class)
public class SciDepartmentImExporter
extends AbstractContentItemImExporter<SciDepartment>{
@Override
public Class<SciDepartment> getEntityClass() {
return SciDepartment.class;
}
}

View File

@ -0,0 +1,293 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.l10n.LocalizedString;
import org.librecms.assets.ContactableEntity;
import org.librecms.assets.Person;
import org.librecms.contentsection.ContentItemRepository;
import org.scientificcms.contenttypes.sciproject.SciProject;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class SciDepartmentManager implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private ContactRepository contactRepo;
@Inject
private ContentItemRepository itemRepo;
@Inject
private DepartmentProjectRepository departmentProjectRepo;
@Inject
private DepartmentTextRepository departmentTextRepo;
@Inject
private MembershipRepository membershipRepo;
@Transactional(Transactional.TxType.REQUIRED)
public void addText(
final LocalizedString text,
final SciDepartment toDepartment,
final String withKey
) {
Objects.requireNonNull(
toDepartment,
"Can't add a text to department null"
);
Objects.requireNonNull(text, "Can't add null as text.");
Objects.requireNonNull(
withKey,
"Can't add a text to a department with key null."
);
if (withKey.isBlank()) {
throw new IllegalArgumentException(
"Can't add a text to a department using a blank key."
);
}
final DepartmentText departmentText = new DepartmentText();
departmentText.setDepartment(toDepartment);
departmentText.setKey(withKey);
departmentText.setOrder(toDepartment.getAdditionalTexts().size());
departmentText.setText(text);
toDepartment.putAdditionalText(withKey, departmentText);
departmentTextRepo.save(departmentText);
itemRepo.save(toDepartment);
}
@Transactional(Transactional.TxType.REQUIRED)
public void removeText(
final SciDepartment fromDepartment,
final String withKey
) {
Objects.requireNonNull(
fromDepartment,
"Can't remove a text from department null."
);
if (fromDepartment.getAdditionalTexts().containsKey(withKey)) {
final DepartmentText removed = fromDepartment
.getAdditionalTexts()
.get(withKey);
fromDepartment.removeAdditionalText(withKey);
itemRepo.save(fromDepartment);
departmentTextRepo.delete(removed);
}
}
@Transactional(Transactional.TxType.REQUIRED)
public void addContact(
final ContactableEntity contactable,
final SciDepartment toDepartment,
final String withType
) {
Objects.requireNonNull(
contactable,
"Can't add null as Contact to a SciDepartment."
);
Objects.requireNonNull(
toDepartment,
"Can't add a Contact to a department null."
);
final Contact contact = new Contact();
contact.setContactable(contactable);
contact.setDepartment(toDepartment);
contact.setContactType(withType);
contact.setOrder(toDepartment.getContacts().size());
toDepartment.addContact(contact);
contactRepo.save(contact);
itemRepo.save(toDepartment);
}
@Transactional(Transactional.TxType.REQUIRED)
public void removeContact(
final ContactableEntity contactable,
final SciDepartment fromDepartment
) {
Objects.requireNonNull(
contactable,
"Can't remove null as Contact from a SciDepartment."
);
Objects.requireNonNull(
fromDepartment,
"Can't remove a Contact from department null."
);
final Optional<Contact> result = fromDepartment
.getContacts()
.stream()
.filter(
contact -> filterContact(contact, contactable, fromDepartment)
)
.findFirst();
if (result.isPresent()) {
final Contact removed = result.get();
fromDepartment.removeContact(removed);
itemRepo.save(fromDepartment);
contactRepo.delete(removed);
}
}
@Transactional(Transactional.TxType.REQUIRED)
public void addMember(
final Person person,
final SciDepartment toDepartment,
final String withRole,
final MembershipStatus withStatus
) {
Objects.requireNonNull(
person,
"Can't add null as a member null to a SciDepartment."
);
Objects.requireNonNull(
toDepartment,
"Can't a member to a SciDepartment null."
);
final Membership membership = new Membership();
membership.setDepartment(toDepartment);
membership.setMember(person);
membership.setRole(withRole);
membership.setStatus(withStatus);
toDepartment.addMember(membership);
membershipRepo.save(membership);
itemRepo.save(toDepartment);
}
@Transactional(Transactional.TxType.REQUIRED)
public void removeMember(
final Person person,
final SciDepartment fromDepartment
) {
Objects.requireNonNull(
person,
"Can't remove null as a member from a SciDepartment."
);
Objects.requireNonNull(
fromDepartment,
"Can't remove a member from a SciDepartment null."
);
final Optional<Membership> result = fromDepartment
.getMembers()
.stream()
.filter(
membership -> filterMembership(
membership,
person,
fromDepartment
)
)
.findFirst();
if (result.isPresent()) {
final Membership removed = result.get();
fromDepartment.removeMember(removed);
itemRepo.save(fromDepartment);
membershipRepo.delete(removed);
}
}
@Transactional(Transactional.TxType.REQUIRED)
public void addProject(
final SciProject project,
final SciDepartment toDepartment
) {
Objects.requireNonNull(
project,
"Can't add null as a project null to a SciDepartment."
);
Objects.requireNonNull(
toDepartment,
"Can't a project to a SciDepartment null."
);
final DepartmentProject departmentProject =new DepartmentProject();
departmentProject.setDepartment(toDepartment);
departmentProject.setProject(project);
toDepartment.addProject(departmentProject);
departmentProjectRepo.save(departmentProject);
itemRepo.save(project);
}
@Transactional(Transactional.TxType.REQUIRED)
public void removeProject(
final SciProject project,
final SciDepartment fromDepartment
) {
Objects.requireNonNull(
project,
"Can't remove null as a project from a SciDepartment."
);
Objects.requireNonNull(
fromDepartment,
"Can't remove a project from a SciDepartment null."
);
final Optional<DepartmentProject> result = fromDepartment
.getProjects()
.stream()
.filter(
departmentProject -> filterDepartmentProject(
departmentProject, project, fromDepartment
)
)
.findFirst();
if (result.isPresent()) {
final DepartmentProject removed = result.get();
fromDepartment.removeProject(removed);
itemRepo.save(fromDepartment);
departmentProjectRepo.delete(removed);
}
}
private boolean filterContact(
final Contact contact,
final ContactableEntity byContactable,
final SciDepartment byDepartment
) {
return contact.getContactable().equals(byContactable)
&& contact.getDepartment().equals(byDepartment);
}
private boolean filterMembership(
final Membership membership,
final Person byPerson,
final SciDepartment byDepartment
) {
return membership.getMember().equals(byPerson)
&& membership.getDepartment().equals(byDepartment);
}
private boolean filterDepartmentProject(
final DepartmentProject departmentProject,
final SciProject byProject,
final SciDepartment byDepartment
) {
return departmentProject.getProject().equals(byProject)
&& departmentProject.getDepartment().equals(byDepartment);
}
}

View File

@ -0,0 +1,46 @@
package org.scientificcms.contenttypes.scidepartment;
import org.libreccm.modules.CcmModule;
import org.libreccm.modules.InitEvent;
import org.libreccm.modules.InstallEvent;
import org.libreccm.modules.RequiredModule;
import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
import org.librecms.contenttypes.ContentTypes;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@org.libreccm.modules.Module(
requiredModules = {
@RequiredModule(module = org.libreccm.core.CcmCore.class),
@RequiredModule(module = org.librecms.Cms.class)
}
)
@ContentTypes({
SciDepartment.class
})
public class SciDepartmentModule implements CcmModule {
@Override
public void install(final InstallEvent event) {
//ToDo Create initial data for the module if neccessary
}
@Override
public void init(final InitEvent event) {
//ToDo Add initialisation logic necessary for your module
}
@Override
public void shutdown(final ShutdownEvent event) {
//ToDo Add shutdown logic if necessary
}
@Override
public void uninstall(final UnInstallEvent event) {
//ToDo Remove module data
}
}

View File

@ -0,0 +1,36 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ApplicationScoped
public class SciDepartmentAuthoringSteps implements MvcAuthoringSteps {
@Override
public Set<Class<?>> getClasses() {
return Set.of(
SciDepartmentPropertiesStep.class,
SciDepartmentDescriptionStep.class
);
}
@Override
public Set<Class<?>> getResourceClasses() {
return Set.of(
SciDepartmentDescriptionContacts.class,
SciDepartmentDescriptionStepResources.class,
SciDepartmentDescriptionStepService.class,
SciDepartmentTextsResources.class
);
}
}

View File

@ -0,0 +1,67 @@
package org.scientificcms.contenttypes.scidepartment.ui;
/**
* DTO providing the information about a {@link Contact} of a
* {@link SciDepartment} in a form that is easy to use from a MVC template.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SciDepartmentContact {
/**
* The ID of the {@link Contact} represented by this object.
*/
private long contactId;
/**
* The type of the contact.
*
* @see Contact#contactType
*/
private String contactType;
/**
* Order of contact.
*/
private long order;
/**
* The title of the {@link ContactableEntity}
*
* @see Contact#contactable
*/
private String contactable;
public long getContactId() {
return contactId;
}
public void setContactId(final long contactId) {
this.contactId = contactId;
}
public String getContactType() {
return contactType;
}
public void setContactType(final String contactType) {
this.contactType = contactType;
}
public long getOrder() {
return order;
}
public void setOrder(final long order) {
this.order = order;
}
public String getContactable() {
return contactable;
}
public void setContactable(final String contactable) {
this.contactable = contactable;
}
}

View File

@ -0,0 +1,67 @@
package org.scientificcms.contenttypes.scidepartment.ui;
/**
* DTO providing the information about a {@link Contact} of a
* {@link SciDepartment} in a form that is easy usable from a MVC template.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SciDepartmentContactModel {
/**
* The ID of the {@link Contact} represented by this object.
*/
private long contactId;
/**
* The type of the contact.
*
* @see Contact#contactType
*/
private String contactType;
/**
* Order of contact.
*/
private long order;
/**
* The title of the {@link ContactableEntity}
*
* @see Contact#contactable
*/
private String contactable;
public long getContactId() {
return contactId;
}
public void setContactId(final long contactId) {
this.contactId = contactId;
}
public String getContactType() {
return contactType;
}
public void setContactType(final String contactType) {
this.contactType = contactType;
}
public long getOrder() {
return order;
}
public void setOrder(final long order) {
this.order = order;
}
public String getContactable() {
return contactable;
}
public void setContactable(final String contactable) {
this.contactable = contactable;
}
}

View File

@ -0,0 +1,29 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.ui.AbstractMessagesBean;
import org.scientificcms.contenttypes.scidepartment.SciDepartmentConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentContactTypes")
public class SciDepartmentContactTypes extends AbstractMessagesBean {
@Inject
private ConfigurationManager confManager;
@Override
protected String getMessageBundle() {
return confManager
.findConfiguration(SciDepartmentConfig.class)
.getContactTypesBundleName();
}
}

View File

@ -0,0 +1,266 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.workflow.Workflow;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.ui.contentsections.documents.AbstractMvcDocumentCreateStep;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.transaction.Transactional;
/**
* Create step for a {@link SciDepartment}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentCreateStep")
public class SciDepartmentCreateStep
extends AbstractMvcDocumentCreateStep<SciDepartment> {
private static final String FORM_PARAM_NAME = "name";
private static final String FORM_PARAM_TITLE = "title";
private static final String FORM_PARAM_SHORT_DESCRIPTION = "shortdesc";
private static final String FORM_PARAM_INITIAL_LOCALE = "locale";
private static final String FORM_PARAM_SELECTED_WORKFLOW = "workflow";
/**
* Provides functions for working with content items.
*/
@Inject
private ContentItemManager itemManager;
/**
* Used to save the event.
*/
@Inject
private ContentItemRepository itemRepo;
/**
* Provides functions for working with {@link LocalizedString}s.
*/
@Inject
private GlobalizationHelper globalizationHelper;
/**
* Nmae of the department.
*/
private String name;
/**
* Title of the department.
*/
private String title;
/**
* The short description of the department.
*/
private String shortDescription;
/**
* The initial locale of the department.
*/
private String initialLocale;
/**
* The workflow to use for the new department.
*/
private String selectedWorkflow;
@Override
public String getDocumentType() {
return SciDepartment.class.getName();
}
@Override
public String getDescription() {
return globalizationHelper
.getLocalizedTextsUtil(getBundle())
.getText("createstep.description");
}
@Override
public String getBundle() {
return SciDepartmentStepsConstants.BUNDLE;
}
public String getName() {
return name;
}
public String getTitle() {
return title;
}
public String getShortDescription() {
return shortDescription;
}
public String getInitialLocale() {
return initialLocale;
}
@Transactional(Transactional.TxType.REQUIRED)
public String getSelectedWorkflow() {
if (selectedWorkflow == null || selectedWorkflow.isEmpty()) {
return getContentSection()
.getContentTypes()
.stream()
.filter(
type -> type.getContentItemClass().equals(
SciDepartment.class.getName()
)
)
.findAny()
.map(type -> type.getDefaultWorkflow())
.map(
workflow -> globalizationHelper.getValueFromLocalizedString(
workflow.getName()
)
)
.orElse("");
} else {
return selectedWorkflow;
}
}
@Override
public String showCreateStep() {
return "org/scientificcms/contenttypes/scidepartment/ui/create-scidepartment.xhtml";
}
@Override
public String createItem(final Map<String, String[]> formParams) {
if (!formParams.containsKey(FORM_PARAM_NAME)
|| formParams.get(FORM_PARAM_NAME) == null
|| formParams.get(FORM_PARAM_NAME).length == 0) {
addMessage(
"danger",
globalizationHelper
.getLocalizedTextsUtil(getBundle())
.getText("createstep.name.error.missing")
);
return showCreateStep();
}
name = formParams.get(FORM_PARAM_NAME)[0];
if (!name.matches("^([a-zA-Z0-9_-]*)$")) {
addMessage(
"danger",
globalizationHelper
.getLocalizedTextsUtil(getBundle())
.getText("createstep.name.error.invalid")
);
return showCreateStep();
}
if (!formParams.containsKey(FORM_PARAM_TITLE)
|| formParams.get(FORM_PARAM_TITLE) == null
|| formParams.get(FORM_PARAM_TITLE).length == 0) {
addMessage(
"danger",
globalizationHelper
.getLocalizedTextsUtil(getBundle())
.getText("createstep.title.error.missing")
);
return showCreateStep();
}
title = formParams.get(FORM_PARAM_TITLE)[0];
if (!formParams.containsKey(FORM_PARAM_SHORT_DESCRIPTION)
|| formParams.get(FORM_PARAM_SHORT_DESCRIPTION) == null
|| formParams.get(FORM_PARAM_SHORT_DESCRIPTION).length == 0) {
addMessage(
"danger",
globalizationHelper
.getLocalizedTextsUtil(getBundle())
.getText("createstep.summary.error.missing")
);
return showCreateStep();
}
shortDescription = formParams.get(FORM_PARAM_SHORT_DESCRIPTION)[0];
if (!formParams.containsKey(FORM_PARAM_INITIAL_LOCALE)
|| formParams.get(FORM_PARAM_INITIAL_LOCALE) == null
|| formParams.get(FORM_PARAM_INITIAL_LOCALE).length == 0) {
addMessage(
"danger",
globalizationHelper.getLocalizedTextsUtil(
getBundle()
).getText("createstep.initial_locale.error.missing")
);
return showCreateStep();
}
final Locale locale = new Locale(
formParams.get(FORM_PARAM_INITIAL_LOCALE)[0]
);
if (!formParams.containsKey(FORM_PARAM_SELECTED_WORKFLOW)
|| formParams.get(FORM_PARAM_SELECTED_WORKFLOW) == null
|| formParams.get(FORM_PARAM_SELECTED_WORKFLOW).length == 0) {
addMessage(
"danger",
globalizationHelper.getLocalizedTextsUtil(
getBundle()
).getText("createstep.workflow.none_selected")
);
return showCreateStep();
}
selectedWorkflow = formParams.get(FORM_PARAM_SELECTED_WORKFLOW)[0];
final Optional<Workflow> workflowResult = getContentSection()
.getWorkflowTemplates()
.stream()
.filter(template -> template.getUuid().equals(selectedWorkflow))
.findAny();
if (!workflowResult.isPresent()) {
addMessage(
"danger",
globalizationHelper.getLocalizedTextsUtil(
getBundle()
).getText("createstep.workflow.error.not_available")
);
return showCreateStep();
}
if (!getMessages().isEmpty()) {
return showCreateStep();
}
final SciDepartment department = itemManager.createContentItem(
name,
getContentSection(),
getFolder(),
workflowResult.get(),
SciDepartment.class,
locale
);
department.getTitle().putValue(locale, title);
department.getShortDescription().putValue(locale, shortDescription);
itemRepo.save(department);
return String.format(
"redirect:%s/documents/%s/%s/@scidepartment-basicproperties",
getContentSectionLabel(),
getFolderPath(),
name
);
}
}

View File

@ -0,0 +1,101 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.contenttypes.scidepartment.Contact;
import org.scientificcms.contenttypes.scidepartment.ContactRepository;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "scidepartment-description-contacts")
public class SciDepartmentDescriptionContacts {
@Inject
private ContactRepository contactRepo;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionsUi sectionsUi;
@POST
@Path("/save-order")
@Consumes(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
public Response saveOrder(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
final List<String> order
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException(
String.format(
"No content identifed by %s found.",
sectionIdentifier
)
)
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPath)
.orElseThrow(
() -> new NotFoundException(
String.format(
"No document for path %s in section %s.",
documentPath,
contentSection.getLabel()
)
)
);
if (!(document instanceof SciDepartment)) {
throw new NotFoundException(
String.format(
"No SciDepartment for path %s in section %s.",
documentPath,
contentSection.getLabel()
)
);
}
final Map<Long, Long> orderMap = new HashMap<>();
for (int i = 0; i < order.size(); i++) {
orderMap.put(Long.parseLong(order.get(i)), (long) i);
}
final SciDepartment department = (SciDepartment)document;
for (final Contact contact : department.getContacts()) {
contact.setOrder(orderMap.get(contact.getContactId()));
contactRepo.save(contact);
}
return Response.ok().build();
}
}

View File

@ -0,0 +1,57 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.assets.Organization;
import org.librecms.assets.Person;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentDescriptionContacts")
public class SciDepartmentDescriptionContactsModel {
private boolean canEdit;
private List<SciDepartmentContactModel> contacts;
private String baseUrl;
public boolean getCanEdit() {
return canEdit;
}
protected void setCanEdit(final boolean canEdit) {
this.canEdit = canEdit;
}
public List<SciDepartmentContactModel> getContacts() {
return Collections.unmodifiableList(contacts);
}
protected void setContacts(final List<SciDepartmentContactModel> contacts) {
this.contacts = new ArrayList<>(contacts);
}
public String getContactableTypes() {
return String.join(
",", Person.class.getName(), Organization.class.getName()
);
}
public String getBaseUrl() {
return baseUrl;
}
protected void setBaseUrl(final String baseUrl) {
this.baseUrl = baseUrl;
}
}

View File

@ -0,0 +1,66 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.assets.Person;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentDescriptionMembers")
public class SciDepartmentDescriptionMembersModel {
private boolean canEdit;
private List<SciDepartmentMembershipModel> members;
private Map<String, String> statusValues;
private String baseUrl;
public String getMemberType() {
return Person.class.getName();
}
public boolean getCanEdit() {
return canEdit;
}
protected void setCanEdit(final boolean canEdit) {
this.canEdit = canEdit;
}
public List<SciDepartmentMembershipModel> getMembers() {
return Collections.unmodifiableList(members);
}
protected void setMembers(final List<SciDepartmentMembershipModel> members) {
this.members = new ArrayList<>(members);
}
public Map<String, String> getStatusValues() {
return Collections.unmodifiableMap(statusValues);
}
protected void setStatusValues(final Map<String, String> statusValues) {
this.statusValues = new LinkedHashMap<>(statusValues);
}
public String getBaseUrl() {
return baseUrl;
}
protected void setBaseUrl(final String baseUrl) {
this.baseUrl = baseUrl;
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2022 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.ui.contentsections.documents.CmsEditorLocaleVariantRow;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentDescriptionModel")
public class SciDepartmentDescriptionModel {
private boolean canEdit;
private Map<String, String> descriptionValues;
private List<CmsEditorLocaleVariantRow> variants;
private List<String> unusedLocales;
private String selectedLocale;
public Map<String, String> getDescriptionValues() {
return Optional
.ofNullable(descriptionValues)
.map(Collections::unmodifiableMap)
.orElse(Collections.emptyMap());
}
protected void setDescriptionValues(
final Map<String, String> descriptionValues
) {
this.descriptionValues = Optional
.ofNullable(descriptionValues)
.map(values -> new HashMap<>(values))
.map(values -> (Map<String, String>) values)
.orElse(Collections.emptyMap());
}
public List<CmsEditorLocaleVariantRow> getVariants() {
return Optional
.ofNullable(variants)
.map(Collections::unmodifiableList)
.orElse(Collections.emptyList());
}
protected void setVariants(final List<CmsEditorLocaleVariantRow> variants) {
this.variants = Optional
.ofNullable(variants)
.map(list -> new ArrayList<>(list))
.map(list -> (List<CmsEditorLocaleVariantRow>) list)
.orElse(Collections.emptyList());
}
public List<String> getUnusedLocales() {
return Optional
.ofNullable(unusedLocales)
.map(Collections::unmodifiableList)
.orElse(Collections.emptyList());
}
protected void setUnusedLocales(final List<String> unusedLocales) {
this.unusedLocales = Optional
.ofNullable(unusedLocales)
.map(list -> new ArrayList<>(list))
.map(list -> (List<String>) list)
.orElse(Collections.emptyList());
}
public String getSelectedLocale() {
return selectedLocale;
}
protected void setSelectedLocale(final String selectedLocale) {
this.selectedLocale = selectedLocale;
}
public boolean getCanEdit() {
return canEdit;
}
protected void setCanEdit(final boolean canEdit) {
this.canEdit = canEdit;
}
}

View File

@ -0,0 +1,123 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.Locale;
import java.util.StringTokenizer;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "scidepartment-description-resources")
public class SciDepartmentDescriptionStepResources {
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private ItemPermissionChecker itemPermissionChecker;
@GET
@Path("/department-description/wordcount/{locale}")
@Produces(MediaType.TEXT_HTML)
@Transactional(Transactional.TxType.REQUIRED)
public String getDepartmentDescriptionWordCount(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPathParam,
@PathParam("locale") final String localeParam
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException()
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new NotFoundException()
);
if (!(document instanceof SciDepartment)) {
throw new NotFoundException();
}
final SciDepartment department = (SciDepartment) document;
if (itemPermissionChecker.canEditItem(department)) {
final String text = department
.getDepartmentDescription()
.getValue(new Locale(localeParam));
final Document jsoupDoc = Jsoup.parseBodyFragment(text);
final long result = new StringTokenizer(
jsoupDoc.body().text()
).countTokens();
return Long.toString(result);
} else {
throw new ForbiddenException();
}
}
@GET
@Path("/department-description/{locale}")
@Produces(MediaType.TEXT_HTML)
@Transactional(Transactional.TxType.REQUIRED)
public String viewDepartmentDescriptionValue(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPathParam,
@PathParam("locale") final String localeParam
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException()
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new NotFoundException()
);
if (!(document instanceof SciDepartment)) {
throw new NotFoundException();
}
final SciDepartment department = (SciDepartment) document;
if (itemPermissionChecker.canEditItem(department)) {
return department.getDepartmentDescription().getValue(
new Locale(localeParam)
);
} else {
throw new ForbiddenException();
}
}
}

View File

@ -0,0 +1,130 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.contenttypes.scidepartment.Contact;
import org.scientificcms.contenttypes.scidepartment.ContactRepository;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "scidepartment-description-service")
public class SciDepartmentDescriptionStepService {
@Inject
private ContactRepository contactRepo;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionsUi sectionsUi;
@POST
@Path("/contacts/save-order")
@Consumes(MediaType.APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
public Response saveContactsOrder(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
final List<String> contactsOrder
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException(
String.format(
"No content identifed by %s found.",
sectionIdentifier
)
)
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPath)
.orElseThrow(
() -> new NotFoundException(
String.format(
"No document for path %s in section %s.",
documentPath,
contentSection.getLabel()
)
)
);
if (!(document instanceof SciDepartment)) {
throw new BadRequestException(
String.format(
"Document %s is not a %s.",
documentPath,
SciDepartment.class.getSimpleName()
)
);
}
final SciDepartment department = (SciDepartment) document;
final List<Contact> contacts = department.getContacts();
if (contactsOrder.size() != contacts.size()) {
throw new BadRequestException(
String.format(
"Number of contacts of the SciDepartment %s does "
+ "not match the number of values in the order "
+ "list. Number of contactas: %d, number of values in "
+ "the contacts order list: %d",
documentPath,
contacts.size(),
contactsOrder.size()
)
);
}
for (int i = 0; i < contactsOrder.size(); i++) {
final String contactIdParam = contactsOrder.get(i);
final long contactId = Long.parseLong(contactIdParam);
final Contact contact = contacts
.stream()
.filter(con -> con.getContactId() == contactId)
.findAny()
.orElseThrow(
() -> new BadRequestException(
String.format(
"contactsOrder has an entry for contact with "
+ "ID %d, but there is not contact with that "
+ "ID.",
contactId
)
)
);
contact.setOrder(i);
contactRepo.save(contact);
}
return Response.ok().build();
}
}

View File

@ -0,0 +1,143 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.scientificcms.contenttypes.scidepartment.Membership;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
/**
* DTO providing the information about a {@link Membership} of a
* {@link SciDepartment} in an form that easy usable from a MVC template.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SciDepartmentMembershipModel {
/**
* The ID of the {@link Membership}.
*/
private long membershipId;
/**
* The role of the member.
*
* @see Membership#role
*/
private String role;
/**
* The status of the membership.
*
* @see Membership#status
*/
private String status;
/**
* The given name of the member.
*
* @see PersonName#givenName
*/
private String givenName;
/**
* The surname of the member.
*
* @see PersonName#surname
*/
private String surname;
/**
* An optional prefix for the name of the member.
*
* @see PersonName#prefix
*/
private String prefix;
/**
* An optional suffix for the name of the member.
*
* @see PersonName#suffix
*/
private String suffix;
public long getMembershipId() {
return membershipId;
}
public void setMembershipId(final long membershipId) {
this.membershipId = membershipId;
}
public String getRole() {
return role;
}
public void setRole(final String role) {
this.role = role;
}
public String getStatus() {
return status;
}
public void setStatus(final String status) {
this.status = status;
}
public String getName() {
final StringBuilder builder = new StringBuilder();
if (prefix != null && !prefix.isBlank()) {
builder.append(prefix);
builder.append(" ");
}
if (surname != null && !surname.isBlank()) {
builder.append(surname);
}
if (surname != null
&& !surname.isBlank()
&& givenName != null
&& !givenName.isBlank()) {
builder.append(", ");
}
if (givenName != null && !givenName.isBlank()) {
builder.append(givenName);
}
if (suffix != null && !suffix.isBlank()) {
builder.append(" ");
builder.append(suffix);
}
return builder.toString();
}
public String getGivenName() {
return givenName;
}
public void setGivenName(final String givenName) {
this.givenName = givenName;
}
public String getSurname() {
return surname;
}
public void setSurname(final String surname) {
this.surname = surname;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(final String suffix) {
this.suffix = suffix;
}
}

View File

@ -0,0 +1,21 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.ui.AbstractMessagesBean;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentMessageBundle")
public class SciDepartmentMessageBundle extends AbstractMessagesBean {
@Override
protected String getMessageBundle() {
return SciDepartmentStepsConstants.BUNDLE;
}
}

View File

@ -0,0 +1,492 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.security.AuthorizationRequired;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.ui.contentsections.ContentSectionNotFoundException;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.mvc.Controller;
import javax.mvc.Models;
import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "scidepartment-basicproperties")
@Controller
@MvcAuthoringStepDef(
bundle = SciDepartmentStepsConstants.BUNDLE,
descriptionKey = "authoringsteps.basicproperties.description",
labelKey = "authoringsteps.basicproperties.label",
supportedDocumentType = SciDepartment.class
)
public class SciDepartmentPropertiesStep extends AbstractMvcAuthoringStep {
@Inject
private SciDepartmentMessageBundle messageBundle;
/**
* Used for retrieving and saving the departments.
*/
@Inject
private ContentItemRepository itemRepo;
@Inject
private DocumentUi documentUi;
/**
* Provides functions for working with {@link LocalizedString}s.
*/
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private ItemPermissionChecker itemPermissionChecker;
@Inject
private SciDepartmentPropertiesStepModel propertiesStepModel;
@Inject
private Models models;
@Override
public Class<SciDepartmentPropertiesStep> getStepClass() {
return SciDepartmentPropertiesStep.class;
}
@Override
@Transactional(Transactional.TxType.REQUIRED)
protected void init() throws ContentSectionNotFoundException,
DocumentNotFoundException {
super.init();
propertiesStepModel.setName(getDocument().getDisplayName());
final Set<Locale> titleLocales = getDocument()
.getTitle()
.getAvailableLocales();
propertiesStepModel.setTitleValues(
getDocument()
.getTitle()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
entry -> entry.getValue()
)
)
);
propertiesStepModel.setUnusedTitleLocales(
globalizationHelper
.getAvailableLocales()
.stream()
.filter(locale -> !titleLocales.contains(locale))
.map(Locale::toString)
.collect(Collectors.toList())
);
final SciDepartment department = (SciDepartment) getDocument();
propertiesStepModel.setShortDescriptionValues(
department
.getShortDescription()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
entry -> entry.getValue()
)
)
);
final Set<Locale> shortDescriptionLocales = department
.getShortDescription()
.getAvailableLocales();
propertiesStepModel.setUnusedShortDescriptionLocales(
globalizationHelper
.getAvailableLocales()
.stream()
.filter(locale -> !shortDescriptionLocales.contains(locale))
.map(Locale::toString)
.collect(Collectors.toList())
);
}
@GET
@Path("/")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
public String showStep(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
return "org/scientificcms/contenttypes/scidepartment/ui/scidepartment-basic-properties.xhtml";
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
messageBundle.getMessage("scidepartment.edit.denied")
);
}
}
/**
* Updates the name of the current department.
*
* @param sectionIdentifier
* @param documentPath
* @param name
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/name")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateName(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@FormParam("name") @DefaultValue("") final String name
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
if (name.isBlank()) {
models.put("nameMissing", true);
return showStep(sectionIdentifier, documentPath);
}
getDocument().setDisplayName(name);
itemRepo.save(getDocument());
updateDocumentPath();
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Updates a localized title of the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale to update.
* @param value The updated title value.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/title/@add")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String addTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@FormParam("locale") final String localeParam,
@FormParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
getDocument().getTitle().putValue(locale, value);
itemRepo.save(getDocument());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Updates a localized title of the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale to update.
* @param value The updated title value.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/title/@edit/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String editTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@PathParam("locale") final String localeParam,
@FormParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
getDocument().getTitle().putValue(locale, value);
itemRepo.save(getDocument());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Removes a localized title of the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale to remove.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/title/@remove/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String removeTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@PathParam("locale") final String localeParam
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
getDocument().getTitle().removeValue(locale);
itemRepo.save(getDocument());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Adds a localized short description to the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale of the description.
* @param value The description value.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/short-description/@add")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
public String addShortDescription(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@FormParam("locale") final String localeParam,
@FormParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
final SciDepartment department = (SciDepartment) getDocument();
department.getShortDescription().putValue(locale, value);
itemRepo.save(department);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Updates a localized short description to the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale to update.
* @param value The description value.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/short-description/@edit/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
public String editShortDescription(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@PathParam("locale") final String localeParam,
@FormParam("value") final String value
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
final SciDepartment department = (SciDepartment) getDocument();
department.getShortDescription().putValue(locale, value);
itemRepo.save(department);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
/**
* Removes a localized short description from the department.
*
* @param sectionIdentifier
* @param documentPath
* @param localeParam The locale to remove.
*
* @return A redirect to this authoring step.
*/
@POST
@Path("/short-description/@remove/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
public String removeShortDescription(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@PathParam("locale") final String localeParam
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
final SciDepartment department = (SciDepartment) getDocument();
department.getShortDescription().removeValue(locale);
itemRepo.save(department);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
getContentSection(),
getDocument(),
getLabel()
);
}
}
}

View File

@ -0,0 +1,76 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentPropertiesStep")
public class SciDepartmentPropertiesStepModel {
private String name;
private Map<String, String> titleValues;
private List<String> unusedTitleLocales;
private Map<String, String> shortDescriptionValues;
private List<String> unusedShortDescriptionLocales;
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public Map<String, String> getTitleValues() {
return Collections.unmodifiableMap(titleValues);
}
public void setTitleValues(final Map<String, String> titleValues) {
this.titleValues = new HashMap<>(titleValues);
}
public List<String> getUnusedTitleLocales() {
return Collections.unmodifiableList(unusedTitleLocales);
}
public void setUnusedTitleLocales(final List<String> unusedTitleLocales) {
this.unusedTitleLocales = new ArrayList<>(unusedTitleLocales);
}
public Map<String, String> getShortDescriptionValues() {
return Collections.unmodifiableMap(shortDescriptionValues);
}
public void setShortDescriptionValues(
final Map<String, String> shortDescriptionValues
) {
this.shortDescriptionValues = new HashMap<>(shortDescriptionValues);
}
public List<String> getUnusedShortDescriptionLocales() {
return Collections.unmodifiableList(unusedShortDescriptionLocales);
}
public void setUnusedShortDescriptionLocales(
final List<String> unusedShortDescriptionLocales
) {
this.unusedShortDescriptionLocales = new ArrayList<>(
unusedShortDescriptionLocales
);
}
}

View File

@ -0,0 +1,29 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.ui.AbstractMessagesBean;
import org.scientificcms.contenttypes.scidepartment.SciDepartmentConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentRoles")
public class SciDepartmentRoles extends AbstractMessagesBean {
@Inject
private ConfigurationManager confManager;
@Override
protected String getMessageBundle() {
return confManager
.findConfiguration(SciDepartmentConfig.class)
.getMemberRolesBundleName();
}
}

View File

@ -0,0 +1,16 @@
package org.scientificcms.contenttypes.scidepartment.ui;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class SciDepartmentStepsConstants {
private SciDepartmentStepsConstants() {
// Nothing
}
public static final String BUNDLE
= "org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentBundle";
}

View File

@ -0,0 +1,100 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.librecms.ui.contentsections.documents.CmsEditorLocaleVariantRow;
import org.scientificcms.contenttypes.scidepartment.DepartmentText;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* DTO providing the data of a {@link DepartmentText} in a form that is easy
* usable from the view.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SciDepartmentTextModel {
private String key;
private Map<String, String> textValues;
private List<CmsEditorLocaleVariantRow> variants;
private List<String> unusedLocales;
private long order;
public Map<String, String> getTextValues() {
return Optional
.ofNullable(textValues)
.map(Collections::unmodifiableMap)
.orElse(Collections.emptyMap());
}
protected void setTextValues(
final Map<String, String> textValues
) {
this.textValues = Optional
.ofNullable(textValues)
.map(values -> new HashMap<>(values))
.map(values -> (Map<String, String>) values)
.orElse(Collections.emptyMap());
}
public List<CmsEditorLocaleVariantRow> getVariants() {
return Optional
.ofNullable(variants)
.map(Collections::unmodifiableList)
.orElse(Collections.emptyList());
}
protected void setVariants(final List<CmsEditorLocaleVariantRow> variants) {
this.variants = Optional
.ofNullable(variants)
.map(list -> new ArrayList<>(list))
.map(list -> (List<CmsEditorLocaleVariantRow>) list)
.orElse(Collections.emptyList());
}
public List<String> getUnusedLocales() {
return Optional
.ofNullable(unusedLocales)
.map(Collections::unmodifiableList)
.orElse(Collections.emptyList());
}
protected void setUnusedLocales(final List<String> unusedLocales) {
this.unusedLocales = Optional
.ofNullable(unusedLocales)
.map(list -> new ArrayList<>(list))
.map(list -> (List<String>) list)
.orElse(Collections.emptyList());
}
public String getKey() {
return key;
}
protected void setKey(final String key) {
this.key = key;
}
public String getKeyId() {
return key.replace('.', '-');
}
public long getOrder() {
return order;
}
protected void setOrder(final long order) {
this.order = order;
}
}

View File

@ -0,0 +1,29 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.ui.AbstractMessagesBean;
import org.scientificcms.contenttypes.scidepartment.SciDepartmentConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentTexts")
public class SciDepartmentTexts extends AbstractMessagesBean {
@Inject
private ConfigurationManager confManager;
@Override
protected String getMessageBundle() {
return confManager
.findConfiguration(SciDepartmentConfig.class)
.getTextKeysBundleName();
}
}

View File

@ -0,0 +1,72 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciDepartmentTextsModel")
public class SciDepartmentTextsModel {
private boolean canEdit;
private Map<String, String> availableTextKeys;
private Map<String, SciDepartmentTextModel> texts;
private String selectedText;
private String selectedLocale;
public boolean getCanEdit() {
return canEdit;
}
protected void setCanEdit(final boolean canEdit) {
this.canEdit = canEdit;
}
public Map<String, String> getAvailableTextKeys() {
return Collections.unmodifiableMap(availableTextKeys);
}
protected void setAvailableTextKeys(
final Map<String, String> availableTextKeys
) {
this.availableTextKeys = new LinkedHashMap<>(availableTextKeys);
}
public Map<String, SciDepartmentTextModel> getTexts() {
return Collections.unmodifiableMap(texts);
}
protected void setTexts(final Map<String, SciDepartmentTextModel> texts) {
this.texts = new LinkedHashMap<>(texts);
}
public String getSelectedText() {
return selectedText;
}
public void setSelectedText(final String selectedText) {
this.selectedText = selectedText;
}
public String getSelectedLocale() {
return selectedLocale;
}
protected void setSelectedLocale(final String selectedLocale) {
this.selectedLocale = selectedLocale;
}
}

View File

@ -0,0 +1,125 @@
package org.scientificcms.contenttypes.scidepartment.ui;
import org.jsoup.Jsoup;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import org.scientificcms.contenttypes.scidepartment.SciDepartment;
import java.util.Locale;
import java.util.Optional;
import java.util.StringTokenizer;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "scidepartment-texts-resources")
public class SciDepartmentTextsResources {
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private ItemPermissionChecker itemPermissionChecker;
@GET
@Path("/department-texts/{textKey}/wordcount/{locale}")
@Produces(MediaType.TEXT_HTML)
@Transactional(Transactional.TxType.REQUIRED)
public String getDepartmentDescriptionWordCount(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPathParam,
@PathParam("textKey") final String textKey,
@PathParam("locale") final String localeParam
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException()
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new NotFoundException()
);
if (!(document instanceof SciDepartment)) {
throw new NotFoundException();
}
final SciDepartment department = (SciDepartment) document;
if (itemPermissionChecker.canEditItem(department)) {
return Optional
.ofNullable(department.getAdditionalTexts().get(textKey))
.map(text -> text.getText().getValue(new Locale(localeParam)))
.map(text -> Jsoup.parseBodyFragment(text))
.map(jsoupDoc -> jsoupDoc.body().text())
.map(text -> new StringTokenizer(text).countTokens())
.map(Long::toString)
.orElseThrow(() -> new NotFoundException());
} else {
throw new ForbiddenException();
}
}
@GET
@Path("/department-texts/{textKey}/{locale}")
@Produces(MediaType.TEXT_HTML)
@Transactional(Transactional.TxType.REQUIRED)
public String viewDepartmentDescriptionValue(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPathParam,
@PathParam("textKey") final String textKey,
@PathParam("locale") final String localeParam
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException()
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new NotFoundException()
);
if (!(document instanceof SciDepartment)) {
throw new NotFoundException();
}
final SciDepartment department = (SciDepartment) document;
if (itemPermissionChecker.canEditItem(department)) {
return Optional
.ofNullable(department.getAdditionalTexts().get(textKey))
.map(text -> text.getText().getValue(new Locale(localeParam)))
.orElseThrow(() -> new NotFoundException());
} else {
throw new ForbiddenException();
}
}
}

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
author: Jens Pelzetter
-->
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="ScientificCMS" transaction-type="JTA">
<!--
Enforce JPA provider
Not really necessary here because we don't use any Hibernate
specific features, but makes it easier to manage to database
creation scripts.
-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/comp/env/jdbc/scientificcms/db</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.id.new_generator_mappings" value="true"/>
<!--
Properties for Hibernate Envers
We are using the ValidityAuditStrategy here because it is faster
when querying data than the DefaultStrategy
-->
<property name="org.hibernate.envers.audit_strategy"
value="org.hibernate.envers.strategy.ValidityAuditStrategy"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1 @@
org.scientificcms.contenttypes.scidepartment.SciDepartmentModule

View File

@ -0,0 +1,86 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
<ui:define name="main">
<div class="container">
<h1>#{SciDepartmentMessageBundle['createstep.title']}</h1>
<c:forEach items="#{SciDepartmentCreateStep.messages.entrySet()}"
var="message">
<div class="alert alert-#{message.key}"
role="alert">
#{message.value}
</div>
</c:forEach>
<form action="#{mvc.basePath}/#{SciDepartmentCreateStep.contentSectionLabel}/documents/#{SciDepartmentCreateStep.folderPath}@create/#{SciDepartmentCreateStep.documentType}"
method="post">
<bootstrap:formGroupText
help="#{SciDepartmentMessageBundle['createform.name.help']}"
inputId="name"
label="#{SciDepartmentMessageBundle['createform.name.label']}"
name="name"
pattern="^([a-zA-Z0-9_-]*)$"
required="true"
value="#{SciDepartmentCreateStep.name}"
/>
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['createform.initial_locale.help']}"
inputId="locale"
label="#{SciDepartmentMessageBundle['createform.initial_locale.label']}"
name="locale"
options="#{SciDepartmentCreateStep.availableLocales}"
required="true"
selectedOptions="#{[SciDepartmentCreateStep.initialLocale]}"
/>
<bootstrap:formGroupText
help="#{SciDepartmentMessageBundle['createform.title.help']}"
inputId="title"
label="#{SciDepartmentMessageBundle['createform.title.label']}"
name="title"
required="true"
value="#{SciDepartmentCreateStep.title}"
/>
<bootstrap:formGroupTextarea
cols="80"
help="#{SciDepartmentMessageBundle['createform.summary.help']}"
inputId="shortdesc"
label="#{SciDepartmentMessageBundle['createform.summary.label']}"
name="shortdesc"
required="true"
rows="16"
value="#{SciDepartmentCreateStep.shortDescription}"
/>
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['createform.workflow.help']}"
inputId="workflow"
label="#{SciDepartmentMessageBundle['createform.workflow.label']}"
name="workflow"
options="#{SciDepartmentCreateStep.availableWorkflows}"
selectedOptions="#{[SciDepartmentCreateStep.selectedWorkflow]}"
/>
<a class="btn btn-warning"
href="#{mvc.basePath}/#{SciDepartmentCreateStep.contentSectionLabel}/documentsfolders/#{SciDepartmentCreateStep.folderPath}">
#{SciDepartmentMessageBundle['createform.cancel']}
</a>
<button class="btn btn-success"
type="submit">
#{SciDepartmentMessageBundle['createform.submit']}
</button>
</form>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<div class="d-flex">
<a class="btn btn-secondary btn-sm align-self-center mr-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description">
<bootstrap:svgIcon icon="caret-left-fill" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.back']}</span>
</a>
<h2>#{SciDepartmentMessageBundle['description_step.description.header.edit']}</h2>
</div>
<c:if test="#{SciDepartmentDescriptionModel.canEdit}">
<librecms:cmsEditor
backUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description"
baseUrl="#{mvc.basePath}"
canEdit="#{SciDepartmentDescriptionModel.canEdit}"
contentSection="#{ContentSectionModel.sectionName}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/edit"
editorId="scidepartment-description-editor"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"
selectedLocale="#{SciDepartmentDescriptionModel.selectedLocale}"
title="#{SciDepartmentMessageBundle['description.editor.header']}"
variantUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description-resources/department-description"
/>
</c:if>
</ui:define>
<ui:define name="scripts">
<script src="#{request.contextPath}/assets/@content-sections/cms-editor.js"></script>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<div class="d-flex">
<a class="btn btn-secondary btn-sm align-self-center mr-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemName}/@scidepartment-description">
<bootstrap:svgIcon icon="caret-left-fill" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.back']}</span>
</a>
<h2>#{SciDepartmentMessageBundle['description_step.description.header.view']}</h2>
</div>
<c:if test="#{SciDepartmentDescriptionModel.canEdit}">
<div class="text-right">
<a class="btn btn-secondary"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/edit">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.edit']}</span>
</a>
</div>
</c:if>
<div class="cms-text-preview article-text border p-2">
<h:outputText escape="false"
value="#{SciDepartmentDescriptionModel.descriptionValues.get(SciDepartmentDescriptionModel.selectedLocale)}" />
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,149 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:param name="authoringStep"
value="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties" />
<ui:define name="authoringStep">
<h2>#{SciDepartmentMessageBundle.getMessage('basicproperties.header', [SciDepartmentPropertiesStep.name])}</h2>
<h3>#{SciDepartmentMessageBundle['basicproperties.name.header']}</h3>
<div class="d-flex">
<pre class="mr-2">#{SciDepartmentPropertiesStep.name}</pre>
<c:if test="#{CmsSelectedDocumentModel.canEdit}">
<button class="btn btn-primary btn-sm"
data-toggle="modal"
data-target="#name-edit-dialog"
type="button">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">
#{SciDepartmentMessageBundle['basicproperties.name.edit']}
</span>
</button>
</c:if>
</div>
<c:if test="#{CmsSelectedDocumentModel.canEdit}">
<div aria-hidden="true"
aria-labelledby="name-edit-dialog-title"
class="modal fade"
id="name-edit-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/name"
class="modal-content"
method="post">
<div class="modal-header">
<h4 class="modal-title"
id="name-edit-dialog-title">
#{SciDepartmentMessageBundle['basicproperties.name.edit.title']}
</h4>
<button aria-label="#{SciDepartmentMessageBundle['basicproperties.name.edit.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText
help="#{SciDepartmentMessageBundle['basicproperties.name.help']}"
inputId="name"
label="#{SciDepartmentMessageBundle['basicproperties.name.label']}"
name="name"
pattern="^([a-zA-Z0-9_-]*)$"
required="true"
value="#{SciDepartmentPropertiesStep.name}"/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{SciDepartmentMessageBundle['basicproperties.name.edit.close']}
</button>
<button class="btn btn-success"
type="submit">
#{SciDepartmentMessageBundle['basicproperties.name.edit.submit']}
</button>
</div>
</form>
</div>
</div>
</c:if>
<libreccm:localizedStringEditor
addButtonLabel="#{SciDepartmentMessageBundle['basicproperties.title.add']}"
addDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.title.add.cancel']}"
addDialogLocaleSelectHelp="#{SciDepartmentMessageBundle['basicproperties.title.add.locale.help']}"
addDialogLocaleSelectLabel="#{SciDepartmentMessageBundle['basicproperties.title.add.locale.label']}"
addDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.title.add.submit']}"
addDialogTitle="#{SciDepartmentMessageBundle['basicproperties.title.add.header']}"
addDialogValueHelp="#{SciDepartmentMessageBundle['basicproperties.title.add.value.help']}"
addDialogValueLabel="#{SciDepartmentMessageBundle['basicproperties.title.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/title/@add"
editButtonLabel="#{SciDepartmentMessageBundle['basicproperties.title.edit']}"
editDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.title.edit.cancel']}"
editDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.title.edit.submit']}"
editDialogTitle="#{SciDepartmentMessageBundle['basicproperties.title.edit.header']}"
editDialogValueHelp="#{SciDepartmentMessageBundle['basicproperties.title.edit.value.help']}"
editDialogValueLabel="#{SciDepartmentMessageBundle['basicproperties.title.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/title/@edit"
editorId="title-editor"
hasUnusedLocales="#{!SciDepartmentPropertiesStep.unusedTitleLocales.isEmpty()}"
headingLevel="3"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"
readOnly="#{!CmsSelectedDocumentModel.canEdit}"
removeButtonLabel="#{SciDepartmentMessageBundle['basicproperties.title.remove']}"
removeDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.title.remove.cancel']}"
removeDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.title.remove.submit']}"
removeDialogText="#{SciDepartmentMessageBundle['basicproperties.title.remove.text']}"
removeDialogTitle="#{SciDepartmentMessageBundle['basicproperties.title.remove.header']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/title/@remove"
title="#{SciDepartmentMessageBundle['basicproperties.title.header']}"
unusedLocales="#{SciDepartmentPropertiesStep.unusedTitleLocales}"
values="#{SciDepartmentPropertiesStep.titleValues}"
/>
<libreccm:localizedStringEditor
addButtonLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add']}"
addDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.cancel']}"
addDialogLocaleSelectHelp="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.locale.help']}"
addDialogLocaleSelectLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.locale.label']}"
addDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.submit']}"
addDialogTitle="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.header']}"
addDialogValueHelp="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.value.help']}"
addDialogValueLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/short-description/@add"
editButtonLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit']}"
editDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit.cancel']}"
editDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit.submit']}"
editDialogTitle="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit.header']}"
editDialogValueHelp="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit.value.help']}"
editDialogValueLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/short-description/@edit"
editorId="summary-editor"
hasUnusedLocales="#{!SciDepartmentPropertiesStep.unusedShortDescriptionLocales.isEmpty()}"
headingLevel="3"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"
readOnly="#{!CmsSelectedDocumentModel.canEdit}"
removeButtonLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.remove']}"
removeDialogCancelLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.remove.cancel']}"
removeDialogSubmitLabel="#{SciDepartmentMessageBundle['basicproperties.shortdescription.remove.submit']}"
removeDialogText="#{SciDepartmentMessageBundle['basicproperties.shortdescription.remove.text']}"
removeDialogTitle="#{SciDepartmentMessageBundle['basicproperties.shortdescription.remove.header']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-basicproperties/short-description/@remove"
title="#{SciDepartmentMessageBundle['basicproperties.shortdescription.header']}"
unusedLocales="#{SciDepartmentPropertiesStep.unusedShortDescriptionLocales}"
useTextarea="true"
values="#{SciDepartmentPropertiesStep.shortDescriptionValues}"
/>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,457 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:param name="authoringStep"
value="/libreccm/@contentsections/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/scidepartment-description" />
<ui:define name="authoringStep">
<h2>#{SciDepartmentMessageBundle['description_step.header']}</h2>
<c:if test="#{contactableNotFound != null}">
<div class="alert alert-warning" role="alert">
#{SciDepartmentMessageBundle.getMessage('description_step.errors.contactable_not_found', [contactableNotFound])}
</div>
</c:if>
<c:if test="#{personNotFound != null}">
<div class="alert alert-warning" role="alert">
#{SciDepartmentMessageBundle.getMessage('description_step.errors.person_not_found', [personNotFound])}
</div>
</c:if>
<c:if test="#{illegalStatusValue != null}">
<div class="alert alert-warning" role="alert">
#{SciDepartmentMessageBundle.getMessage('description_step.errors.illegal_member_status_value', [illegalStatusValue])}
</div>
</c:if>
<template id="scidepartment-contacts-sort-error-general">
<div class="alert alert-danger mt-3" role="alert">
#{SciDepartmentMessageBundle['contacts.sort.errors.general']}
</div>
</template>
<template id="scidepartment-contacts-sort-error-save">
<div class="alert alert-danger mt-3" role="alert">
#{SciDepartmentMessageBundle['contacts.sort.errors.save']}
</div>
</template>
<div id="messages"></div>
<librecms:cmsEditorVariants
addButtonLabel="#{SciDepartmentMessageBundle['description.editor.add_variant']}"
addDialogLocaleSelectHelp="#{SciDepartmentMessageBundle['description.editor.add.locale.help']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/add"
canEdit="#{SciDepartmentDescriptionModel.canEdit}"
editorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/edit"
hasUnusedLocales="#{!SciDepartmentDescriptionModel.unusedLocales.isEmpty()}"
headingLevel="3"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/remove"
sourceEditorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/docuements/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/edit-source"
title="#{SciDepartmentMessageBundle['description.editor.header']}"
unusedLocales="#{SciDepartmentDescriptionModel.unusedLocales}"
variants="#{SciDepartmentDescriptionModel.variants}"
variantsId="description"
viewPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/description/view"
/>
<h3>#{SciDepartmentMessageBundle['contacts.header']}</h3>
<div class="mb-2">
<div class="text-right">
<librecms:assetPickerButton
assetPickerId="contacts-picker"
buttonIcon="plus-circle"
buttonText="#{SciDepartmentMessageBundle['contacts.add_button.label']}"
/>
</div>
</div>
<librecms:assetPicker
actionUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/contacts/add"
assetType="#{SciDepartmentDescriptionContacts.contactableTypes}"
assetPickerId="contacts-picker"
baseUrl="#{SciDepartmentDescriptionContacts.baseUrl}"
contentSection="#{ContentSectionModel.sectionName}"
dialogTitle="#{SciDepartmentMessageBundle['contact.add.title']}"
formParamName="contactableUuid">
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['contacts.type.help']}"
inputId="type"
label="#{SciDepartmentMessageBundle['contacts.type.label']}"
name="type"
options="#{SciDepartmentContactTypes}"
/>
</librecms:assetPicker>
<button class="btn btn-secondary contacts-save-order-button"
disabled="disable"
type="button">
<span class="save-icon">
<bootstrap:svgIcon icon="save" />
</span>
<span class="save-spinner d-none">
<span aria-hidden="true"
class="spinner-border spinner-border-sm"
role="status"></span>
<span class="sr-only">#{SciDepartmentMessageBundle['contacts.order.save.inprogress']}</span>
</span>
<span>#{SciDepartmentMessageBundle['contacts.order.save']}</span>
</button>
<c:choose>
<c:when test="#{SciDepartmentDescriptionContacts.contacts.isEmpty()}">
<p>#{SciDepartmentMessageBundle['contacts.none']}</p>
</c:when>
<c:otherwise>
<table id="scidepartment-contacts-table"
data-saveUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description-contacts/save-order">
<thead>
<tr>
<th scope="col">#{SciDepartmentMessageBundle['contacts.cols.contactable']}</th>
<th scope="col">#{SciDepartmentMessageBundle['contacts.cols.type']}</th>
<th colspan="2"
scope="col"
>#{SciDepartmentMessageBundle['contacts.cols.actions']}</th>
</tr>
</thead>
<tbody>
<c:forEach items="#{SciDepartmentDescriptionContacts.contacts}"
var="contact">
<tr class="scidepartment-contact"
id="#{contact.contactId}"
data-id="#{contact.contactId}">
<td>
<c:if test="#{CmsSelectedDocumentModel.canEdit}">
<button class="btn btn-secondary cms-sort-handle mr-2"
type="button">
<bootstrap:svgIcon icon="arrows-move" />
<span class="sr-only">#{SciDepartmentMessageBundle['contacts.move.button']}</span>
</button>
</c:if>
#{contact.contactable}
</td>
<td>#{SciDepartmentContactTypes[contact.contactType]}</td>
<td>
<button class="btn btn-secondary"
data-toggle="modal"
data-target="#contact-edit-dialog-#{contact.contactId}"
type="button">
<bootstrap:svgIcon icon="pen" />
<span>#{SciDepartmentMessageBundle['contacts.edit.label']}</span>
</button>
<div aria-hidden="true"
aria-labelledby="contact-edit-dialog-#{contact.contactId}-title"
class="modal fade"
id="contact-edit-dialog-#{contact.contactId}"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/contacts/edit/#{contact.contactId}"
class="modal-content"
method="post">
<div class="modal-header">
<h4 class="modal-title"
id="contact-edit-dialog-#{contact.contactId}-title">
#{SciDepartmentMessageBundle['contacts.edit.title']}
</h4>
<button
aria-label="#{SciDepartmentMessageBundle['contacts.edit.cancel']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x"/>
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['contacts.edit.type.help']}"
inputId="type-edit"
label="#{SciDepartmentMessageBundle['contacts.edit.type.label']}"
name="type"
options="#{SciDepartmentContactTypes}"
selectedOptions="#{[contact.contactType]}"
/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{SciDepartmentMessageBundle['contacts.edit.cancel']}
</button>
<button class="btn btn-success"
type="submit">
#{SciDepartmentMessageBundle['contacts.edit.submit']}
</button>
</div>
</form>
</div>
</div>
</td>
<td>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/contacts/#{contact.contactId}/remove"
buttonText="#{SciDepartmentMessageBundle['contacts.delete.label']}"
cancelLabel="#{SciDepartmentMessageBundle['contacts.delete.cancel']}"
confirmLabel="#{SciDepartmentMessageBundle['contacts.delete.confirm']}"
dialogId="contact-delete-dialog-#{contact.contactId}"
dialogTitle="#{SciDepartmentMessageBundle['contacts.delete.title']}"
message="#{SciDepartmentMessageBundle.getMessage('contacts.delete.message', [contact.contactable, SciDepartmentContactTypes[contact.contactType]])}"
/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</c:otherwise>
</c:choose>
<h3>#{SciDepartmentMessageBundle['memberships.header']}</h3>
<div class="mb-2">
<div class="text-right">
<librecms:assetPickerButton
assetPickerId="members-picker"
buttonIcon="plus-circle"
buttonText="#{SciDepartmentMessageBundle['memberships.add_button.label']}"
/>
</div>
</div>
<librecms:assetPicker
actionUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/members/add"
assetPickerId="members-picker"
assetType="#{SciDepartmentDescriptionMembers.memberType}"
baseUrl="#{SciDepartmentDescriptionContacts.baseUrl}"
contentSection="#{ContentSectionModel.sectionName}"
dialogTitle="#{SciDepartmentMessageBundle['memberships.add.title']}"
formParamName="personUuid">
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['memberships.role.help']}"
inputId="type"
label="#{SciDepartmentMessageBundle['memberships.role.label']}"
name="role"
options="#{SciDepartmentRoles}"
/>
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['memberships.status.help']}"
inputId="status"
label="#{SciDepartmentMessageBundle['memberships.status.label']}"
name="status"
options="#{SciDepartmentDescriptionMembers.statusValues}"
/>
</librecms:assetPicker>
<c:choose>
<c:when test="#{SciDepartmentDescriptionMembers.members.isEmpty()}">
<p>#{SciDepartmentMessageBundle['memberships.none']}</p>
</c:when>
<c:otherwise>
<table>
<thead>
<tr>
<th scope="col">#{SciDepartmentMessageBundle['memberships.cols.name']}</th>
<th scope="col">#{SciDepartmentMessageBundle['memberships.cols.role']}</th>
<th scope="col">#{SciDepartmentMessageBundle['memberships.cols.status']}</th>
<th colspan="2"
scope="col">#{SciDepartmentMessageBundle['memberships.cols.actions']}</th>
</tr>
</thead>
<tbody id="members-list">
<c:forEach items="#{SciDepartmentDescriptionMembers.members}"
var="member">
<tr>
<td>
#{member.name}
</td>
<td>
#{SciDepartmentRoles[member.role]}
</td>
<td>
#{member.status}
</td>
<td>
<button class="btn btn-secondary"
data-toggle="modal"
data-target="#membership-#{member.membershipId}-edit-dialog"
type="button">
<bootstrap:svgIcon icon="pen"/>
<span class="sr-only">#{SciDepartmentMessageBundle['memberships.edit.label']}</span>
</button>
<div aria-hidden="true"
aria-labelledby="membership-#{member.membershipId}-edit-dialog-title"
class="modal fade"
id="membership-#{member.membershipId}-edit-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/members/edit/#{member.membershipId}"
class="modal-content"
method="post">
<div class="modal-header">
<h4 class="modal-title"
id="membership-#{member.membershipId}-edit-dialog-title">
</h4>
<button
aria-label="#{SciDepartmentMessageBundle['memberships.edit.cancel']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x"/>
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['memberships.edit.role.help']}"
inputId="role"
label="#{SciDepartmentMessageBundle['memberships.edit.role.label']}"
name="role"
options="#{SciDepartmentRoles}"
selectedOptions="#{[member.role]}"
/>
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['memberships.edit.status.help']}"
inputId="status"
label="#{SciDepartmentMessageBundle['memberships.edit.status.label']}"
name="status"
options="#{SciDepartmentDescriptionMembers.statusValues}"
selectedOptions="#{[member.status]}"
/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{SciDepartmentMessageBundle['members.edit.cancel']}
</button>
<button class="btn btn-success"
type="submit">
#{SciDepartmentMessageBundle['members.edit.submit']}
</button>
</div>
</form>
</div>
</div>
</td>
<td>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/members/remove/#{member.membershipId}"
buttonText="#{SciDepartmentMessageBundle['memberships.delete.label']}"
cancelLabel="#{SciDepartmentMessageBundle['memberships.delete.cancel']}"
confirmLabel="#{SciDepartmentMessageBundle['memberships.delete.confirm']}"
dialogId="membership-#{member.membershipId}-delete-dialog"
dialogTitle="#{SciDepartmentMessageBundle['memberships.delete.title']}"
message="#{SciDepartmentMessageBundle.getMessage('memberships.delete.message', [member.name])}"
/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</c:otherwise>
</c:choose>
<h3>
#{SciDepartmentMessageBundle['texts.header']}
<button class="btn btn-secondary"
data-toggle="modal"
data-target="#department-text-add-dialog"
type="button">
<bootstrap:svgIcon icon="plus-circle" />
<span class="sr-only">#{SciDepartmentMessageBundle['texts.add.label']}</span>
</button>
</h3>
<div aria-hidden="true"
aria-labelledby="department-text-add-dialog-title"
class="modal fade"
id="department-text-add-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/add"
class="modal-content"
method="post">
<div class="modal-header">
<h4 class="modal-title"
id="department-text-add-dialog-title">
#{SciDepartmentMessageBundle['texts.add.dialog.title']}
</h4>
<button aria-label="#{SciDepartmentMessageBundle['texts.add.cancel']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupSelect
help="#{SciDepartmentMessageBundle['texts.add.key.help']}"
inputId="text-key"
label="#{SciDepartmentMessageBundle['texts.add.key.label']}"
name="textKey"
options="#{SciDepartmentTextsModel.availableTextKeys}"
/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{SciDepartmentMessageBundle['texts.add.cancel']}
</button>
<button class="btn btn-success"
type="submit">
#{SciDepartmentMessageBundle['texts.add.submit']}
</button>
</div>
</form>
</div>
</div>
<c:choose>
<c:when test="#{SciDepartmentTextsModel.texts.isEmpty()}">
<p>#{SciDepartmentMessageBundle['texts.none']}</p>
</c:when>
<c:otherwise>
<c:forEach items="#{SciDepartmentTextsModel.texts.entrySet()}"
var="text">
<div class="d-flex">
<h4 class="mr-2">#{SciDepartmentTexts[text.key]}</h4>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/remove/#{text.key}"
buttonText="#{SciDepartmentMessageBundle['texts.delete.label']}"
cancelLabel="#{SciDepartmentMessageBundle['texts.delete.cancel']}"
confirmLabel="#{SciDepartmentMessageBundle['texts.delete.confirm']}"
dialogId="text-#{text.value.keyId}-delete-dialog"
dialogTitle="#{SciDepartmentMessageBundle['texts.delete.title']}"
message="#{SciDepartmentMessageBundle.getMessage('texts.delete.message', [SciDepartmentTexts[text.key]])}"
/>
</div>
<librecms:cmsEditorVariants
addButtonLabel="#{SciDepartmentMessageBundle['texts.editor.add_variant']}"
addDialogLocaleSelectHelp="#{SciDepartmentMessageBundle['texts.editor.add.locale.help']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/add/#{text.key}"
canEdit="#{SciDepartmentDescriptionModel.canEdit}"
editorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/edit/#{text.key}"
hasUnusedLocales="#{!text.value.unusedLocales.isEmpty()}"
headingLevel="5"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/remove/#{text.key}"
sourceEditorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/edit-source/#{text.key}"
title="#{SciDepartmentMessageBundle.getMessage('texts.editor.header', [SciDepartmentTexts[text.key]])}"
unusedLocales="#{text.value.unusedLocales}"
variants="#{text.value.variants}"
variantsId="text-#{text.value.keyId}"
viewPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/view/#{text.key}"
/>
</c:forEach>
</c:otherwise>
</c:choose>
</ui:define>
<ui:define name="scripts">
<script src="#{request.contextPath}/assets/@scidepartment/scidepartment-contacts.js" />
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<div class="d-flex">
<a class="btn btn-secondary btn-sm align-self-center mr-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description">
<bootstrap:svgIcon icon="caret-left-fill" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.back']}</span>
</a>
<h2>#{SciDepartmentMessageBundle.getMessage('description_step.text.header.edit', [SciDepartmentTexts[SciDepartmentTextsModel.selectedText]])}</h2>
</div>
<c:if test="#{SciDepartmentDescriptionModel.canEdit}">
<librecms:cmsEditor
backUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description"
baseUrl="#{mvc.basePath}"
canEdit="#{SciDepartmentDescriptionModel.canEdit}"
contentSection="#{ContentSectionModel.sectionName}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-description/texts/edit/#{SciDepartmentTextsModel.selectedText}"
editorId="scidepartment-texts-editor"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"
selectedLocale="#{SciDepartmentTextsModel.selectedLocale}"
title="#{SciDepartmentMessageBundle.getMessage('texts.editor.header', [SciDepartmentTexts[SciDepartmentTextsModel.selectedText]])}"
variantUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@scidepartment-texts-resources/department-texts/#{SciDepartmentTextsModel.selectedText}"
/>
</c:if>
</ui:define>
<ui:define name="scripts">
<script src="#{request.contextPath}/assets/@content-sections/cms-editor.js"></script>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<div class="d-flex">
<a class="btn btn-secondary btn-sm align-self-center mr-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemName}/@department-description">
<bootstrap:svgIcon icon="caret-left-fill" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.back']}</span>
</a>
<h2>#{SciDepartmentMessageBundle.getMessage('description_step.texts.header.view', [SciDepartmentTexts[SciDepartmentTextsModel.selectedText]])}</h2>
</div>
<c:if test="#{SciDepartmentDescriptionModel.canEdit}">
<div class="text-right">
<a class="btn btn-secondary"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-description/texts/edit/#{SciDepartmentTextsModel.selectedText}">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{SciDepartmentMessageBundle['description_step.edit']}</span>
</a>
</div>
</c:if>
<div class="cms-text-preview article-text border p-2">
<h:outputText escape="false"
value="#{SciDepartmentTextsModel.texts.get(SciDepartmentTextsModel.selectedText).textValues.get(SciDepartmentTextsModel.selectedLocale)}" />
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,302 @@
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM (
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647),
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD (
REV integer not null,
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647) not null,
LOCALE varchar(255) not null,
REVTYPE tinyint,
REVEND integer,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS (
CONTACT_ID bigint not null,
CONTACT_TYPE varchar(255),
CONTACT_ORDER bigint,
CONTACTABLE_ID bigint,
DEPARTMENT_ID bigint,
primary key (CONTACT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD (
CONTACT_ID bigint not null,
REV integer not null,
REVTYPE tinyint,
REVEND integer,
CONTACT_TYPE varchar(255),
CONTACT_ORDER bigint,
CONTACTABLE_ID bigint,
DEPARTMENT_ID bigint,
primary key (CONTACT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS (
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647),
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD (
REV integer not null,
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647) not null,
LOCALE varchar(255) not null,
REVTYPE tinyint,
REVEND integer,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS (
MEMBERSHIP_ID bigint not null,
MEMBER_ROLE varchar(255),
STATUS varchar(255),
DEPARTMENT_ID bigint,
MEMBER_ID bigint,
primary key (MEMBERSHIP_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD (
MEMBERSHIP_ID bigint not null,
REV integer not null,
REVTYPE tinyint,
REVEND integer,
MEMBER_ROLE varchar(255),
STATUS varchar(255),
DEPARTMENT_ID bigint,
MEMBER_ID bigint,
primary key (MEMBERSHIP_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS (
DEPARTMENT_PROJECT_ID bigint not null,
DEPARTMENT_ID bigint,
PROJECT_ID bigint,
primary key (DEPARTMENT_PROJECT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD (
DEPARTMENT_PROJECT_ID bigint not null,
REV integer not null,
REVTYPE tinyint,
REVEND integer,
DEPARTMENT_ID bigint,
PROJECT_ID bigint,
primary key (DEPARTMENT_PROJECT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS (
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647),
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD (
REV integer not null,
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647) not null,
LOCALE varchar(255) not null,
REVTYPE tinyint,
REVEND integer,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES (
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647),
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD (
REV integer not null,
OBJECT_ID bigint not null,
LOCALIZED_VALUE varchar(2147483647) not null,
LOCALE varchar(255) not null,
REVTYPE tinyint,
REVEND integer,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS (
TEXT_ID bigint not null,
key varchar(255) not null,
CONTACT_ORDER bigint,
DEPARTMENT_ID bigint,
additionalTexts_KEY varchar(255),
primary key (TEXT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD (
TEXT_ID bigint not null,
REV integer not null,
REVTYPE tinyint,
REVEND integer,
key varchar(255),
CONTACT_ORDER bigint,
DEPARTMENT_ID bigint,
primary key (TEXT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENTS (
OBJECT_ID bigint not null,
primary key (OBJECT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENTS_AUD (
OBJECT_ID bigint not null,
REV integer not null,
primary key (OBJECT_ID, REV)
);
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM
add constraint FKkr6pwbcsp0qxafbxbgwqa11ay
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD
add constraint FKelrcnq39r31r0l519afl15qay
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD
add constraint FKl2uuj3krtky6ouk99n1vaujs4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS
add constraint FK61b1pvrsuxxt0ajyhmu6vgp8f
foreign key (CONTACTABLE_ID)
references CCM_CMS.CONTACTABLE_ENTITIES;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS
add constraint FK2rk6b5rwwhypbhlwxfvfg34bp
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD
add constraint FK7hxnvivdkm7ullkb3x33w89qa
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD
add constraint FKe2m5dgvrbh28yuetflg847k9p
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS
add constraint FKtkxxxyb2r0oeljttm3vg1ek1c
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD
add constraint FKtfrxdrq4x3fvne2qnum009h9m
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD
add constraint FKfoygb3t7vg4a6kwedec9gnfgc
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS
add constraint FKswvausrj6rpiuewwky4966o8w
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS
add constraint FKl7xexed4rkmd8849fs87wcikf
foreign key (MEMBER_ID)
references CCM_CMS.PERSONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD
add constraint FKnueow1dk4s148ddigm1smh5l6
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD
add constraint FKb4k1r14kxplvq5yvls3mc9wg7
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS
add constraint FK44ec63uxo6tfkbicbx7m0au9x
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS
add constraint FKqo3qvk46erndngcg3s9g5g0y2
foreign key (PROJECT_ID)
references SCI_TYPES_PROJECT.PROJECTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD
add constraint FKg2wdr3xj8vmctvusi9dmu6nby
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD
add constraint FKaail9qrssr6m2whdi85ill2xn
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS
add constraint FKhjjjhfgyubyc7dqv7cwylynib
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD
add constraint FK1avu0wp25u2qol0h6u8gv5itg
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD
add constraint FKjv8lhvqcodppyow6x7qqodbe4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES
add constraint FKq9e443yyn5x582n0gv8dkox2q
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD
add constraint FKbtj714r1oclsq27js49fpsfx1
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD
add constraint FKimyfv8v61io9kox2atqswk7iy
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS
add constraint FKc5fi9md95eldjfpeaqtfplqab
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD
add constraint FKb8ani402kr1vng8kdqhvaxum6
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD
add constraint FK1r1yt6d7l6g1xqgbmu6s2pdb4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENTS
add constraint FKmya9o3si7s3wu50quhlapy5dc
foreign key (OBJECT_ID)
references CCM_CMS.CONTENT_ITEMS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENTS_AUD
add constraint FKet2pdc2rct7iisg420vtworwm
foreign key (OBJECT_ID, REV)
references CCM_CMS.CONTENT_ITEMS_AUD;

View File

@ -0,0 +1,302 @@
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM (
OBJECT_ID int8 not null,
LOCALIZED_VALUE text,
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD (
REV int4 not null,
OBJECT_ID int8 not null,
LOCALIZED_VALUE text not null,
LOCALE varchar(255) not null,
REVTYPE int2,
REVEND int4,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS (
CONTACT_ID int8 not null,
CONTACT_TYPE varchar(255),
CONTACT_ORDER int8,
CONTACTABLE_ID int8,
DEPARTMENT_ID int8,
primary key (CONTACT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD (
CONTACT_ID int8 not null,
REV int4 not null,
REVTYPE int2,
REVEND int4,
CONTACT_TYPE varchar(255),
CONTACT_ORDER int8,
CONTACTABLE_ID int8,
DEPARTMENT_ID int8,
primary key (CONTACT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS (
OBJECT_ID int8 not null,
LOCALIZED_VALUE text,
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD (
REV int4 not null,
OBJECT_ID int8 not null,
LOCALIZED_VALUE text not null,
LOCALE varchar(255) not null,
REVTYPE int2,
REVEND int4,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS (
MEMBERSHIP_ID int8 not null,
MEMBER_ROLE varchar(255),
STATUS varchar(255),
DEPARTMENT_ID int8,
MEMBER_ID int8,
primary key (MEMBERSHIP_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD (
MEMBERSHIP_ID int8 not null,
REV int4 not null,
REVTYPE int2,
REVEND int4,
MEMBER_ROLE varchar(255),
STATUS varchar(255),
DEPARTMENT_ID int8,
MEMBER_ID int8,
primary key (MEMBERSHIP_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS (
DEPARTMENT_PROJECT_ID int8 not null,
DEPARTMENT_ID int8,
PROJECT_ID int8,
primary key (DEPARTMENT_PROJECT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD (
DEPARTMENT_PROJECT_ID int8 not null,
REV int4 not null,
REVTYPE int2,
REVEND int4,
DEPARTMENT_ID int8,
PROJECT_ID int8,
primary key (DEPARTMENT_PROJECT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS (
OBJECT_ID int8 not null,
LOCALIZED_VALUE text,
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD (
REV int4 not null,
OBJECT_ID int8 not null,
LOCALIZED_VALUE text not null,
LOCALE varchar(255) not null,
REVTYPE int2,
REVEND int4,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES (
OBJECT_ID int8 not null,
LOCALIZED_VALUE text,
LOCALE varchar(255) not null,
primary key (OBJECT_ID, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD (
REV int4 not null,
OBJECT_ID int8 not null,
LOCALIZED_VALUE text not null,
LOCALE varchar(255) not null,
REVTYPE int2,
REVEND int4,
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS (
TEXT_ID int8 not null,
key varchar(255) not null,
CONTACT_ORDER int8,
DEPARTMENT_ID int8,
additionalTexts_KEY varchar(255),
primary key (TEXT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD (
TEXT_ID int8 not null,
REV int4 not null,
REVTYPE int2,
REVEND int4,
key varchar(255),
CONTACT_ORDER int8,
DEPARTMENT_ID int8,
primary key (TEXT_ID, REV)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENTS (
OBJECT_ID int8 not null,
primary key (OBJECT_ID)
);
create table SCI_TYPES_DEPARTMENT.DEPARTMENTS_AUD (
OBJECT_ID int8 not null,
REV int4 not null,
primary key (OBJECT_ID, REV)
);
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM
add constraint FKkr6pwbcsp0qxafbxbgwqa11ay
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD
add constraint FKelrcnq39r31r0l519afl15qay
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_ADDENDUM_AUD
add constraint FKl2uuj3krtky6ouk99n1vaujs4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS
add constraint FK61b1pvrsuxxt0ajyhmu6vgp8f
foreign key (CONTACTABLE_ID)
references CCM_CMS.CONTACTABLE_ENTITIES;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS
add constraint FK2rk6b5rwwhypbhlwxfvfg34bp
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD
add constraint FK7hxnvivdkm7ullkb3x33w89qa
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_CONTACTS_AUD
add constraint FKe2m5dgvrbh28yuetflg847k9p
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS
add constraint FKtkxxxyb2r0oeljttm3vg1ek1c
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD
add constraint FKtfrxdrq4x3fvne2qnum009h9m
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_DESCS_AUD
add constraint FKfoygb3t7vg4a6kwedec9gnfgc
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS
add constraint FKswvausrj6rpiuewwky4966o8w
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS
add constraint FKl7xexed4rkmd8849fs87wcikf
foreign key (MEMBER_ID)
references CCM_CMS.PERSONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD
add constraint FKnueow1dk4s148ddigm1smh5l6
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_MEMBERSHIPS_AUD
add constraint FKb4k1r14kxplvq5yvls3mc9wg7
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS
add constraint FK44ec63uxo6tfkbicbx7m0au9x
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS
add constraint FKqo3qvk46erndngcg3s9g5g0y2
foreign key (PROJECT_ID)
references SCI_TYPES_PROJECT.PROJECTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD
add constraint FKg2wdr3xj8vmctvusi9dmu6nby
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_PROJECTS_AUD
add constraint FKaail9qrssr6m2whdi85ill2xn
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS
add constraint FKhjjjhfgyubyc7dqv7cwylynib
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD
add constraint FK1avu0wp25u2qol0h6u8gv5itg
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_SHORT_DESCS_AUD
add constraint FKjv8lhvqcodppyow6x7qqodbe4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES
add constraint FKq9e443yyn5x582n0gv8dkox2q
foreign key (OBJECT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD
add constraint FKbtj714r1oclsq27js49fpsfx1
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXT_VALUES_AUD
add constraint FKimyfv8v61io9kox2atqswk7iy
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS
add constraint FKc5fi9md95eldjfpeaqtfplqab
foreign key (DEPARTMENT_ID)
references SCI_TYPES_DEPARTMENT.DEPARTMENTS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD
add constraint FKb8ani402kr1vng8kdqhvaxum6
foreign key (REV)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENT_TEXTS_AUD
add constraint FK1r1yt6d7l6g1xqgbmu6s2pdb4
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENTS
add constraint FKmya9o3si7s3wu50quhlapy5dc
foreign key (OBJECT_ID)
references CCM_CMS.CONTENT_ITEMS;
alter table SCI_TYPES_DEPARTMENT.DEPARTMENTS_AUD
add constraint FKet2pdc2rct7iisg420vtworwm
foreign key (OBJECT_ID, REV)
references CCM_CMS.CONTENT_ITEMS_AUD;

View File

@ -0,0 +1,4 @@
groupId=${project.groupId}
artifactId=${project.artifactId}
version=${project.version}
build.date=${timestamp}

View File

@ -0,0 +1,3 @@
label=Department
description=Describes a department.

View File

@ -0,0 +1,3 @@
label=Abteillung
description=Beschreibung einer Abteilung oder eines Lehrstuhls.

View File

@ -0,0 +1,5 @@
member=Member
head=Department head
deputy_head=Deputy department head
associated_member=Associated member

View File

@ -0,0 +1,5 @@
member=Mitglied
head=Abteilungsleitung
deputy_head=Stellvertretende Abteilungsleitung
associated_member=Assoziertes Mitglied

View File

@ -0,0 +1,3 @@
scidepartment.research=Research
scidepartment.concept=Concept

View File

@ -0,0 +1,3 @@
scidepartment.research=Forschung
scidepartment.concept=Leitkonzept

View File

@ -0,0 +1,150 @@
createstep.description=Creates a new SciDepartment.
authoringsteps.description.description=Description of the department.
authoringsteps.description.label=Description
scidepartment.edit.denied=Access denied.
authoringsteps.basicproperties.description=Basicproperties of the department.
authoringsteps.basicproperties.label=Basic Properties
createstep.title=Create a new department description
createform.name.help=The name of the new department description. Also used as URL fragment.
createform.name.label=Name
createform.initial_locale.help=The initial locale of the department description.
createform.initial_locale.label=Summary
createform.title.help=The title of the department.
createform.title.label=Title
createform.summary.help=A summary of the description of the department.
createform.summary.label=Summary
createform.workflow.help=The workflow to use for the department description.
createform.workflow.label=Workflow
createform.cancel=Cancel
createform.submit=Create department
basicproperties.header=Edit basic properties of department {0}
basicproperties.name.header=Name
basicproperties.name.edit=Edit name
basicproperties.name.edit.title=Edit name
basicproperties.name.edit.close=Cancel
basicproperties.name.help=The name of the department. Also used as URL fragment.
basicproperties.name.label=Name
basicproperties.title.add=Add a localized title
basicproperties.title.add.cancel=Cancel
basicproperties.title.add.locale.help=The locale of the localized title.
basicproperties.title.add.locale.label=Locale
basicproperties.title.add.submit=Add
basicproperties.title.add.header=Add localized title
basicproperties.title.add.value.help=The localized title.
basicproperties.title.add.value.label=Title
basicproperties.title.edit=Edit
basicproperties.title.edit.cancel=Cancel
basicproperties.title.edit.submit=Save
basicproperties.title.edit.header=Edit localized title
basicproperties.title.edit.value.help=The localized title.
basicproperties.title.edit.value.label=Title
basicproperties.title.remove=Remove
basicproperties.title.remove.cancel=Cancel
basicproperties.title.remove.submit=Remove
basicproperties.title.remove.text=Are you sure to remove this localized title?
basicproperties.title.remove.header=Confirm removal of localized title
basicproperties.title.header=Title
basicproperties.shortdescription.add=Add
basicproperties.shortdescription.add.cancel=Cancel
basicproperties.shortdescription.add.locale.help=The locale of the localized short description.
basicproperties.shortdescription.add.locale.label=Locale
basicproperties.shortdescription.add.submit=Add
basicproperties.shortdescription.add.header=Add a localized short description
basicproperties.shortdescription.add.value.help=The localized short description.
basicproperties.shortdescription.add.value.label=Short description
basicproperties.shortdescription.edit=Edit
basicproperties.shortdescription.edit.cancel=Cancel
basicproperties.shortdescription.edit.submit=Save
basicproperties.shortdescription.edit.header=Edit localized short description
basicproperties.shortdescription.edit.value.help=The localized short description.
basicproperties.shortdescription.edit.value.label=Short description
basicproperties.shortdescription.remove=Remove
basicproperties.shortdescription.remove.cancel=Cancel
basicproperties.shortdescription.remove.submit=Remove
basicproperties.shortdescription.remove.text=Are you sure to remove this localized short description?
basicproperties.shortdescription.remove.header=Confirm removal of localized short description
basicproperties.shortdescription.header=Short description
description_step.header=Department Description
description_step.errors.contactable_not_found=The selected contactable entity {0} was not found.
description_step.errors.person_not_found=The selected person was not found.
description_step.errors.illegal_member_status_value=Illegal member status.
contacts.sort.errors.general=Error while sorting contacts.
contacts.sort.errors.save=Error while saving contact order.
description.editor.add_variant=Add localized description
description.editor.add.locale.help=The locale of the localized description.
description.editor.header=Description
contacts.header=Contacts
contacts.add_button.label=Add contact
contact.add.title=Add contact
contacts.type.help=The type of the contact.
contacts.type.label=Type
contacts.order.save.inprogress=Saving contacts order...
contacts.none=No contacts have been added yet.
contacts.cols.contactable=Contact
contacts.cols.type=Type
contacts.cols.actions=Actions
contacts.move.button=Move
contacts.edit.label=Edit
contacts.edit.title=Edit contact
contacts.edit.cancel=Cancel
contacts.edit.type.help=The type of the contact.
contacts.edit.type.label=Type
contacts.edit.submit=Save
contacts.delete.label=Remove
contacts.delete.cancel=Cancel
contacts.delete.confirm=Remove
contacts.delete.title=Confirm Removeal of Contact
contacts.delete.message=Are you sure to remove the contact {0} with type {1}?
memberships.header=Members
memberships.add_button.label=Add member
memberships.add.title=Add member
memberships.role.help=The role of the member.
memberships.role.label=Role
memberships.status.help=The status of the member.
memberships.status.label=Status
memberships.none=No member have been added yet.
memberships.cols.name=Name
memberships.cols.role=Role
memberships.cols.status=Status
memberships.cols.actions=Actions
memberships.edit.label=Edit
memberships.edit.cancel=Cancel
memberships.edit.role.help=The role of the member.
memberships.edit.role.label=Role
memberships.edit.status.help=The status of the member.
memberships.edit.status.label=Status
members.edit.cancel=Cancel
members.edit.submit=Save
memberships.delete.label=Remove
memberships.delete.cancel=Cancel
memberships.delete.confirm=Remove
memberships.delete.title=Confirm Removal of Member
memberships.delete.message=Are you sure to remove the member {0}?
texts.header=Additional texts
texts.add.label=Add text
texts.add.dialog.title=Add text
texts.add.cancel=Cancel
texts.add.key.help=The identifier of the text.
texts.add.key.label=Identifier
texts.add.submit=Add text
texts.none=No texts have been added yet.
texts.delete.label=Remove text
texts.delete.cancel=Cancel
texts.delete.confirm=Remove text
texts.delete.title=Confirm Removal of Text
texts.delete.message=Are you sure to remove the text {0}?
texts.editor.add_variant=Add localization
texts.editor.add.locale.help=The locale of the localized text.
texts.editor.header=Edit text {0}
description_step.back=Back
description_step.description.header.edit=Edit description
description_step.text.header.edit=Edit text {0}
description_step.texts.header.view=View text {0}
description_step.edit=Edit
description_step.description.header.view=Description
basicproperties.name.edit.submit=Save
contacts.order.save=Save order
members.status.active=Active
members.status.associated=Associated
members.status.former=Former

View File

@ -0,0 +1,150 @@
createstep.description=Erstellt eine neue Abteilung.
authoringsteps.description.description=Beschreibung der Abteilung.
authoringsteps.description.label=Beschreibung
scidepartment.edit.denied=Zugriff verweigert.
authoringsteps.basicproperties.description=Basiseigenschaften der Abteilung.
authoringsteps.basicproperties.label=Basiseigenschaften
createstep.title=Neue Abteilungsbeschriebung anlegen
createform.name.help=Der Name des neuen Abteilungsbeschreibung. Wird auch als URL-Fragment genutzt.
createform.name.label=Name
createform.initial_locale.help=Die initiale Sprache der Abteilungsbeschreibung.
createform.initial_locale.label=Zusammenfassung
createform.title.help=Der Titel des Abteilung.
createform.title.label=Titel
createform.summary.help=Eine Zusammenfassung der Beschreibung der Abteilung
createform.summary.label=Zusammenfassung
createform.workflow.help=Der Arbeitsablauf, der f\u00fcr die Abteilungsbeschreibung genutzt werden soll.
createform.workflow.label=Arbeitsablauf
createform.cancel=Abbrechen
createform.submit=Abteilung anlegen
basicproperties.header=Basiseigenschaften der Abteilung {0} bearbeiten
basicproperties.name.header=Name
basicproperties.name.edit=Name bearbeiten
basicproperties.name.edit.title=Name bearbeiten
basicproperties.name.edit.close=Abbrechen
basicproperties.name.help=Der Name der Abteilung. Wird auch als URL Fragment verwendet.
basicproperties.name.label=Name
basicproperties.title.add=Lokalisierten Titel hinzuf\u00fcgen
basicproperties.title.add.cancel=Abbrechen
basicproperties.title.add.locale.help=Die Sprache des lokalisierten Titels.
basicproperties.title.add.locale.label=Sprache
basicproperties.title.add.submit=Hinzuf\u00fcgen
basicproperties.title.add.header=Lokalisierten Titel hinzuf\u00fcgen
basicproperties.title.add.value.help=Der lokalisierte Titel.
basicproperties.title.add.value.label=Titel
basicproperties.title.edit=Bearbeiten
basicproperties.title.edit.cancel=Abbrechen
basicproperties.title.edit.submit=Speichern
basicproperties.title.edit.header=Lokalisierten Titel bearbeiten
basicproperties.title.edit.value.help=Der lokalisierte Titel
basicproperties.title.edit.value.label=Titel
basicproperties.title.remove=Entfernen
basicproperties.title.remove.cancel=Abbrechen
basicproperties.title.remove.submit=Entfernen
basicproperties.title.remove.text=Sind Sie sicher dass Sie diesen lokalisierten Titel entfernen wollen?
basicproperties.title.remove.header=Entfernen eines lokalisierten Titels best\u00e4tigen
basicproperties.title.header=Titel
basicproperties.shortdescription.add=Hinzuf\u00fcgen
basicproperties.shortdescription.add.cancel=Abbrechen
basicproperties.shortdescription.add.locale.help=Die Sprache der lokaliserten Kurzbeschreibung.
basicproperties.shortdescription.add.locale.label=Sprache
basicproperties.shortdescription.add.submit=Hinzuf\u00fcgen
basicproperties.shortdescription.add.header=Eine lokaliserte Kurzbeschreibung hinzuf\u00fcgen
basicproperties.shortdescription.add.value.help=Die lokalisierte Kurzbeschreibung.
basicproperties.shortdescription.add.value.label=Kurzbeschreibung
basicproperties.shortdescription.edit=Bearbeiten
basicproperties.shortdescription.edit.cancel=Abbrechen
basicproperties.shortdescription.edit.submit=Speichern
basicproperties.shortdescription.edit.header=Lokalisierte Kurzbeschreibung bearbeiten
basicproperties.shortdescription.edit.value.help=Die lokalisierte Kurzbeschreibung.
basicproperties.shortdescription.edit.value.label=Kurzbeschreibung
basicproperties.shortdescription.remove=Entfernen
basicproperties.shortdescription.remove.cancel=Abbrechen
basicproperties.shortdescription.remove.submit=Entfernen
basicproperties.shortdescription.remove.text=Sind Sie sicher, dass Sie diese lokaliserte Kurzbeschreibung entfernen wollen?
basicproperties.shortdescription.remove.header=Entfernen einer lokalisierten Kurzbeschreibung best\u00e4tigen
basicproperties.shortdescription.header=Kurzbeschreibung
description_step.header=Beschreibung der Abteilung
description_step.errors.contactable_not_found=Die ausgew\u00e4hlte Person oder Organisation {0} konnte nicht gefunden werden.
description_step.errors.person_not_found=Die ausgew\u00e4hlte Person konnte nicht gefunden werden.
description_step.errors.illegal_member_status_value=Fehlerhafter Status f\u00fcr Mitglied.
contacts.sort.errors.general=Fehler beim Sortieren der Kontakte.
contacts.sort.errors.save=Die Sortierung der Kontakte konnte nicht gespeichert werden.
description.editor.add_variant=Lokalisierte Beschreibung hinzuf\u00fcgen
description.editor.add.locale.help=Die Sprache der lokalisierten Beschreibung.
description.editor.header=Beschreibung
contacts.header=Kontakte
contacts.add_button.label=Kontakt hinzuf\u00fcgen
contact.add.title=Kontakt hinzuf\u00fcgen
contacts.type.help=Der Typ des Kontakts.
contacts.type.label=Typ
contacts.order.save.inprogress=Speichere Sortierung der Kontakte...
contacts.none=Es wurden noch keine Kontakte hinzugef\u00fcgt.
contacts.cols.contactable=Kontakt
contacts.cols.type=Typ
contacts.cols.actions=Aktionen
contacts.move.button=Verschieben
contacts.edit.label=Bearbeiten
contacts.edit.title=Kontakt bearbeiten
contacts.edit.cancel=Abbrechen
contacts.edit.type.help=Der Typ des Kontakts.
contacts.edit.type.label=Typ
contacts.edit.submit=Speichern
contacts.delete.label=Entfernen
contacts.delete.cancel=Abbrechen
contacts.delete.confirm=Entfernen
contacts.delete.title=Entfernen des Kontaktes best\u00e4tigen
contacts.delete.message=Sind Sie sicher das Sie den Kontakt {0} (Typ: {1}) entfernen wollen?
memberships.header=Mitglieder
memberships.add_button.label=Mitglied hinzuf\u00fcgen
memberships.add.title=Mitglied hinzuf\u00fcgen
memberships.role.help=Die Rolle des Mitglieds.
memberships.role.label=Rolle
memberships.status.help=Der Status des Mitglieds.
memberships.status.label=Status
memberships.none=Es wurden noch keine Mitglieder hinzugef\u00fcgt.
memberships.cols.name=Name
memberships.cols.role=Rolle
memberships.cols.status=Status
memberships.cols.actions=Aktionen
memberships.edit.label=Bearbeiten
memberships.edit.cancel=Abbrechen
memberships.edit.role.help=Die Rolle des Mitglieds.
memberships.edit.role.label=Rolle
memberships.edit.status.help=Der Status des Mitglieds.
memberships.edit.status.label=Status
members.edit.cancel=Abbrechen
members.edit.submit=Speichern
memberships.delete.label=Entfernen
memberships.delete.cancel=Abbrechen
memberships.delete.confirm=Entfernen
memberships.delete.title=Entfernen des Mitglieds best\u00e4tigen
memberships.delete.message=Sind Sie sicher, dass Sie das Mitglied {0} entfernen wollen?
texts.header=Weitere Texte
texts.add.label=Text hinzuf\u00fcgen
texts.add.dialog.title=Text hinzuf\u00fcgen
texts.add.cancel=Abbrechen
texts.add.key.help=Bezeichner des Textes.
texts.add.key.label=Bezeichner
texts.add.submit=Text hinzuf\u00fcgen
texts.none=Es wurden noch keine Texte hinzugef\u00fcgt.
texts.delete.label=Text entfernen
texts.delete.cancel=Abbrechen
texts.delete.confirm=Text entfernen
texts.delete.title=Entfernen des Textes best\u00e4tigen
texts.delete.message=Sind Sie sicher, dass Sie den Text {0} entfernen wollen?
texts.editor.add_variant=\u00dcbersetzung hinzuf\u00fcgen
texts.editor.add.locale.help=Die Sprache der \u00dcbersetzung.
texts.editor.header=Text {0} bearbeiten
description_step.back=Zur\u00fcck
description_step.description.header.edit=Beschreibung bearbeiten
description_step.text.header.edit=Text {0} bearbeiten
description_step.texts.header.view=Text {0}
description_step.edit=Bearbeiten
description_step.description.header.view=Beschreibung
basicproperties.name.edit.submit=Speichern
contacts.order.save=Sortierung speichern
members.status.active=Aktiv
members.status.associated=Assoziert
members.status.former=Ehemalig

View File

@ -0,0 +1,152 @@
import Sortable, { SortableEvent } from "sortablejs";
let contactsSortable: Sortable;
document.addEventListener("DOMContentLoaded", function (event) {
const contactsTable = document.querySelector(
"#scidepartment-contacts-table tbody"
);
if (contactsTable) {
contactsSortable = initContactsTable(contactsTable as HTMLElement);
}
const saveOrderButtons = document.querySelectorAll(
".contacts-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) {
saveOrderButtons[i].addEventListener("click", saveOrder);
}
});
function initContactsTable(contactsTable: HTMLElement): Sortable {
return new Sortable(contactsTable, {
animation: 150,
group: "scidepartment-contact",
handle: ".cms-sort-handle",
onEnd: enableSaveButton,
});
}
function enableSaveButton(event: SortableEvent) {
const saveOrderButtons = document.querySelectorAll(
".contacts-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = false;
}
}
function saveOrder() {
const contactsTable = document.querySelector("#scidepartment-contacts-table");
if (!contactsTable) {
showGeneralError();
throw Error("scidepartment-contacts-table not found");
}
const saveUrl = contactsTable.getAttribute("data-saveUrl");
if (!saveUrl) {
showGeneralError();
throw Error(
"data-saveUrl on scidepartment-contacts-table container is missing or empty"
);
}
const saveOrderButtons = document.querySelectorAll(
".contacts-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = true;
const saveIcon = saveOrderButton.querySelector(".save-icon");
const spinner = saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none");
}
const headers = new Headers();
headers.append("Content-Type", "application/json");
fetch(saveUrl, {
credentials: "include",
body: JSON.stringify(contactsSortable.toArray()),
headers,
method: "POST",
})
.then((response) => {
if (response.ok) {
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
const saveIcon =
saveOrderButton.querySelector(".save-icon");
const spinner =
saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none");
}
} else {
showSaveError();
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = false;
const saveIcon =
saveOrderButton.querySelector(".save-icon");
const spinner =
saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none");
}
throw Error(
`Failed to save contacts order. Response status: ${response.status}, statusText: ${response.statusText}`
);
}
})
.catch((error) => {
showSaveError();
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = false;
const saveIcon = saveOrderButton.querySelector(".save-icon");
const spinner = saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none");
}
throw new Error(`Failed to save contacts order: ${error}`);
});
}
function showGeneralError(): void {
const alertTemplate = document.querySelector(
"#scidepartment-contacts-sort-error-general"
) as HTMLTemplateElement;
const alert = alertTemplate.content.cloneNode(true) as Element;
const container = document.querySelector("#messages");
if (container) {
container.appendChild(alert);
}
}
function showSaveError(): void {
const alertTemplate = document.querySelector(
"#scidepartment-contacts-sort-error-save"
) as HTMLTemplateElement;
const alert = alertTemplate.content.cloneNode(true) as Element;
const container = document.querySelector("#messages");
if (container) {
container.appendChild(alert);
}
}

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"lib": [
"DOM",
"ES2016"
],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "target/generated-resources/assets/@scidepartment",
"sourceMap": true,
"strict": true,
"target": "ES6"
},
"include": [
"src/main/typescript/**/*"
]
}

View File

@ -0,0 +1,23 @@
module.exports = {
mode: "development",
devtool: "source-map",
optimization: {
chunkIds: false
},
entry: {
"scidepartment-contacts": "./src/main/typescript/scidepartment-contacts.ts"
},
output: {
filename: "[name].js",
path: __dirname + "/target/generated-resources/assets/@scidepartment"
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".json"]
},
module: {
rules: [
// all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
{ test: /\.tsx?$/, use: ["ts-loader"], exclude: /node_modules/ }
]
}
}

View File

@ -30,7 +30,7 @@ import static org.scientificcms.contenttypes.sciproject.SciProjectConstants.*;
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Entity(name = "ProjectContact")
@Audited
@Table(name = "PROJECT_CONTACTS", schema = DB_SCHEMA)
@JsonIdentityInfo(

View File

@ -32,7 +32,7 @@ import static org.scientificcms.contenttypes.sciproject.SciProjectConstants.*;
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Entity(name = "PROJECT_MEMBERSHIP")
@Audited
@Table(name = "PROJECT_MEMBERSHIPS", schema = DB_SCHEMA)
@JsonIdentityInfo(

View File

@ -7,7 +7,6 @@ package org.scientificcms.contenttypes.sciproject;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import javax.persistence.Entity;
@ -89,7 +88,7 @@ import static org.scientificcms.contenttypes.sciproject.SciProjectConstants.*;
),
@NamedQuery(
name = "SciProject.findByMember",
query = "SELECT p FROM SciProject p JOIN Membership m "
query = "SELECT p FROM SciProject p JOIN p.members m "
+ "WHERE m.member = :member"
)
})

View File

@ -23,7 +23,7 @@ public class SciProjectConfig {
@Setting
private String memberRolesBundleName
= "org.scientificcms.contenttypes.sciproject.MemberRoles";
= "org.scientificcms.contenttypes.sciproject.DefaultMemberRoles";
@Setting
private boolean enableSponsor = true;

View File

@ -9,7 +9,6 @@ import org.librecms.assets.ContactableEntity;
import org.librecms.assets.Organization;
import org.librecms.assets.Person;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.ui.contentsections.ContentSectionsUi;
import java.io.Serializable;
import java.util.Objects;

View File

@ -11,7 +11,6 @@ import org.librecms.contentsection.ContentItemRepository;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

View File

@ -0,0 +1,29 @@
package org.scientificcms.contenttypes.sciproject.ui;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.ui.AbstractMessagesBean;
import org.scientificcms.contenttypes.sciproject.SciProjectConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciProjectContactTypes")
public class SciProjectContactTypes extends AbstractMessagesBean {
@Inject
private ConfigurationManager confManager;
@Override
protected String getMessageBundle() {
return confManager
.findConfiguration(SciProjectConfig.class)
.getContactTypesBundleName();
}
}

View File

@ -76,7 +76,7 @@ public class SciProjectDescriptionStepService {
)
);
if ((document instanceof SciProject)) {
if (!(document instanceof SciProject)) {
throw new BadRequestException(
String.format(
"Document %s is not a %s.",

View File

@ -0,0 +1,29 @@
package org.scientificcms.contenttypes.sciproject.ui;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.ui.AbstractMessagesBean;
import org.scientificcms.contenttypes.sciproject.SciProjectConfig;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("SciProjectRoles")
public class SciProjectRoles extends AbstractMessagesBean {
@Inject
private ConfigurationManager confManager;
@Override
protected String getMessageBundle() {
return confManager
.findConfiguration(SciProjectConfig.class)
.getMemberRolesBundleName();
}
}

View File

@ -31,6 +31,7 @@
<h:outputText escape="false"
value="#{SciProjectDescriptionModel.descriptionValues.get(SciProjectDescriptionModel.selectedLocale)}" />
</div>
</ui:define>
</ui:composition>

View File

@ -80,11 +80,12 @@
contentSection="#{ContentSectionModel.sectionName}"
dialogTitle="#{SciProjectMessageBundle['contact.add.title']}"
formParamName="contactableUuid">
<bootstrap:formGroupText
<bootstrap:formGroupSelect
help="#{SciProjectMessageBundle['contacts.type.help']}"
inputId="type"
label="#{SciProjectMessageBundle['contacts.type.label']}"
name="type"
options="#{SciProjectContactTypes}"
/>
</librecms:assetPicker>
<button class="btn btn-secondary contacts-save-order-button"
@ -133,7 +134,7 @@
</c:if>
#{contact.contactable}
</td>
<td>#{contact.contactType}</td>
<td>#{SciProjectContactTypes[contact.contactType]}</td>
<td>
<button class="btn btn-secondary"
data-toggle="modal"
@ -149,7 +150,7 @@
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-description/contacts/edit/#{contact.contactId}"
class="modal-content"
class="modal-content"
method="post">
<div class="modal-header">
<h4 class="modal-title"
@ -165,12 +166,13 @@
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText
<bootstrap:formGroupSelect
help="#{SciProjectMessageBundle['contacts.edit.type.help']}"
inputId="type-edit"
label="#{SciProjectMessageBundle['contacts.edit.type.label']}"
name="type"
value="#{contact.contactType}"
options="#{SciProjectContactTypes}"
selectedOptions="#{[contact.contactType]}"
/>
</div>
<div class="modal-footer">
@ -226,11 +228,12 @@
dialogTitle="#{SciProjectMessageBundle['memberships.add.title']}"
formParamName="personUuid">
<bootstrap:formGroupText
<bootstrap:formGroupSelect
help="#{SciProjectMessageBundle['memberships.role.help']}"
inputId="type"
inputId="role"
label="#{SciProjectMessageBundle['memberships.role.label']}"
name="role"
options="#{SciProjectRoles}"
/>
<bootstrap:formGroupSelect
@ -265,7 +268,7 @@
#{member.name}
</td>
<td>
#{member.role}
#{SciProjectRoles[member.role]}
</td>
<td>
#{member.status}
@ -300,12 +303,13 @@
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText
help="#{SciProjectMessageBundle['memberships.edit.role.help']}"
<bootstrap:formGroupSelect
help="#{SciProjectMessageBundle['memberships.role.help']}"
inputId="role"
label="#{SciProjectMessageBundle['memberships.edit.role.label']}"
label="#{SciProjectMessageBundle['memberships.role.label']}"
name="role"
value="#{member.role}"
options="#{SciProjectRoles}"
selectedOptions="#{[member.role]}"
/>
<bootstrap:formGroupSelect

View File

@ -0,0 +1,5 @@
member=Member
head=Department head
deputy_head=Deputy department head
associated_member=Associated member

View File

@ -0,0 +1,5 @@
member=Mitglied
head=Abteilungsleitung
deputy_head=Stellvertretende Abteilungsleitung
associated_member=Assoziertes Mitglied

View File

@ -8,7 +8,7 @@ basicproperties.name.header=Name
basicproperties.name.edit=Name bearbeiten
basicproperties.name.edit.title=Name bearbeiten
basicproperties.name.edit.close=Abbrechen
basicproperties.name.help=Der Name des Projektes. Wird auch als URL fragment verwendet.
basicproperties.name.help=Der Name des Projektes. Wird auch als URL Fragment verwendet.
basicproperties.name.label=Name
basicproperties.name.edit.submit=Speichern
basicproperties.title.add=Lokalisierten Titel hinzuf\u00fcgen
@ -29,7 +29,7 @@ basicproperties.title.remove=Entfernen
basicproperties.title.remove.cancel=Abbrechen
basicproperties.title.remove.submit=Entfernen
basicproperties.title.remove.text=Sind Sie sicher dass Sie diesen lokalisierten Titel entfernen wollen?
basicproperties.title.remove.header=Entfernen eines lokalisierten Titels entfernen
basicproperties.title.remove.header=Entfernen eines lokalisierten Titels best\u00e4tigen
basicproperties.title.header=Titel
basicproperties.begin.header=Beginn des Projektes
basicproperties.begin.edit=Bearbeiten

View File

@ -0,0 +1 @@
runtime.properties

View File

@ -230,6 +230,22 @@
<include>scripts/</include>
</includes>
</overlay>-->
<overlay>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-department</artifactId>
<type>jar</type>
<includes>
<include>assets/</include>
</includes>
</overlay>
<overlay>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-department</artifactId>
<type>jar</type>
<includes>
<include>WEB-INF/</include>
</includes>
</overlay>
<overlay>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-project</artifactId>

View File

@ -1,7 +0,0 @@
libreccm.debug.suspend=n
libreccm.database.host=localhost
libreccm.database.port=5432
libreccm.database.name=scicms-devel
libreccm.database.user=ccm
libreccm.database.password=ccm47web

View File

@ -25,6 +25,7 @@
<jar-file>lib/ccm-cms-7.0.0-SNAPSHOT.jar</jar-file>
<jar-file>lib/ccm-shortcuts-7.0.0-SNAPSHOT.jar</jar-file>
<jar-file>lib/sci-publications-7.0.0-SNAPSHOT.jar</jar-file>
<jar-file>lib/sci-types-department-7.0.0-SNAPSHOT.jar</jar-file>
<jar-file>lib/sci-types-project-7.0.0-SNAPSHOT.jar</jar-file>
<properties>

View File

@ -63,6 +63,11 @@
<artifactId>sci-publications</artifactId>
<version>7.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-department</artifactId>
<version>7.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.scientificcms</groupId>
<artifactId>sci-types-project</artifactId>