@osfarm/itineraire-technique 1.2.0 → 1.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/.github/copilot-instructions.md +56 -0
- package/.github/workflows/publish.yml +34 -0
- package/README.md +2 -34
- package/css/styles-editor.css +1 -1
- package/css/styles-editor.css.map +1 -1
- package/editor.html +38 -748
- package/js/chart-render.js +16 -11
- package/js/editor-interventions.js +315 -189
- package/js/editor-loader-default.js +238 -0
- package/js/editor-loader-itinera.js +135 -0
- package/js/{editor-wiki-editor.js → editor-loader-wiki.js} +99 -11
- package/js/editor-main.js +752 -0
- package/js/intervention.js +12 -0
- package/js/step-model.js +69 -0
- package/package.json +6 -59
- package/scss/styles-editor.scss +145 -0
- package/scss/styles-rendering.scss +184 -0
- package/examples/README.md +0 -137
- package/examples/nextjs-_document.tsx +0 -66
- package/examples/nextjs-api-route.ts +0 -122
- package/examples/nextjs-app-router-editor.tsx +0 -304
- package/examples/nextjs-app-router-viewer.tsx +0 -90
- package/js/editor-attributes.js +0 -99
- package/js/editor-crops.js +0 -136
- package/js/editor-export.js +0 -118
- package/react/QUICKSTART.md +0 -172
- package/react/README.md +0 -305
- package/react/TikaEditor.jsx +0 -212
- package/react/TikaRenderer.jsx +0 -116
- package/react/hooks.ts +0 -217
- package/react/index.ts +0 -19
- package/react/types.ts +0 -152
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intervention class - Represents an intervention on a crop
|
|
3
|
+
*/
|
|
4
|
+
class Intervention {
|
|
5
|
+
constructor(day, name, type, description) {
|
|
6
|
+
this.id = crypto.randomUUID();
|
|
7
|
+
this.day = day;
|
|
8
|
+
this.name = name || "";
|
|
9
|
+
this.type = type;
|
|
10
|
+
this.description = description || "";
|
|
11
|
+
}
|
|
12
|
+
}
|
package/js/step-model.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StepModel class - Represents a step/crop in the technical itinerary
|
|
3
|
+
* Manages step data, interventions, and form interactions
|
|
4
|
+
*/
|
|
5
|
+
class StepModel {
|
|
6
|
+
constructor(step) {
|
|
7
|
+
this.step = step;
|
|
8
|
+
|
|
9
|
+
this.step.id = step.id ?? crypto.randomUUID();
|
|
10
|
+
this.step.name = step.name ?? "";
|
|
11
|
+
this.step.color = step.color ?? "#0db3bf";
|
|
12
|
+
this.step.startDate = step.startDate ? new Date(step.startDate) : new Date();
|
|
13
|
+
this.step.endDate = step.endDate ? new Date(step.endDate) : new Date();
|
|
14
|
+
this.step.description = step.description ?? "";
|
|
15
|
+
this.step.interventions = step.interventions || [];
|
|
16
|
+
this.step.secondary_crop = step.secondary_crop ?? false;
|
|
17
|
+
|
|
18
|
+
this.step.useDefaultColor = step.useDefaultColor ?? true;
|
|
19
|
+
this.step.useDefaultStartDate = step.useDefaultStartDate ?? true;
|
|
20
|
+
this.step.useDefaultEndDate = step.useDefaultEndDate ?? true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setAsEdited() {
|
|
24
|
+
this.step.useDefaultColor = false;
|
|
25
|
+
this.step.useDefaultStartDate = false;
|
|
26
|
+
this.step.useDefaultEndDate = false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getStep() {
|
|
30
|
+
return this.step;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setStartDate(date) {
|
|
34
|
+
this.step.startDate = new Date(date);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
setDurationInMonths(durationInMonths) {
|
|
38
|
+
this.step.endDate = new Date(this.step.startDate);
|
|
39
|
+
this.step.endDate.setMonth(this.step.startDate.getMonth() + durationInMonths);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setDurationInDays(durationInDays) {
|
|
43
|
+
this.step.endDate = new Date(this.step.startDate);
|
|
44
|
+
this.step.endDate.setDate(this.step.startDate.getDate() + durationInDays);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getDurationInDays() {
|
|
48
|
+
const diffTime = Math.abs(this.step.endDate - this.step.startDate);
|
|
49
|
+
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
addIntervention(day, name, type, description) {
|
|
53
|
+
let intervention = { "id": crypto.randomUUID(), "day": day, "name": name, "type": type, "description": description };
|
|
54
|
+
this.step.interventions.push(intervention);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
removeIntervention(interventionId) {
|
|
58
|
+
this.step.interventions = this.step.interventions.filter(function (intervention) { return intervention.id != interventionId });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
updateFromForm() {
|
|
62
|
+
this.step.name = $("#cropName").val();
|
|
63
|
+
this.step.description = $("#cropDescription").val();
|
|
64
|
+
this.step.startDate = new Date($("#cropStartDate").val());
|
|
65
|
+
this.step.endDate = new Date($("#cropEndDate").val());
|
|
66
|
+
this.step.color = $("#cropColor").val();
|
|
67
|
+
this.step.secondary_crop = $("#cropSecondary").prop("checked") || false;
|
|
68
|
+
}
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,66 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osfarm/itineraire-technique",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "A visualisation tool to show agricultural technical itineraries based on Echarts
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "react/types.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./js/chart-render.js",
|
|
10
|
-
"require": "./js/chart-render.js"
|
|
11
|
-
},
|
|
12
|
-
"./react": {
|
|
13
|
-
"import": "./react/index.ts",
|
|
14
|
-
"require": "./react/index.ts",
|
|
15
|
-
"types": "./react/types.ts"
|
|
16
|
-
},
|
|
17
|
-
"./react/TikaRenderer": {
|
|
18
|
-
"import": "./react/TikaRenderer.jsx",
|
|
19
|
-
"require": "./react/TikaRenderer.jsx"
|
|
20
|
-
},
|
|
21
|
-
"./react/TikaEditor": {
|
|
22
|
-
"import": "./react/TikaEditor.jsx",
|
|
23
|
-
"require": "./react/TikaEditor.jsx"
|
|
24
|
-
},
|
|
25
|
-
"./css/*": "./css/*",
|
|
26
|
-
"./js/*": "./js/*"
|
|
27
|
-
},
|
|
28
|
-
"files": [
|
|
29
|
-
"js",
|
|
30
|
-
"css",
|
|
31
|
-
"react",
|
|
32
|
-
"examples",
|
|
33
|
-
"test",
|
|
34
|
-
"images",
|
|
35
|
-
"*.html",
|
|
36
|
-
"LICENSE",
|
|
37
|
-
"README.md"
|
|
38
|
-
],
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "A visualisation tool to show agricultural technical itineraries based on Echarts",
|
|
5
|
+
"main": "editor.html",
|
|
39
6
|
"scripts": {
|
|
40
7
|
"build:scss": "sass --style=compressed scss/styles-editor.scss css/styles-editor.css && sass --style=compressed scss/styles-rendering.scss css/styles-rendering.css",
|
|
41
8
|
"dev:scss": "sass scss/styles-editor.scss css/styles-editor.css && sass scss/styles-rendering.scss css/styles-rendering.css",
|
|
42
9
|
"watch:scss": "sass --watch scss/styles-editor.scss:css/styles-editor.css scss/styles-rendering.scss:css/styles-rendering.css",
|
|
43
10
|
"build": "npm run build:scss",
|
|
44
|
-
"start": "npm run watch:scss"
|
|
45
|
-
"setup:react": "bash scripts/setup-react.sh || powershell -ExecutionPolicy Bypass -File scripts/setup-react.ps1",
|
|
46
|
-
"postinstall": "echo '\n✨ Pour utiliser avec React/Next.js, exécutez: npm run setup:react\n'"
|
|
47
|
-
},
|
|
48
|
-
"peerDependencies": {
|
|
49
|
-
"react": ">=16.8.0",
|
|
50
|
-
"react-dom": ">=16.8.0"
|
|
51
|
-
},
|
|
52
|
-
"peerDependenciesMeta": {
|
|
53
|
-
"react": {
|
|
54
|
-
"optional": true
|
|
55
|
-
},
|
|
56
|
-
"react-dom": {
|
|
57
|
-
"optional": true
|
|
58
|
-
}
|
|
11
|
+
"start": "npm run watch:scss"
|
|
59
12
|
},
|
|
60
13
|
"devDependencies": {
|
|
61
|
-
"sass": "^1.85.1"
|
|
62
|
-
"@types/react": "^18.0.0",
|
|
63
|
-
"@types/react-dom": "^18.0.0"
|
|
14
|
+
"sass": "^1.85.1"
|
|
64
15
|
},
|
|
65
16
|
"publishConfig": {
|
|
66
17
|
"access": "public"
|
|
@@ -80,10 +31,6 @@
|
|
|
80
31
|
"visualization",
|
|
81
32
|
"farming",
|
|
82
33
|
"itineraire-technique",
|
|
83
|
-
"TIKA"
|
|
84
|
-
"react",
|
|
85
|
-
"nextjs",
|
|
86
|
-
"technical-itinerary",
|
|
87
|
-
"crop-rotation"
|
|
34
|
+
"TIKA"
|
|
88
35
|
]
|
|
89
36
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
$button-color : green;
|
|
2
|
+
$button-hover-color: rgb(2, 102, 2);
|
|
3
|
+
$button-text-color : white;
|
|
4
|
+
$header-height : 3rem;
|
|
5
|
+
|
|
6
|
+
.main-header {
|
|
7
|
+
background-color: #6fa76f;
|
|
8
|
+
color : white;
|
|
9
|
+
height : $header-height;
|
|
10
|
+
|
|
11
|
+
display : flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
|
|
14
|
+
.btn.show,
|
|
15
|
+
.btn:first-child:active,
|
|
16
|
+
:not(.btn-check)+.btn:active {
|
|
17
|
+
background-color: #026602;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.editor-view {
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
|
|
24
|
+
//scrollbar only for the editor
|
|
25
|
+
height: calc(100vh - #{$header-height + 1rem});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Add a button in the rotation to edit right from the transcript
|
|
29
|
+
.rotation_item {
|
|
30
|
+
.step-edit {
|
|
31
|
+
color : #878787;
|
|
32
|
+
cursor : pointer;
|
|
33
|
+
display : none;
|
|
34
|
+
margin-left : 10px;
|
|
35
|
+
font-size : 70%;
|
|
36
|
+
vertical-align: super;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&:hover .step-edit {
|
|
40
|
+
display: inline !important;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.welcome-view {
|
|
45
|
+
background-color: #6fa76f;
|
|
46
|
+
color : white;
|
|
47
|
+
padding : 1rem;
|
|
48
|
+
margin-top : 1rem;
|
|
49
|
+
border-radius : 1rem;
|
|
50
|
+
|
|
51
|
+
#cropsContainer {
|
|
52
|
+
color: green;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.card-white {
|
|
57
|
+
background-color: white;
|
|
58
|
+
padding : 1rem;
|
|
59
|
+
border-radius : 1rem;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.card-holder {
|
|
63
|
+
background-color: whitesmoke;
|
|
64
|
+
padding : 1rem;
|
|
65
|
+
border-radius : 1rem;
|
|
66
|
+
margin : auto
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.editable-row {
|
|
70
|
+
background-color: #f7f7f7;
|
|
71
|
+
min-height : 3rem;
|
|
72
|
+
|
|
73
|
+
display : flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
|
|
76
|
+
border-radius: 0.5rem;
|
|
77
|
+
|
|
78
|
+
.edit-buttons {
|
|
79
|
+
visibility: hidden;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&:hover>.edit-buttons {
|
|
83
|
+
visibility: visible;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.intervention-row {
|
|
88
|
+
background: #e0e0e0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.primary-button {
|
|
92
|
+
color : $button-text-color;
|
|
93
|
+
background-color: $button-color;
|
|
94
|
+
border : $button-color;
|
|
95
|
+
|
|
96
|
+
&:hover {
|
|
97
|
+
background-color: $button-hover-color;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.close-step-times {
|
|
102
|
+
background: none;
|
|
103
|
+
border : none;
|
|
104
|
+
color : #878787;
|
|
105
|
+
font-size : 120%;
|
|
106
|
+
|
|
107
|
+
&:hover {
|
|
108
|
+
color: #494949;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#cropsContainer{
|
|
113
|
+
.drag-handle {
|
|
114
|
+
color : #CCC;
|
|
115
|
+
font-weight : normal;
|
|
116
|
+
font-size : 86%;
|
|
117
|
+
margin-right : 10px;
|
|
118
|
+
vertical-align: middle;
|
|
119
|
+
cursor : grab;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
div.col {
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.form-control {
|
|
128
|
+
&.text-right {
|
|
129
|
+
text-align: right;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.modal {
|
|
134
|
+
.form-label {
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#code-snippet {
|
|
140
|
+
font-family : monospace;
|
|
141
|
+
font-size : 13px;
|
|
142
|
+
text-align : left;
|
|
143
|
+
border : 1px inset;
|
|
144
|
+
background-color: #f1f1f1;
|
|
145
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
div.mainITKContainer {
|
|
2
|
+
container-type: inline-size;
|
|
3
|
+
container-name: myparent;
|
|
4
|
+
line-height : 1rem;
|
|
5
|
+
|
|
6
|
+
.left-transcript {
|
|
7
|
+
display : none;
|
|
8
|
+
width : 50%;
|
|
9
|
+
font-family: Segoe UI;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.chart-div {
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.bottom-transcript {
|
|
17
|
+
display: none;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.withTranscript {
|
|
21
|
+
.bottom-transcript {
|
|
22
|
+
display : block;
|
|
23
|
+
font-family: Segoe UI;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@container myparent (min-width: 800px) {
|
|
28
|
+
&.withTranscript {
|
|
29
|
+
.left-transcript {
|
|
30
|
+
display: block;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.chart-div {
|
|
34
|
+
width: 50%;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.bottom-transcript {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@container myparent (min-width: 1000px) {
|
|
44
|
+
&.withTranscript {
|
|
45
|
+
.left-transcript {
|
|
46
|
+
display: block;
|
|
47
|
+
width : 40%;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.chart-div {
|
|
51
|
+
width: 60%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.bottom-transcript {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
div.rotation_item {
|
|
61
|
+
background-color: #F8FAFC;
|
|
62
|
+
border-left : #FFFFFF 14px solid;
|
|
63
|
+
border-radius : 7px;
|
|
64
|
+
padding : 8px 3px 5px 9px;
|
|
65
|
+
margin : 12px 0;
|
|
66
|
+
overflow-x : hidden;
|
|
67
|
+
|
|
68
|
+
&.highlighted {
|
|
69
|
+
box-shadow: 0px 4px 4px 0px var(--UI-Shadow, rgba(17, 36, 69, 0.16)),
|
|
70
|
+
0px 1px 16px 0px var(--UI-Shadow, rgba(17, 36, 69, 0.16));
|
|
71
|
+
background-color: #F0F3F5;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
div.step-header {
|
|
75
|
+
h4 {
|
|
76
|
+
font-size : 20px;
|
|
77
|
+
margin-bottom: 0;
|
|
78
|
+
margin-top : 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
div.step_dates {
|
|
82
|
+
font-size : 11px;
|
|
83
|
+
background-color: #cdcccc;
|
|
84
|
+
color : #000000;
|
|
85
|
+
margin : 5px;
|
|
86
|
+
padding : 2px 5px;
|
|
87
|
+
border-radius : 5px;
|
|
88
|
+
height : 20px;
|
|
89
|
+
float : right;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
div.collapse-button {
|
|
93
|
+
border-radius: 50%;
|
|
94
|
+
width : 30px;
|
|
95
|
+
height : 30px;
|
|
96
|
+
text-align : center;
|
|
97
|
+
padding : 5px 0px;
|
|
98
|
+
margin : 0 5px 3px 0;
|
|
99
|
+
cursor : pointer;
|
|
100
|
+
background : #dfe6f7;
|
|
101
|
+
color : #7a8bad;
|
|
102
|
+
float : right;
|
|
103
|
+
transition : transform 0.3s ease-in-out;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.step_description {
|
|
108
|
+
clear: both;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.show-all {
|
|
112
|
+
div.collapse-button {
|
|
113
|
+
transform: rotate(180deg);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
div.details {
|
|
117
|
+
max-height: 10000px;
|
|
118
|
+
/* Adjust this value as needed */
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
div.details {
|
|
123
|
+
max-height: 0px;
|
|
124
|
+
overflow : hidden;
|
|
125
|
+
transition: max-height 0.3s ease-in-out;
|
|
126
|
+
|
|
127
|
+
div.intervention {
|
|
128
|
+
background-color: #FFFFFF;
|
|
129
|
+
border-radius : 5px;
|
|
130
|
+
margin-bottom : 11px;
|
|
131
|
+
padding : 13px;
|
|
132
|
+
cursor : pointer;
|
|
133
|
+
|
|
134
|
+
span.intervention_title {
|
|
135
|
+
font-weight: bold;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
span.intervention_date {
|
|
139
|
+
color : #707070;
|
|
140
|
+
background-color: #F0F3F5;
|
|
141
|
+
float : right;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
div.intervention_description {
|
|
145
|
+
margin-top: 5px;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.step-edit {
|
|
151
|
+
display: none;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.charts {
|
|
156
|
+
width : 100%;
|
|
157
|
+
height : 500px;
|
|
158
|
+
display: inline-block;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.transcript {
|
|
162
|
+
font-size : 80%;
|
|
163
|
+
width : 100%;
|
|
164
|
+
max-height : 450px;
|
|
165
|
+
overflow-y : scroll;
|
|
166
|
+
scroll-behavior: smooth;
|
|
167
|
+
padding : 3px;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.rotation-tooltip {
|
|
172
|
+
max-width : 400px;
|
|
173
|
+
text-align: left;
|
|
174
|
+
|
|
175
|
+
div.step_dates {
|
|
176
|
+
font-size : 9px;
|
|
177
|
+
background-color: #cdcccc;
|
|
178
|
+
color : #000000;
|
|
179
|
+
margin : 5px;
|
|
180
|
+
padding : 0px 5px;
|
|
181
|
+
border-radius : 5px;
|
|
182
|
+
float: right;
|
|
183
|
+
}
|
|
184
|
+
}
|
package/examples/README.md
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# Exemples d'utilisation
|
|
2
|
-
|
|
3
|
-
Ce dossier contient des exemples d'intégration du visualisateur d'itinéraires techniques TIKA dans différents contextes.
|
|
4
|
-
|
|
5
|
-
## Fichiers disponibles
|
|
6
|
-
|
|
7
|
-
### Next.js
|
|
8
|
-
|
|
9
|
-
- **`nextjs-app-router-viewer.tsx`** - Exemple de page de visualisation avec Next.js App Router (13+)
|
|
10
|
-
- Affichage d'un itinéraire technique
|
|
11
|
-
- Gestion du chargement des données
|
|
12
|
-
- Événements de clic et survol
|
|
13
|
-
|
|
14
|
-
- **`nextjs-app-router-editor.tsx`** - Exemple d'éditeur complet avec Next.js App Router
|
|
15
|
-
- Interface complète d'édition
|
|
16
|
-
- Ajout/modification/suppression d'étapes
|
|
17
|
-
- Gestion des interventions
|
|
18
|
-
- Sauvegarde et export
|
|
19
|
-
|
|
20
|
-
- **`nextjs-_document.tsx`** - Configuration du document Next.js
|
|
21
|
-
- Chargement des dépendances CDN
|
|
22
|
-
- Configuration des scripts et styles
|
|
23
|
-
- Compatible Pages Router
|
|
24
|
-
|
|
25
|
-
- **`nextjs-api-route.ts`** - Exemple d'API Routes
|
|
26
|
-
- Sauvegarde et chargement d'itinéraires
|
|
27
|
-
- CRUD complet
|
|
28
|
-
- Gestion des fichiers JSON
|
|
29
|
-
|
|
30
|
-
## Utilisation
|
|
31
|
-
|
|
32
|
-
### 1. Copier les exemples
|
|
33
|
-
|
|
34
|
-
Copiez les fichiers dans votre projet Next.js :
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
# Pour le visualiseur
|
|
38
|
-
cp examples/nextjs-app-router-viewer.tsx app/itineraire/page.tsx
|
|
39
|
-
|
|
40
|
-
# Pour l'éditeur
|
|
41
|
-
cp examples/nextjs-app-router-editor.tsx app/editor/page.tsx
|
|
42
|
-
|
|
43
|
-
# Pour la configuration
|
|
44
|
-
cp examples/nextjs-_document.tsx pages/_document.tsx # Pages Router
|
|
45
|
-
# ou adaptez pour app/layout.tsx (App Router)
|
|
46
|
-
|
|
47
|
-
# Pour l'API
|
|
48
|
-
cp examples/nextjs-api-route.ts app/api/itineraire/route.ts # App Router
|
|
49
|
-
# ou pages/api/itineraire.ts (Pages Router)
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### 2. Installer les dépendances
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
npm install @osfarm/itineraire-technique
|
|
56
|
-
npm run setup:react
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### 3. Adapter à votre projet
|
|
60
|
-
|
|
61
|
-
Les exemples sont commentés et peuvent être adaptés à vos besoins spécifiques :
|
|
62
|
-
|
|
63
|
-
- Personnalisez les styles
|
|
64
|
-
- Ajoutez votre logique métier
|
|
65
|
-
- Intégrez avec votre base de données
|
|
66
|
-
- Ajoutez l'authentification
|
|
67
|
-
|
|
68
|
-
## Structure d'un projet Next.js complet
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
my-app/
|
|
72
|
-
├── app/ # App Router (Next.js 13+)
|
|
73
|
-
│ ├── layout.tsx # Layout principal avec scripts CDN
|
|
74
|
-
│ ├── itineraire/
|
|
75
|
-
│ │ └── page.tsx # Page de visualisation
|
|
76
|
-
│ ├── editor/
|
|
77
|
-
│ │ └── page.tsx # Page d'édition
|
|
78
|
-
│ └── api/
|
|
79
|
-
│ └── itineraire/
|
|
80
|
-
│ └── route.ts # API Routes
|
|
81
|
-
├── public/ # Fichiers statiques
|
|
82
|
-
│ ├── js/
|
|
83
|
-
│ │ ├── chart-render.js
|
|
84
|
-
│ │ └── editor-*.js
|
|
85
|
-
│ ├── css/
|
|
86
|
-
│ │ ├── styles-rendering.css
|
|
87
|
-
│ │ └── styles-editor.css
|
|
88
|
-
│ └── test/
|
|
89
|
-
│ └── test.json
|
|
90
|
-
├── package.json
|
|
91
|
-
└── tsconfig.json
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Frameworks alternatifs
|
|
95
|
-
|
|
96
|
-
Bien que ces exemples soient pour Next.js, les composants React sont compatibles avec :
|
|
97
|
-
|
|
98
|
-
- **Create React App** - Ajoutez les scripts CDN dans `public/index.html`
|
|
99
|
-
- **Vite** - Ajoutez les scripts CDN dans `index.html`
|
|
100
|
-
- **Remix** - Ajoutez les scripts dans `root.tsx`
|
|
101
|
-
- **Gatsby** - Utilisez `gatsby-ssr.js` pour ajouter les scripts
|
|
102
|
-
|
|
103
|
-
## Support TypeScript
|
|
104
|
-
|
|
105
|
-
Tous les exemples sont fournis en TypeScript avec les types complets. Si vous utilisez JavaScript, supprimez simplement les annotations de type.
|
|
106
|
-
|
|
107
|
-
## Personnalisation
|
|
108
|
-
|
|
109
|
-
### Thème et styles
|
|
110
|
-
|
|
111
|
-
Vous pouvez personnaliser les styles en :
|
|
112
|
-
|
|
113
|
-
1. Surchargeant les classes CSS existantes
|
|
114
|
-
2. Modifiant les fichiers SCSS sources
|
|
115
|
-
3. Utilisant la prop `className` des composants
|
|
116
|
-
|
|
117
|
-
### Événements
|
|
118
|
-
|
|
119
|
-
Les composants exposent des callbacks pour interagir avec eux :
|
|
120
|
-
|
|
121
|
-
```tsx
|
|
122
|
-
<TikaRenderer
|
|
123
|
-
data={data}
|
|
124
|
-
onItemClick={(id, event) => {
|
|
125
|
-
// Votre logique
|
|
126
|
-
}}
|
|
127
|
-
onItemHover={(id, event) => {
|
|
128
|
-
// Votre logique
|
|
129
|
-
}}
|
|
130
|
-
/>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Besoin d'aide ?
|
|
134
|
-
|
|
135
|
-
- Consultez la [documentation React](../react/README.md)
|
|
136
|
-
- Consultez le [Quick Start](../react/QUICKSTART.md)
|
|
137
|
-
- Ouvrez une [issue sur GitHub](https://github.com/osfarm/itineraire-technique/issues)
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exemple de _document.tsx pour Next.js Pages Router
|
|
3
|
-
* Fichier: pages/_document.tsx
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Html, Head, Main, NextScript } from 'next/document';
|
|
7
|
-
|
|
8
|
-
export default function Document() {
|
|
9
|
-
return (
|
|
10
|
-
<Html lang="fr">
|
|
11
|
-
<Head>
|
|
12
|
-
{/* ECharts - Bibliothèque de graphiques */}
|
|
13
|
-
<script src="https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.js"></script>
|
|
14
|
-
|
|
15
|
-
{/* jQuery et jQuery UI */}
|
|
16
|
-
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
|
17
|
-
<script src="https://cdn.jsdelivr.net/npm/jquery-ui@1.14.1/dist/jquery-ui.min.js"></script>
|
|
18
|
-
<link
|
|
19
|
-
rel="stylesheet"
|
|
20
|
-
href="https://cdn.jsdelivr.net/npm/jquery-ui@1.14.1/themes/base/jquery-ui.css"
|
|
21
|
-
/>
|
|
22
|
-
|
|
23
|
-
{/* Underscore.js */}
|
|
24
|
-
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.7/underscore-umd-min.js"></script>
|
|
25
|
-
|
|
26
|
-
{/* Bootstrap */}
|
|
27
|
-
<script
|
|
28
|
-
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
|
|
29
|
-
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
|
|
30
|
-
crossOrigin="anonymous"
|
|
31
|
-
></script>
|
|
32
|
-
<link
|
|
33
|
-
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
34
|
-
rel="stylesheet"
|
|
35
|
-
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
|
|
36
|
-
crossOrigin="anonymous"
|
|
37
|
-
/>
|
|
38
|
-
|
|
39
|
-
{/* Font Awesome */}
|
|
40
|
-
<link
|
|
41
|
-
href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"
|
|
42
|
-
rel="stylesheet"
|
|
43
|
-
/>
|
|
44
|
-
|
|
45
|
-
{/*
|
|
46
|
-
Scripts TIKA - À copier dans le dossier public/
|
|
47
|
-
Voir instructions dans react/README.md
|
|
48
|
-
*/}
|
|
49
|
-
<script src="/chart-render.js"></script>
|
|
50
|
-
<script src="/editor-attributes.js"></script>
|
|
51
|
-
<script src="/editor-interventions.js"></script>
|
|
52
|
-
<script src="/editor-crops.js"></script>
|
|
53
|
-
<script src="/editor-export.js"></script>
|
|
54
|
-
<script src="/editor-wiki-editor.js"></script>
|
|
55
|
-
|
|
56
|
-
{/* Styles TIKA - À copier dans le dossier public/ */}
|
|
57
|
-
<link href="/styles-rendering.css" rel="stylesheet" />
|
|
58
|
-
<link href="/styles-editor.css" rel="stylesheet" />
|
|
59
|
-
</Head>
|
|
60
|
-
<body>
|
|
61
|
-
<Main />
|
|
62
|
-
<NextScript />
|
|
63
|
-
</body>
|
|
64
|
-
</Html>
|
|
65
|
-
);
|
|
66
|
-
}
|