Skip to content

Commit 031a67b

Browse files
authored
Merge CSS/JS Options for sites Meeds-io/MIPs#167 (#21)
2 parents 0dd95fc + 5a30bc3 commit 031a67b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2457
-61
lines changed

crowdin.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,41 @@ files: [
3232
"update_option" : "update_as_unapproved",
3333
"escape_special_characters": 0,
3434
"escape_quotes" : 0,
35+
},
36+
{
37+
"source": "/ide-webapp/src/main/resources/locale/portlet/SiteManagement_en.properties",
38+
39+
"translation": "%original_path%/%file_name%!_%locale_with_underscore%.%file_extension%",
40+
"translation_replace": {
41+
"_en!": "","ar_SA": "ar","ar_OM": "aro","az_AZ": "az","ca_ES": "ca","ceb_PH": "ceb",
42+
"co_FR": "co","cs_CZ": "cs","de_DE": "de","el_GR": "el","en_US": "en","es_ES": "es_ES","eu_ES": "eu","fa_IR": "fa",
43+
"fi_FI": "fi","fil_PH": "fil","fr_FR": "fr","hi_IN": "hi","hu_HU": "hu","id_ID": "id","it_IT": "it","ja_JP": "ja",
44+
"kab_KAB": "kab","ko_KR": "ko","lt_LT": "lt","ms_MY": "ms","nl_NL": "nl","no_NO": "no","pcm_NG": "pcm","pl_PL": "pl",
45+
"pt_BR": "pt_BR","pt_PT": "pt_PT","ro_RO": "ro","ru_RU": "ru","sk_SK": "sk","sl_SI": "sl","sq_AL": "sq",
46+
"sv_SE": "sv_SE","th_TH": "th","tl_PH": "tl","tr_TR": "tr","uk_UA": "uk","ur_IN": "ur_IN","vi_VN": "vi",
47+
"zh_CN": "zh_CN","zh_TW": "zh_TW",
48+
},
49+
"dest": "hub/ide/SiteManagement.properties",
50+
"update_option": "update_as_unapproved",
51+
"escape_special_characters": 0,
52+
"escape_quotes": 0,
53+
},
54+
{
55+
"source": "/ide-webapp/src/main/resources/locale/portlet/Analytics_en.properties",
56+
57+
"translation": "%original_path%/%file_name%!_%locale_with_underscore%.%file_extension%",
58+
"translation_replace": {
59+
"_en!": "","ar_SA": "ar","ar_OM": "aro","az_AZ": "az","ca_ES": "ca","ceb_PH": "ceb",
60+
"co_FR": "co","cs_CZ": "cs","de_DE": "de","el_GR": "el","en_US": "en","es_ES": "es_ES","eu_ES": "eu","fa_IR": "fa",
61+
"fi_FI": "fi","fil_PH": "fil","fr_FR": "fr","hi_IN": "hi","hu_HU": "hu","id_ID": "id","it_IT": "it","ja_JP": "ja",
62+
"kab_KAB": "kab","ko_KR": "ko","lt_LT": "lt","ms_MY": "ms","nl_NL": "nl","no_NO": "no","pcm_NG": "pcm","pl_PL": "pl",
63+
"pt_BR": "pt_BR","pt_PT": "pt_PT","ro_RO": "ro","ru_RU": "ru","sk_SK": "sk","sl_SI": "sl","sq_AL": "sq",
64+
"sv_SE": "sv_SE","th_TH": "th","tl_PH": "tl","tr_TR": "tr","uk_UA": "uk","ur_IN": "ur_IN","vi_VN": "vi",
65+
"zh_CN": "zh_CN","zh_TW": "zh_TW",
66+
},
67+
"dest": "hub/ide/Analytics.properties",
68+
"update_option": "update_as_unapproved",
69+
"escape_special_characters": 0,
70+
"escape_quotes": 0,
3571
}
3672
]

ide-service/pom.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<rest.api.doc.version>1.0</rest.api.doc.version>
3737
<rest.api.doc.description>Widget IDE endpoints</rest.api.doc.description>
3838

