@eeacms/volto-slate-footnote 6.1.8 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -1
- package/Dockerfile +1 -1
- package/Jenkinsfile +160 -134
- package/Makefile +33 -2
- package/cypress.config.js +3 -3
- package/package.json +1 -1
- package/src/Blocks/Footnote/FootnotesBlockView.jsx +51 -5
- package/src/editor/FootnoteEditor.jsx +0 -1
- package/src/editor/extensions.js +1 -2
- package/src/editor/render.jsx +15 -7
- package/src/editor/utils.js +71 -34
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,35 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
-
### [6.1
|
|
7
|
+
### [6.2.1](https://github.com/eea/volto-slate-footnote/compare/6.2.0...6.2.1) - 18 January 2024
|
|
8
|
+
|
|
9
|
+
#### :bug: Bug Fixes
|
|
10
|
+
|
|
11
|
+
- fix: check if element exists when rendering extensions - refs #263143 [ana-oprea - [`9677db5`](https://github.com/eea/volto-slate-footnote/commit/9677db52435ab710e8a4d54720583eda0db7bd69)]
|
|
12
|
+
|
|
13
|
+
### [6.2.0](https://github.com/eea/volto-slate-footnote/compare/6.1.8...6.2.0) - 17 January 2024
|
|
14
|
+
|
|
15
|
+
#### :rocket: New Features
|
|
16
|
+
|
|
17
|
+
- feat: Allow footnotes work on complex blocks such as statistics, accordion, tabs, where nested data is present - refs #261770 [dobri1408 - [`66363d3`](https://github.com/eea/volto-slate-footnote/commit/66363d3d64cde426c99f0e9f0ecad59816a80552)]
|
|
18
|
+
- feat(popup): is now accessible by keyboard tabbing [David Ichim - [`3649da0`](https://github.com/eea/volto-slate-footnote/commit/3649da0d381ae8a76b77c8a34a6217a72a0c3709)]
|
|
19
|
+
|
|
20
|
+
#### :bug: Bug Fixes
|
|
21
|
+
|
|
22
|
+
- fix: footnote error in statistic block - refs #261770 [dobri1408 - [`3cf696c`](https://github.com/eea/volto-slate-footnote/commit/3cf696c44dbb84fc54935acf3d5951ac2c198d88)]
|
|
23
|
+
|
|
24
|
+
#### :house: Internal changes
|
|
25
|
+
|
|
26
|
+
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`5a5e1ad`](https://github.com/eea/volto-slate-footnote/commit/5a5e1adf997af84e93a4015dc66b7299abba0874)]
|
|
27
|
+
|
|
28
|
+
#### :hammer_and_wrench: Others
|
|
29
|
+
|
|
30
|
+
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`af6d78f`](https://github.com/eea/volto-slate-footnote/commit/af6d78f60dd040fe61ebb225f4a689ac21ffb55c)]
|
|
31
|
+
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`7f4c07f`](https://github.com/eea/volto-slate-footnote/commit/7f4c07f1fc2e9893d1f925152a473855a7e0f064)]
|
|
32
|
+
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`0670217`](https://github.com/eea/volto-slate-footnote/commit/0670217cca01571e8a3bd64ee3d85bb53ce447be)]
|
|
33
|
+
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`ec08749`](https://github.com/eea/volto-slate-footnote/commit/ec08749f9547d2c133b2174ab8d60cf2bdb1b23a)]
|
|
34
|
+
- test: [JENKINS] Improve cypress time [valentinab25 - [`237e6a3`](https://github.com/eea/volto-slate-footnote/commit/237e6a331e3608aa35d1c93a03c435daf330c2bd)]
|
|
35
|
+
### [6.1.8](https://github.com/eea/volto-slate-footnote/compare/6.1.7...6.1.8) - 22 October 2023
|
|
8
36
|
|
|
9
37
|
#### :house: Internal changes
|
|
10
38
|
|
package/Dockerfile
CHANGED
package/Jenkinsfile
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
pipeline {
|
|
2
|
-
|
|
2
|
+
tools {
|
|
3
|
+
jdk 'Java17'
|
|
4
|
+
}
|
|
5
|
+
agent {
|
|
6
|
+
node { label 'docker-host' }
|
|
7
|
+
}
|
|
3
8
|
|
|
4
9
|
environment {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
GIT_NAME = "volto-slate-footnote"
|
|
11
|
+
NAMESPACE = "@eeacms"
|
|
12
|
+
SONARQUBE_TAGS = "volto.eea.europa.eu,biodiversity.europa.eu,www.eea.europa.eu-ims,climate-energy.eea.europa.eu,sustainability.eionet.europa.eu,forest.eea.europa.eu,clms.land.copernicus.eu,industry.eea.europa.eu,water.europa.eu-freshwater,demo-www.eea.europa.eu,clmsdemo.devel6cph.eea.europa.eu,water.europa.eu-marine,climate-adapt.eea.europa.eu,climate-advisory-board.devel4cph.eea.europa.eu,climate-advisory-board.europa.eu,www.eea.europa.eu-en"
|
|
13
|
+
DEPENDENCIES = ""
|
|
14
|
+
BACKEND_PROFILES = "eea.kitkat:testing"
|
|
15
|
+
BACKEND_ADDONS = ""
|
|
16
|
+
VOLTO = "16"
|
|
17
|
+
IMAGE_NAME = BUILD_TAG.toLowerCase()
|
|
18
|
+
}
|
|
11
19
|
|
|
12
20
|
stages {
|
|
13
|
-
|
|
14
21
|
stage('Release') {
|
|
15
22
|
when {
|
|
16
23
|
allOf {
|
|
@@ -20,52 +27,41 @@ pipeline {
|
|
|
20
27
|
}
|
|
21
28
|
steps {
|
|
22
29
|
node(label: 'docker') {
|
|
23
|
-
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN'),string(credentialsId: 'eea-jenkins-npm-token', variable: 'NPM_TOKEN')]) {
|
|
24
|
-
sh '''docker pull eeacms/gitflow'''
|
|
25
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-gitflow-master" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" -e GIT_TOKEN="$GITHUB_TOKEN" -e NPM_TOKEN="$NPM_TOKEN" -e LANGUAGE=javascript eeacms/gitflow'''
|
|
30
|
+
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN'), string(credentialsId: 'eea-jenkins-npm-token', variable: 'NPM_TOKEN')]) {
|
|
31
|
+
sh '''docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-master" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" -e GIT_TOKEN="$GITHUB_TOKEN" -e NPM_TOKEN="$NPM_TOKEN" -e LANGUAGE=javascript eeacms/gitflow'''
|
|
26
32
|
}
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
stage('
|
|
37
|
+
stage('Check if testing needed') {
|
|
32
38
|
when {
|
|
33
39
|
allOf {
|
|
34
|
-
environment name: 'CHANGE_ID', value: ''
|
|
35
|
-
not { changelog '.*^Automated release [0-9\\.]+$' }
|
|
36
40
|
not { branch 'master' }
|
|
41
|
+
not { branch 'develop' }
|
|
42
|
+
environment name: 'CHANGE_ID', value: ''
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
steps {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
node(label: 'docker') {
|
|
44
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-eslint" -e NAMESPACE="$NAMESPACE" -e VOLTO=$VOLTO -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci eslint'''
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
"Style lint": {
|
|
49
|
-
node(label: 'docker') {
|
|
50
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-stylelint" -e NAMESPACE="$NAMESPACE" -e VOLTO=$VOLTO -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e VOLTO=$VOLTO plone/volto-addon-ci stylelint'''
|
|
51
|
-
}
|
|
52
|
-
},
|
|
46
|
+
script {
|
|
47
|
+
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
|
|
48
|
+
check_result = sh script: '''docker run --pull always -i --rm --name="$IMAGE_NAME-gitflow-check" -e GIT_TOKEN="$GITHUB_TOKEN" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_ORG="$GIT_ORG" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /check_if_testing_needed.sh''', returnStatus: true
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
if (check_result == 0) {
|
|
51
|
+
env.SKIP_TESTS = 'yes'
|
|
52
|
+
}
|
|
57
53
|
}
|
|
58
|
-
|
|
59
|
-
)
|
|
54
|
+
}
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
stage('
|
|
58
|
+
stage('Testing') {
|
|
64
59
|
when {
|
|
65
60
|
anyOf {
|
|
66
61
|
allOf {
|
|
67
62
|
not { environment name: 'CHANGE_ID', value: '' }
|
|
68
63
|
environment name: 'CHANGE_TARGET', value: 'develop'
|
|
64
|
+
environment name: 'SKIP_TESTS', value: ''
|
|
69
65
|
}
|
|
70
66
|
allOf {
|
|
71
67
|
environment name: 'CHANGE_ID', value: ''
|
|
@@ -73,26 +69,76 @@ pipeline {
|
|
|
73
69
|
not { changelog '.*^Automated release [0-9\\.]+$' }
|
|
74
70
|
branch 'master'
|
|
75
71
|
}
|
|
72
|
+
environment name: 'SKIP_TESTS', value: ''
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
stages {
|
|
77
|
+
stage('Build test image') {
|
|
78
|
+
steps {
|
|
79
|
+
checkout scm
|
|
80
|
+
sh '''docker build --pull --build-arg="VOLTO_VERSION=$VOLTO" --build-arg="ADDON_NAME=$NAMESPACE/$GIT_NAME" --build-arg="ADDON_PATH=$GIT_NAME" . -t $IMAGE_NAME-frontend'''
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
stage('Fix code') {
|
|
85
|
+
when {
|
|
86
|
+
environment name: 'CHANGE_ID', value: ''
|
|
87
|
+
not { branch 'master' }
|
|
88
|
+
}
|
|
89
|
+
steps {
|
|
90
|
+
script {
|
|
91
|
+
fix_result = sh(script: '''docker run --name="$IMAGE_NAME-fix" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend ci-fix''', returnStatus: true)
|
|
92
|
+
sh '''docker cp $IMAGE_NAME-fix:/app/src/addons/$GIT_NAME/src .'''
|
|
93
|
+
sh '''docker rm -v $IMAGE_NAME-fix'''
|
|
94
|
+
FOUND_FIX = sh(script: '''git diff | wc -l''', returnStdout: true).trim()
|
|
81
95
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
if (FOUND_FIX != '0') {
|
|
97
|
+
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
|
|
98
|
+
sh '''sed -i "s|url = .*|url = https://eea-jenkins:$GITHUB_TOKEN@github.com/eea/$GIT_NAME.git|" .git/config'''
|
|
99
|
+
}
|
|
100
|
+
sh '''git fetch origin $GIT_BRANCH:$GIT_BRANCH'''
|
|
101
|
+
sh '''git checkout $GIT_BRANCH'''
|
|
102
|
+
sh '''git add src/'''
|
|
103
|
+
sh '''git commit -m "style: Automated code fix" '''
|
|
104
|
+
sh '''git push --set-upstream origin $GIT_BRANCH'''
|
|
105
|
+
sh '''exit 1'''
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
stage('ES lint') {
|
|
112
|
+
steps {
|
|
113
|
+
sh '''docker run --rm --name="$IMAGE_NAME-eslint" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend lint'''
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
stage('Style lint') {
|
|
118
|
+
steps {
|
|
119
|
+
sh '''docker run --rm --name="$IMAGE_NAME-stylelint" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend stylelint'''
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
stage('Prettier') {
|
|
124
|
+
steps {
|
|
125
|
+
sh '''docker run --rm --name="$IMAGE_NAME-prettier" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend prettier'''
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
stage('Coverage Tests') {
|
|
130
|
+
parallel {
|
|
131
|
+
|
|
132
|
+
stage('Unit tests') {
|
|
133
|
+
steps {
|
|
134
|
+
script {
|
|
135
|
+
try {
|
|
136
|
+
sh '''docker run --name="$IMAGE_NAME-volto" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend test-ci'''
|
|
137
|
+
sh '''rm -rf xunit-reports'''
|
|
138
|
+
sh '''mkdir -p xunit-reports'''
|
|
139
|
+
sh '''docker cp $IMAGE_NAME-volto:/app/coverage xunit-reports/'''
|
|
140
|
+
sh '''docker cp $IMAGE_NAME-volto:/app/junit.xml xunit-reports/'''
|
|
141
|
+
publishHTML(target : [
|
|
96
142
|
allowMissing: false,
|
|
97
143
|
alwaysLinkToLastBuild: true,
|
|
98
144
|
keepAll: true,
|
|
@@ -105,75 +151,67 @@ pipeline {
|
|
|
105
151
|
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
|
|
106
152
|
junit testResults: 'xunit-reports/junit.xml', allowEmptyResults: true
|
|
107
153
|
}
|
|
108
|
-
|
|
154
|
+
sh script: '''docker rm -v $IMAGE_NAME-volto''', returnStatus: true
|
|
155
|
+
}
|
|
109
156
|
}
|
|
110
157
|
}
|
|
111
158
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
159
|
+
|
|
160
|
+
stage('Integration tests') {
|
|
161
|
+
steps {
|
|
162
|
+
script {
|
|
163
|
+
try {
|
|
164
|
+
sh '''docker run --pull always --rm -d --name="$IMAGE_NAME-plone" -e SITE="Plone" -e PROFILES="$BACKEND_PROFILES" -e ADDONS="$BACKEND_ADDONS" eeacms/plone-backend'''
|
|
165
|
+
sh '''docker run -d --shm-size=3g --link $IMAGE_NAME-plone:plone --name="$IMAGE_NAME-cypress" -e "RAZZLE_INTERNAL_API_PATH=http://plone:8080/Plone" --entrypoint=make --workdir=/app/src/addons/$GIT_NAME $IMAGE_NAME-frontend start-ci'''
|
|
166
|
+
sh '''timeout -s 9 1800 docker exec --workdir=/app/src/addons/${GIT_NAME} $IMAGE_NAME-cypress make cypress-ci'''
|
|
167
|
+
} finally {
|
|
168
|
+
try {
|
|
169
|
+
sh '''rm -rf cypress-videos cypress-results cypress-coverage cypress-screenshots'''
|
|
170
|
+
sh '''mkdir -p cypress-videos cypress-results cypress-coverage cypress-screenshots'''
|
|
171
|
+
videos = sh script: '''docker cp $IMAGE_NAME-cypress:/app/src/addons/$GIT_NAME/cypress/videos cypress-videos/''', returnStatus: true
|
|
172
|
+
sh '''docker cp $IMAGE_NAME-cypress:/app/src/addons/$GIT_NAME/cypress/reports cypress-results/'''
|
|
173
|
+
screenshots = sh script: '''docker cp $IMAGE_NAME-cypress:/app/src/addons/$GIT_NAME/cypress/screenshots cypress-screenshots''', returnStatus: true
|
|
116
174
|
|
|
117
|
-
|
|
118
|
-
when {
|
|
119
|
-
anyOf {
|
|
120
|
-
allOf {
|
|
121
|
-
not { environment name: 'CHANGE_ID', value: '' }
|
|
122
|
-
environment name: 'CHANGE_TARGET', value: 'develop'
|
|
123
|
-
}
|
|
124
|
-
allOf {
|
|
125
|
-
environment name: 'CHANGE_ID', value: ''
|
|
126
|
-
anyOf {
|
|
127
|
-
not { changelog '.*^Automated release [0-9\\.]+$' }
|
|
128
|
-
branch 'master'
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
steps {
|
|
134
|
-
parallel(
|
|
175
|
+
archiveArtifacts artifacts: 'cypress-screenshots/**', fingerprint: true, allowEmptyArchive: true
|
|
135
176
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
sh '''docker pull eeacms/plone-backend; docker run --rm -d --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="eea.kitkat:testing" eeacms/plone-backend'''
|
|
141
|
-
sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=development -e VOLTO="$VOLTO" plone/volto-addon-ci cypress'''
|
|
142
|
-
} finally {
|
|
143
|
-
try {
|
|
144
|
-
sh '''rm -rf cypress-reports cypress-results cypress-coverage'''
|
|
145
|
-
sh '''mkdir -p cypress-reports cypress-results cypress-coverage'''
|
|
146
|
-
sh '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/cypress/videos cypress-reports/'''
|
|
147
|
-
sh '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/cypress/reports cypress-results/'''
|
|
148
|
-
coverage = sh script: '''docker cp $BUILD_TAG-cypress:/opt/frontend/my-volto-project/src/addons/$GIT_NAME/coverage cypress-coverage/''', returnStatus: true
|
|
149
|
-
if ( coverage == 0 ) {
|
|
150
|
-
publishHTML (target : [allowMissing: false,
|
|
177
|
+
coverage = sh script: '''docker cp $IMAGE_NAME-cypress:/app/src/addons/$GIT_NAME/coverage cypress-coverage''', returnStatus: true
|
|
178
|
+
|
|
179
|
+
if ( coverage == 0 ) {
|
|
180
|
+
publishHTML(target : [allowMissing: false,
|
|
151
181
|
alwaysLinkToLastBuild: true,
|
|
152
182
|
keepAll: true,
|
|
153
183
|
reportDir: 'cypress-coverage/coverage/lcov-report',
|
|
154
184
|
reportFiles: 'index.html',
|
|
155
185
|
reportName: 'CypressCoverage',
|
|
156
186
|
reportTitles: 'Integration Tests Code Coverage'])
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
187
|
+
}
|
|
188
|
+
if ( videos == 0 ) {
|
|
189
|
+
sh '''for file in $(find cypress-results -name *.xml); do if [ $(grep -E 'failures="[1-9].*"' $file | wc -l) -eq 0 ]; then testname=$(grep -E 'file=.*failures="0"' $file | sed 's#.* file=".*\\/\\(.*\\.[jsxt]\\+\\)" time.*#\\1#' ); rm -f cypress-videos/videos/$testname.mp4; fi; done'''
|
|
190
|
+
archiveArtifacts artifacts: 'cypress-videos/**/*.mp4', fingerprint: true, allowEmptyArchive: true
|
|
191
|
+
}
|
|
192
|
+
} finally {
|
|
193
|
+
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
|
|
164
194
|
junit testResults: 'cypress-results/**/*.xml', allowEmptyResults: true
|
|
195
|
+
}
|
|
196
|
+
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
|
|
197
|
+
sh '''docker logs $IMAGE_NAME-cypress'''
|
|
198
|
+
}
|
|
199
|
+
sh script: "docker stop $IMAGE_NAME-cypress", returnStatus: true
|
|
200
|
+
sh script: "docker stop $IMAGE_NAME-plone", returnStatus: true
|
|
201
|
+
sh script: "docker rm -v $IMAGE_NAME-plone", returnStatus: true
|
|
202
|
+
sh script: "docker rm -v $IMAGE_NAME-cypress", returnStatus: true
|
|
165
203
|
}
|
|
166
|
-
sh script: "docker stop $BUILD_TAG-plone", returnStatus: true
|
|
167
|
-
sh script: "docker rm -v $BUILD_TAG-plone", returnStatus: true
|
|
168
|
-
sh script: "docker rm -v $BUILD_TAG-cypress", returnStatus: true
|
|
169
|
-
|
|
170
204
|
}
|
|
171
205
|
}
|
|
172
206
|
}
|
|
173
207
|
}
|
|
174
208
|
}
|
|
175
|
-
|
|
176
|
-
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
post {
|
|
212
|
+
always {
|
|
213
|
+
sh script: "docker rmi $IMAGE_NAME-frontend", returnStatus: true
|
|
214
|
+
}
|
|
177
215
|
}
|
|
178
216
|
}
|
|
179
217
|
|
|
@@ -197,19 +235,14 @@ pipeline {
|
|
|
197
235
|
}
|
|
198
236
|
}
|
|
199
237
|
steps {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
sh '''sed -i "s#/opt/frontend/my-volto-project/src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
209
|
-
sh '''sed -i "s#src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
210
|
-
sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME-$BRANCH_NAME -Dsonar.projectVersion=$BRANCH_NAME-$BUILD_NUMBER"
|
|
211
|
-
sh '''try=2; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}-${BRANCH_NAME}&tags=${SONARQUBE_TAGS},${BRANCH_NAME}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 60; try=\$(( \$try - 1 )); fi; done'''
|
|
212
|
-
}
|
|
238
|
+
script {
|
|
239
|
+
def scannerHome = tool 'SonarQubeScanner'
|
|
240
|
+
def nodeJS = tool 'NodeJS'
|
|
241
|
+
withSonarQubeEnv('Sonarqube') {
|
|
242
|
+
sh '''sed -i "s#/app/src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
243
|
+
sh '''sed -i "s#src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
244
|
+
sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME-$BRANCH_NAME -Dsonar.projectVersion=$BRANCH_NAME-$BUILD_NUMBER"
|
|
245
|
+
sh '''try=5; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}-${BRANCH_NAME}&tags=${SONARQUBE_TAGS},${BRANCH_NAME}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 15; try=\$(( \$try - 1 )); fi; done'''
|
|
213
246
|
}
|
|
214
247
|
}
|
|
215
248
|
}
|
|
@@ -230,18 +263,15 @@ pipeline {
|
|
|
230
263
|
}
|
|
231
264
|
}
|
|
232
265
|
steps {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
sh '''
|
|
237
|
-
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
|
238
|
-
sh '''set -o pipefail; docker run -i --rm --name="$BUILD_TAG-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /checkSonarqubemaster.sh | grep -v "Found script" | tee checkresult.txt'''
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
publishChecks name: 'SonarQube', title: 'Sonarqube Code Quality Check', summary: "Quality check on the SonarQube metrics from branch develop, comparing it with the ones from master branch. No bugs are allowed",
|
|
242
|
-
text: readFile(file: 'checkresult.txt'), conclusion: "${currentBuild.currentResult}",
|
|
243
|
-
detailsURL: "${env.BUILD_URL}display/redirect"
|
|
266
|
+
script {
|
|
267
|
+
sh '''echo "Error" > checkresult.txt'''
|
|
268
|
+
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
|
269
|
+
sh '''set -o pipefail; docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /checkSonarqubemaster.sh | grep -v "Found script" | tee checkresult.txt'''
|
|
244
270
|
}
|
|
271
|
+
|
|
272
|
+
publishChecks name: 'SonarQube', title: 'Sonarqube Code Quality Check', summary: 'Quality check on the SonarQube metrics from branch develop, comparing it with the ones from master branch. No bugs are allowed',
|
|
273
|
+
text: readFile(file: 'checkresult.txt'), conclusion: "${currentBuild.currentResult}",
|
|
274
|
+
detailsURL: "${env.BUILD_URL}display/redirect"
|
|
245
275
|
}
|
|
246
276
|
}
|
|
247
277
|
}
|
|
@@ -254,20 +284,16 @@ pipeline {
|
|
|
254
284
|
environment name: 'CHANGE_TARGET', value: 'master'
|
|
255
285
|
}
|
|
256
286
|
steps {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
sh '''docker pull eeacms/gitflow'''
|
|
264
|
-
sh '''docker run -i --rm --name="$BUILD_TAG-gitflow-pr" -e GIT_CHANGE_TARGET="$CHANGE_TARGET" -e GIT_CHANGE_BRANCH="$CHANGE_BRANCH" -e GIT_CHANGE_AUTHOR="$CHANGE_AUTHOR" -e GIT_CHANGE_TITLE="$CHANGE_TITLE" -e GIT_TOKEN="$GITHUB_TOKEN" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e GIT_ORG="$GIT_ORG" -e GIT_NAME="$GIT_NAME" -e LANGUAGE=javascript eeacms/gitflow'''
|
|
265
|
-
}
|
|
287
|
+
script {
|
|
288
|
+
if (env.CHANGE_BRANCH != 'develop') {
|
|
289
|
+
error 'Pipeline aborted due to PR not made from develop branch'
|
|
290
|
+
}
|
|
291
|
+
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
|
|
292
|
+
sh '''docker run --pull always -i --rm --name="$IMAGE_NAME-gitflow-pr" -e GIT_CHANGE_TARGET="$CHANGE_TARGET" -e GIT_CHANGE_BRANCH="$CHANGE_BRANCH" -e GIT_CHANGE_AUTHOR="$CHANGE_AUTHOR" -e GIT_CHANGE_TITLE="$CHANGE_TITLE" -e GIT_TOKEN="$GITHUB_TOKEN" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e GIT_ORG="$GIT_ORG" -e GIT_NAME="$GIT_NAME" -e LANGUAGE=javascript eeacms/gitflow'''
|
|
266
293
|
}
|
|
267
294
|
}
|
|
268
295
|
}
|
|
269
296
|
}
|
|
270
|
-
|
|
271
297
|
}
|
|
272
298
|
|
|
273
299
|
post {
|
package/Makefile
CHANGED
|
@@ -50,6 +50,11 @@ VOLTO_VERSION?=16
|
|
|
50
50
|
ADDON_PATH="${DIR}"
|
|
51
51
|
ADDON_NAME="@eeacms/${ADDON_PATH}"
|
|
52
52
|
DOCKER_COMPOSE=PLONE_VERSION=${PLONE_VERSION} VOLTO_VERSION=${VOLTO_VERSION} ADDON_NAME=${ADDON_NAME} ADDON_PATH=${ADDON_PATH} docker compose
|
|
53
|
+
RAZZLE_INTERNAL_API_PATH?="http://localhost:8080/Plone"
|
|
54
|
+
RAZZLE_DEV_PROXY_API_PATH?="${RAZZLE_INTERNAL_API_PATH}"
|
|
55
|
+
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}"
|
|
56
|
+
|
|
57
|
+
|
|
53
58
|
|
|
54
59
|
# Top-level targets
|
|
55
60
|
.PHONY: all
|
|
@@ -77,11 +82,11 @@ shell: ## Start a shell in the frontend container
|
|
|
77
82
|
|
|
78
83
|
.PHONY: cypress-open
|
|
79
84
|
cypress-open: ## Open cypress integration tests
|
|
80
|
-
NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress open
|
|
85
|
+
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}" NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress open
|
|
81
86
|
|
|
82
87
|
.PHONY: cypress-run
|
|
83
88
|
cypress-run: ## Run cypress integration tests
|
|
84
|
-
NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run
|
|
89
|
+
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}" NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run --browser chromium
|
|
85
90
|
|
|
86
91
|
.PHONY: test
|
|
87
92
|
test: ## Run jest tests
|
|
@@ -129,3 +134,29 @@ i18n: ## i18n
|
|
|
129
134
|
help: ## Show this help.
|
|
130
135
|
@echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"
|
|
131
136
|
head -n 14 Makefile
|
|
137
|
+
|
|
138
|
+
.PHONY: ci-fix
|
|
139
|
+
ci-fix:
|
|
140
|
+
echo "Running lint-fix"
|
|
141
|
+
make lint-fix
|
|
142
|
+
echo "Running prettier-fix"
|
|
143
|
+
make prettier-fix
|
|
144
|
+
echo "Running stylelint-fix"
|
|
145
|
+
make stylelint-fix
|
|
146
|
+
|
|
147
|
+
.PHONY: test-ci
|
|
148
|
+
test-ci:
|
|
149
|
+
cd /app
|
|
150
|
+
RAZZLE_JEST_CONFIG=src/addons/${ADDON_PATH}/jest-addon.config.js CI=true yarn test src/addons/${ADDON_PATH}/src --watchAll=false --reporters=default --reporters=jest-junit --collectCoverage --coverageReporters lcov cobertura text
|
|
151
|
+
|
|
152
|
+
.PHONY: start-ci
|
|
153
|
+
start-ci:
|
|
154
|
+
cp .coverage.babel.config.js /app/babel.config.js
|
|
155
|
+
cd ../..
|
|
156
|
+
yarn start
|
|
157
|
+
|
|
158
|
+
.PHONY: cypress-ci
|
|
159
|
+
cypress-ci:
|
|
160
|
+
$(NODE_MODULES)/.bin/wait-on -t 240000 http://localhost:3000
|
|
161
|
+
NODE_ENV=development make cypress-run
|
|
162
|
+
|
package/cypress.config.js
CHANGED
|
@@ -2,12 +2,12 @@ const { defineConfig } = require('cypress');
|
|
|
2
2
|
|
|
3
3
|
module.exports = defineConfig({
|
|
4
4
|
viewportWidth: 1280,
|
|
5
|
-
defaultCommandTimeout:
|
|
5
|
+
defaultCommandTimeout: 8888,
|
|
6
6
|
chromeWebSecurity: false,
|
|
7
7
|
reporter: 'junit',
|
|
8
|
-
video:
|
|
8
|
+
video: false,
|
|
9
9
|
retries: {
|
|
10
|
-
runMode:
|
|
10
|
+
runMode: 2,
|
|
11
11
|
openMode: 0,
|
|
12
12
|
},
|
|
13
13
|
reporterOptions: {
|
package/package.json
CHANGED
|
@@ -20,24 +20,70 @@ const alphabet = 'abcdefghijklmnopqrstuvwxyz';
|
|
|
20
20
|
* received from the Volto form.
|
|
21
21
|
*/
|
|
22
22
|
const FootnotesBlockView = (props) => {
|
|
23
|
-
const { data, properties } = props;
|
|
23
|
+
const { data, properties, tabData, content } = props;
|
|
24
24
|
const { title, global, placeholder = 'Footnotes' } = data;
|
|
25
|
+
|
|
25
26
|
const metadata = props.metadata ? props.metadata : properties;
|
|
26
|
-
|
|
27
|
-
const
|
|
27
|
+
|
|
28
|
+
const localMetadata = content
|
|
29
|
+
? content
|
|
30
|
+
: tabData
|
|
31
|
+
? tabData
|
|
32
|
+
: global
|
|
33
|
+
? metadata
|
|
34
|
+
: properties;
|
|
35
|
+
const blocks = getAllBlocksAndSlateFields(localMetadata);
|
|
28
36
|
const notesObj = makeFootnoteListOfUniqueItems(blocks);
|
|
37
|
+
let startList = 1;
|
|
38
|
+
if (Object.keys(notesObj).length > 0) {
|
|
39
|
+
const noteId = Object.keys(notesObj)[0];
|
|
40
|
+
const note = notesObj[noteId];
|
|
41
|
+
const { zoteroId } = note;
|
|
42
|
+
|
|
43
|
+
const notesGlobalResult = makeFootnoteListOfUniqueItems(
|
|
44
|
+
getAllBlocksAndSlateFields(metadata),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const indiceIfZoteroId = note.extra
|
|
48
|
+
? [
|
|
49
|
+
Object.keys(notesGlobalResult).indexOf(zoteroId) + 1, // parent footnote
|
|
50
|
+
...note.extra.map(
|
|
51
|
+
// citations from extra
|
|
52
|
+
(zoteroObj, _index) =>
|
|
53
|
+
// all zotero citation are indexed by zoteroId in notesGlobalResult
|
|
54
|
+
|
|
55
|
+
Object.keys(notesGlobalResult).indexOf(zoteroObj.zoteroId) + 1,
|
|
56
|
+
),
|
|
57
|
+
]
|
|
58
|
+
: // no extra citations (no multiples)
|
|
59
|
+
Object.keys(notesGlobalResult).indexOf(zoteroId) + 1;
|
|
60
|
+
const citationIndice = zoteroId // ZOTERO
|
|
61
|
+
? indiceIfZoteroId
|
|
62
|
+
: // FOOTNOTES
|
|
63
|
+
// parent footnote
|
|
64
|
+
[note, ...(note.extra || [])].map((footnoteObj, _index) => {
|
|
65
|
+
return (
|
|
66
|
+
Object.keys(notesGlobalResult).indexOf(
|
|
67
|
+
Object.keys(notesGlobalResult).find(
|
|
68
|
+
(key) =>
|
|
69
|
+
notesGlobalResult[key].footnote === footnoteObj.footnote,
|
|
70
|
+
),
|
|
71
|
+
) + 1
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
startList = citationIndice;
|
|
75
|
+
}
|
|
29
76
|
|
|
30
77
|
return (
|
|
31
78
|
<div className="footnotes-listing-block">
|
|
32
79
|
<h3 title={placeholder}>{title}</h3>
|
|
33
80
|
{notesObj && (
|
|
34
|
-
<ol>
|
|
81
|
+
<ol start={startList}>
|
|
35
82
|
{Object.keys(notesObj).map((noteId) => {
|
|
36
83
|
const note = notesObj[noteId];
|
|
37
84
|
const { uid, footnote, zoteroId, parentUid } = note;
|
|
38
85
|
const { refs } = note;
|
|
39
86
|
const refsList = refs ? Object.keys(refs) : null;
|
|
40
|
-
|
|
41
87
|
return (
|
|
42
88
|
<li
|
|
43
89
|
key={`footnote-${zoteroId || uid}`}
|
|
@@ -41,7 +41,6 @@ const FootnoteEditor = (props) => {
|
|
|
41
41
|
const metadataBlocks = getAllBlocksAndSlateFields(metadata);
|
|
42
42
|
const storeBlocks = getAllBlocksAndSlateFields(initialFormData);
|
|
43
43
|
const uniqueFootnoteBlocks = [];
|
|
44
|
-
|
|
45
44
|
const flatAllBlocks = isEmpty(metadata) ? storeBlocks : metadataBlocks;
|
|
46
45
|
/**
|
|
47
46
|
* Will add only the items that are unique by text
|
package/src/editor/extensions.js
CHANGED
|
@@ -6,12 +6,11 @@ export const withFootnote = (editor) => {
|
|
|
6
6
|
const { normalizeNode, isInline } = editor;
|
|
7
7
|
|
|
8
8
|
editor.isInline = (element) => {
|
|
9
|
-
return element.type === FOOTNOTE ? true : isInline(element);
|
|
9
|
+
return element && element.type === FOOTNOTE ? true : isInline(element);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
editor.normalizeNode = (entry) => {
|
|
13
13
|
const [node, path] = entry;
|
|
14
|
-
|
|
15
14
|
if (node.type === FOOTNOTE && !node.data?.uid) {
|
|
16
15
|
Transforms.setNodes(
|
|
17
16
|
editor,
|
package/src/editor/render.jsx
CHANGED
|
@@ -24,6 +24,7 @@ export const FootnoteElement = (props) => {
|
|
|
24
24
|
const { data = {} } = element;
|
|
25
25
|
const { uid, zoteroId } = data;
|
|
26
26
|
const editor = useEditorContext();
|
|
27
|
+
const ref = React.useRef(null);
|
|
27
28
|
|
|
28
29
|
const initialFormData = useSelector((state) => state?.content?.data || {});
|
|
29
30
|
const blockProps = editor?.getBlockProps ? editor.getBlockProps() : null;
|
|
@@ -36,7 +37,6 @@ export const FootnoteElement = (props) => {
|
|
|
36
37
|
const notesObjResult = isEmpty(metadata)
|
|
37
38
|
? makeFootnoteListOfUniqueItems(storeBlocks)
|
|
38
39
|
: makeFootnoteListOfUniqueItems(blocks);
|
|
39
|
-
|
|
40
40
|
// will cosider zotero citations and footnote
|
|
41
41
|
// notesObjResult contains all zotero/footnote as unique, and contain refs for other zotero/footnote
|
|
42
42
|
const indiceIfZoteroId = data.extra
|
|
@@ -58,12 +58,15 @@ export const FootnoteElement = (props) => {
|
|
|
58
58
|
// parent footnote
|
|
59
59
|
[data, ...(data.extra || [])]
|
|
60
60
|
.map((footnoteObj, _index) => {
|
|
61
|
+
const indexInNotesObjResult = Object.keys(notesObjResult).indexOf(
|
|
62
|
+
Object.keys(notesObjResult).find(
|
|
63
|
+
(key) => notesObjResult[key].footnote === footnoteObj.footnote,
|
|
64
|
+
),
|
|
65
|
+
);
|
|
61
66
|
return `[${
|
|
62
|
-
|
|
63
|
-
Object.keys(notesObjResult).
|
|
64
|
-
|
|
65
|
-
),
|
|
66
|
-
) + 1
|
|
67
|
+
indexInNotesObjResult === -1
|
|
68
|
+
? Object.keys(notesObjResult).length + 1
|
|
69
|
+
: indexInNotesObjResult + 1
|
|
67
70
|
}]`;
|
|
68
71
|
})
|
|
69
72
|
.join('');
|
|
@@ -83,15 +86,20 @@ export const FootnoteElement = (props) => {
|
|
|
83
86
|
return (
|
|
84
87
|
<>
|
|
85
88
|
{mode === 'view' ? (
|
|
86
|
-
<span id={`ref-${uid}`} aria-describedby="footnote-label">
|
|
89
|
+
<span id={`ref-${uid}`} aria-describedby="footnote-label" ref={ref}>
|
|
87
90
|
<Popup
|
|
88
91
|
position="bottom left"
|
|
92
|
+
pinned={true}
|
|
93
|
+
mountNode={ref.current}
|
|
94
|
+
on={['click', 'hover', 'focus']}
|
|
89
95
|
trigger={
|
|
90
96
|
<span
|
|
91
97
|
id={`cite_ref-${uid}`}
|
|
92
98
|
{...attributes}
|
|
93
99
|
className="citation-item"
|
|
94
100
|
data-footnote-indice={citationIndice}
|
|
101
|
+
tabIndex={0}
|
|
102
|
+
role={'presentation'}
|
|
95
103
|
>
|
|
96
104
|
{children}
|
|
97
105
|
</span>
|
package/src/editor/utils.js
CHANGED
|
@@ -10,6 +10,37 @@ import { getAllBlocks } from '@plone/volto-slate/utils';
|
|
|
10
10
|
export const makeFootnote = (footnote) => {
|
|
11
11
|
return footnote ? footnote.replace('<?xml version="1.0"?>', '') : '';
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* retrive all slate children of nested objects
|
|
15
|
+
* @param {object} path - the keys that we want to extract the slate children from
|
|
16
|
+
* @param {*} value - the source that we want to extract the slate children from
|
|
17
|
+
* Exemple of parameters
|
|
18
|
+
* path:{items:'value'}
|
|
19
|
+
* @returns string
|
|
20
|
+
*/
|
|
21
|
+
const retriveValuesOfSlateFromNestedPath = (path, value) => {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
let allSlateValue = [];
|
|
24
|
+
value.forEach((element) => {
|
|
25
|
+
allSlateValue = [
|
|
26
|
+
...allSlateValue,
|
|
27
|
+
...retriveValuesOfSlateFromNestedPath(path, element),
|
|
28
|
+
];
|
|
29
|
+
});
|
|
30
|
+
return allSlateValue;
|
|
31
|
+
}
|
|
32
|
+
if (typeof path === 'string' && value) {
|
|
33
|
+
if (value[path]?.length > 0) return [...value[path]];
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
if (typeof path === 'object' && Object.keys(path).length > 0) {
|
|
37
|
+
return retriveValuesOfSlateFromNestedPath(
|
|
38
|
+
path[Object.keys(path)[0]],
|
|
39
|
+
value[Object.keys(path)[0]],
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
};
|
|
13
44
|
|
|
14
45
|
/**
|
|
15
46
|
* Will open accordion if contains footnote reference
|
|
@@ -46,6 +77,7 @@ const blockTypesOperations = {
|
|
|
46
77
|
return [...accumulator, ...propertiesBlocks];
|
|
47
78
|
}, []);
|
|
48
79
|
},
|
|
80
|
+
|
|
49
81
|
metadata: (block, properties) => {
|
|
50
82
|
const fId = block?.data?.id;
|
|
51
83
|
return block?.data?.widget === 'slate'
|
|
@@ -80,6 +112,7 @@ const blockTypesOperations = {
|
|
|
80
112
|
*/
|
|
81
113
|
export const getAllBlocksAndSlateFields = (properties) => {
|
|
82
114
|
const blocks = getAllBlocks(properties, []);
|
|
115
|
+
|
|
83
116
|
return blocks.reduce((accumulator, currentblock) => {
|
|
84
117
|
return [
|
|
85
118
|
...accumulator,
|
|
@@ -111,45 +144,48 @@ export const makeFootnoteListOfUniqueItems = (blocks) => {
|
|
|
111
144
|
] || ['value'];
|
|
112
145
|
|
|
113
146
|
mapping.forEach((key) => {
|
|
114
|
-
const value = element
|
|
147
|
+
const value = retriveValuesOfSlateFromNestedPath(key, element);
|
|
148
|
+
|
|
115
149
|
if (!value) return;
|
|
116
150
|
|
|
117
|
-
value
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (node.data
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
node.data
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
value
|
|
152
|
+
.filter((val) => val.children)
|
|
153
|
+
.forEach((item) => {
|
|
154
|
+
// Node.elements(item) returns an iterable generator of nodes
|
|
155
|
+
Array.from(Node.elements(item)).forEach(([node]) => {
|
|
156
|
+
if (footnotes.includes(node.type) && node.data) {
|
|
157
|
+
// for citations (Zotero items) create refs for same zoteroId
|
|
158
|
+
if (node.data.zoteroId) {
|
|
159
|
+
iterateZoteroObj(notesObjResult, node.data);
|
|
160
|
+
// itereate the extra obj for multiple citations
|
|
161
|
+
if (node.data.extra) {
|
|
162
|
+
node.data.extra.forEach((zoteroObjItem) =>
|
|
163
|
+
// send the uid of the parent
|
|
164
|
+
// of the word the will have the reference indice
|
|
165
|
+
iterateZoteroObj(
|
|
166
|
+
notesObjResult,
|
|
167
|
+
zoteroObjItem,
|
|
168
|
+
node.data.uid,
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
// for footnotes - create refs, on identical text
|
|
173
|
+
} else {
|
|
174
|
+
iterateFootnoteObj(notesObjResult, node.data);
|
|
175
|
+
if (node.data.extra) {
|
|
176
|
+
node.data.extra.forEach((footnoteObjItem) =>
|
|
177
|
+
// since is called in case of extra, the parent is needed
|
|
178
|
+
iterateFootnoteObj(
|
|
179
|
+
notesObjResult,
|
|
180
|
+
footnoteObjItem,
|
|
181
|
+
node.data.uid,
|
|
182
|
+
),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
148
185
|
}
|
|
149
186
|
}
|
|
150
|
-
}
|
|
187
|
+
});
|
|
151
188
|
});
|
|
152
|
-
});
|
|
153
189
|
});
|
|
154
190
|
});
|
|
155
191
|
|
|
@@ -204,6 +240,7 @@ const iterateFootnoteObj = (notesObjResultTemp, node, parentUid) => {
|
|
|
204
240
|
return notesObjResultTemp[noteId].footnote === node.footnote;
|
|
205
241
|
});
|
|
206
242
|
// has not yet been added
|
|
243
|
+
|
|
207
244
|
if (!found) {
|
|
208
245
|
// will use the parentUid instead of own uid for render to be able to reference to the correct element
|
|
209
246
|
//(word containing the footnotes)
|