39-
<exo.test.coverage.ratio>0.95</exo.test.coverage.ratio>
39+
<exo.test.coverage.ratio>0.87</exo.test.coverage.ratio>
4040
</properties>
4141
<dependencies>
4242
<dependency>
@@ -47,7 +47,11 @@
4747
<groupId>io.meeds.layout</groupId>
4848
<artifactId>layout-service</artifactId>
4949
</dependency>
50-
50+
<dependency>
51+
<groupId>io.meeds.analytics</groupId>
52+
<artifactId>analytics-api</artifactId>
53+
<scope>provided</scope>
54+
</dependency>
5155
<dependency>
5256
<groupId>org.springframework.boot</groupId>
5357
<artifactId>spring-boot-starter-test</artifactId>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* This file is part of the Meeds project (https://meeds.io/).
3+
*
4+
* Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this program; if not, write to the Free Software Foundation,
16+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*
18+
*/
19+
package io.meeds.ide.constant;
20+
21+
public enum WidgetType {
22+
APP, CSS, JS
23+
}

ide-service/src/main/java/io/meeds/ide/dao/WidgetDAO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
package io.meeds.ide.dao;
2020

2121
import org.springframework.data.jpa.repository.JpaRepository;
22+
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
2223
import org.springframework.stereotype.Repository;
2324

2425
import io.meeds.ide.entity.WidgetEntity;
2526

2627
@Repository
27-
public interface WidgetDAO extends JpaRepository<WidgetEntity, Long> {
28+
public interface WidgetDAO extends JpaRepository<WidgetEntity, Long>, JpaSpecificationExecutor<WidgetEntity> {
2829

2930
boolean existsByPortletId(Long id);
3031

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* This file is part of the Meeds project (https://meeds.io/).
3+
*
4+
* Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
* You should have received a copy of the GNU Lesser General Public License
15+
* along with this program; if not, write to the Free Software Foundation,
16+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*
18+
*/
19+
package io.meeds.ide.dao.query;
20+
21+
import io.meeds.ide.entity.WidgetEntity;
22+
import jakarta.persistence.criteria.*;
23+
import org.springframework.data.jpa.domain.Specification;
24+
25+
import java.util.Map;
26+
import java.util.Objects;
27+
28+
public class WidgetQueryBuilder {
29+
30+
private WidgetQueryBuilder() {
31+
// Static Utils methods
32+
}
33+
34+
public static Specification<WidgetEntity> hasProperties(Map<String, String> properties) {
35+
return (Root<WidgetEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
36+
Predicate finalPredicate = cb.conjunction();
37+
38+
for (Map.Entry<String, String> entry : properties.entrySet()) {
39+
Subquery<Long> subquery = Objects.requireNonNull(query).subquery(Long.class);
40+
Root<WidgetEntity> subRoot = subquery.from(WidgetEntity.class);
41+
MapJoin<WidgetEntity, String, String> subPropertiesJoin = subRoot.joinMap("properties");
42+
43+
subquery.select(cb.literal(1L))
44+
.where(cb.equal(subRoot.get("id"), root.get("id")),
45+
cb.equal(subPropertiesJoin.key(), entry.getKey()),
46+
cb.equal(subPropertiesJoin.value(), entry.getValue()));
47+
48+
finalPredicate = cb.and(finalPredicate, cb.exists(subquery));
49+
}
50+
51+
return finalPredicate;
52+
};
53+
}
54+
}

ide-service/src/main/java/io/meeds/ide/entity/WidgetEntity.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,10 @@
1919
package io.meeds.ide.entity;
2020

2121
import java.time.LocalDateTime;
22+
import java.util.Map;
2223

23-
import jakarta.persistence.Column;
24-
import jakarta.persistence.Entity;
25-
import jakarta.persistence.GeneratedValue;
26-
import jakarta.persistence.GenerationType;
27-
import jakarta.persistence.Id;
28-
import jakarta.persistence.SequenceGenerator;
29-
import jakarta.persistence.Table;
24+
import io.meeds.ide.constant.WidgetType;
25+
import jakarta.persistence.*;
3026
import lombok.AllArgsConstructor;
3127
import lombok.Data;
3228
import lombok.NoArgsConstructor;
@@ -42,30 +38,40 @@ public class WidgetEntity {
4238
@SequenceGenerator(name = "SEQ_IDE_WIDGET_ID", sequenceName = "SEQ_IDE_WIDGET_ID", allocationSize = 1)
4339
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_IDE_WIDGET_ID")
4440
@Column(name = "ID")
45-
protected Long id;
41+
protected Long id;
4642

4743
@Column(name = "PORTLET_ID")
48-
protected Long portletId;
44+
protected Long portletId;
4945

5046
@Column(name = "HTML")
51-
private String html;
47+
private String html;
5248

5349
@Column(name = "CSS")
54-
private String css;
50+
private String css;
5551

5652
@Column(name = "JS")
57-
private String js;
53+
private String js;
5854

5955
@Column(name = "CREATOR_ID")
60-
protected Long creatorId;
56+
protected Long creatorId;
6157

6258
@Column(name = "MODIFIER_ID")
63-
protected Long modifierId;
59+
protected Long modifierId;
6460

6561
@Column(name = "MODIFIED_DATE")
66-
protected LocalDateTime modifiedDate;
62+
protected LocalDateTime modifiedDate;
6763

6864
@Column(name = "CREATED_DATE")
69-
protected LocalDateTime createdDate;
65+
protected LocalDateTime createdDate;
66+
67+
@Enumerated(EnumType.ORDINAL)
68+
@Column(name = "TYPE", nullable = false)
69+
protected WidgetType type;
70+
71+
@ElementCollection(fetch = FetchType.EAGER)
72+
@MapKeyColumn(name = "NAME")
73+
@Column(name = "VALUE")
74+
@CollectionTable(name = "IDE_WIDGETS_SETTINGS", joinColumns = { @JoinColumn(name = "ID") })
75+
private Map<String, String> properties;
7076

7177
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* This file is part of the Meeds project (https://meeds.io/).
3+
*
4+
* Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
package io.meeds.ide.listener;
20+
21+
import static io.meeds.analytics.utils.AnalyticsUtils.addStatisticData;
22+
import static io.meeds.ide.service.StaticResourceService.SITE_NAME;
23+
import static io.meeds.ide.service.WidgetService.IDE_WIDGET_CREATED_EVENT;
24+
25+
import io.meeds.ide.model.Widget;
26+
import org.apache.commons.collections.MapUtils;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.context.annotation.Profile;
29+
import org.springframework.stereotype.Component;
30+
31+
import org.exoplatform.services.listener.Asynchronous;
32+
import org.exoplatform.services.listener.Event;
33+
import org.exoplatform.services.listener.Listener;
34+
import org.exoplatform.services.listener.ListenerService;
35+
36+
import io.meeds.analytics.model.StatisticData;
37+
import jakarta.annotation.PostConstruct;
38+
39+
@Asynchronous
40+
@Component
41+
@Profile("layout")
42+
public class StaticResourcesAnalyticsListener extends Listener<String, Widget> {
43+
44+
private static final String STATISTICS_TYPE_PARAM = "type";
45+
46+
@Autowired
47+
private ListenerService listenerService;
48+
49+
@PostConstruct
50+
public void init() {
51+
listenerService.addListener(IDE_WIDGET_CREATED_EVENT, this);
52+
}
53+
54+
@Override
55+
public void onEvent(Event<String, Widget> event) {
56+
Widget widget = event.getData();
57+
if (widget == null || MapUtils.isEmpty(widget.getProperties())) {
58+
return;
59+
}
60+
StatisticData statisticData = new StatisticData();
61+
statisticData.setModule("portal");
62+
statisticData.setSubModule("layout");
63+
statisticData.setOperation("addStatisticResource");
64+
statisticData.setUserId(widget.getCreatorId());
65+
statisticData.addParameter(SITE_NAME, widget.getProperties().get(SITE_NAME));
66+
statisticData.addParameter(STATISTICS_TYPE_PARAM, widget.getType());
67+
addStatisticData(statisticData);
68+
}
69+
}

ide-service/src/main/java/io/meeds/ide/model/Widget.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
package io.meeds.ide.model;
2020

2121
import java.time.LocalDateTime;
22+
import java.util.Map;
2223

24+
import io.meeds.ide.constant.WidgetType;
2325
import lombok.AllArgsConstructor;
2426
import lombok.Data;
2527
import lombok.NoArgsConstructor;
@@ -29,25 +31,29 @@
2931
@Data
3032
public class Widget {
3133

32-
protected Long id;
34+
protected Long id;
3335

3436
/**
3537
* Portlet instance identifier
3638
*/
37-
protected Long portletId;
39+
protected Long portletId;
3840

39-
private String html;
41+
private String html;
4042

41-
private String css;
43+
private String css;
4244

43-
private String js;
45+
private String js;
4446

45-
protected Long creatorId;
47+
protected Long creatorId;
4648

47-
protected Long modifierId;
49+
protected Long modifierId;
4850

49-
protected LocalDateTime modifiedDate;
51+
protected LocalDateTime modifiedDate;
5052

51-
protected LocalDateTime createdDate;
53+
protected LocalDateTime createdDate;
54+
55+
protected WidgetType type;
56+
57+
private Map<String, String> properties;
5258

5359
}

0 commit comments

Comments
 (0)