Skip to content

Commit 3e08b16

Browse files
authored
feat(ui): editor plugin doc must be always visible and cached (#1087)
1 parent 4e3008d commit 3e08b16

File tree

5 files changed

+71
-33
lines changed

5 files changed

+71
-33
lines changed

Diff for: ui/src/components/inputs/Editor.vue

+44-13
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@
1313
</el-tooltip>
1414
</el-button-group>
1515
<span v-if="!this.guidedProperties.tourStarted">
16-
<el-tooltip v-if="editorTypeDocumentation" :content="editorDocumentation ? $t('hide task documentation') : $t('show task documentation')" :persistent="false" transition="" :hide-after="0">
16+
<el-tooltip :content="editorDocumentation ? $t('hide task documentation') : $t('show task documentation')" :persistent="false" transition="" :hide-after="0">
1717
<el-button type="info" :icon="editorDocumentation ? icon.Close : icon.BookMultipleOutline" circle style="float: right" size="small" @click="setShowDocumentation" />
1818
</el-tooltip>
19-
<el-tooltip v-else :content="$t('Click on a task to show documentation')" :persistent="false" transition="" :hide-after="0">
20-
<el-button type="info" :icon="icon.Help" circle style="float: right" size="small" @click="setShowDocumentation" />
21-
</el-tooltip>
2219
</span>
2320
</nav>
2421

@@ -45,8 +42,12 @@
4542
{{ placeholder }}
4643
</div>
4744
</div>
48-
<div v-if="!this.guidedProperties.tourStarted" :class="[editorTypeDocumentation && plugin && editorDocumentation ? 'plugin-doc-active' : '','plugin-doc']">
45+
<div v-if="!this.guidedProperties.tourStarted" :class="[editorDocumentation ? 'plugin-doc-active' : '','plugin-doc']">
4946
<markdown v-if="plugin" :source="plugin.markdown" />
47+
<div v-else>
48+
<div class="img get-started" />
49+
<el-alert type="info" :title="$t('focus task')" show-icon :closable="false" />
50+
</div>
5051
</div>
5152
</div>
5253
</div>
@@ -100,11 +101,13 @@
100101
Close: shallowRef(Close)
101102
},
102103
oldDecorations: [],
103-
editorDocumentation: undefined
104+
editorDocumentation: undefined,
105+
plugin: undefined,
106+
taskType: undefined
104107
};
105108
},
106109
computed: {
107-
...mapState("plugin", ["plugin","pluginSingleList","editorTypeDocumentation"]),
110+
...mapState("plugin", ["pluginSingleList","pluginsDocumentation"]),
108111
...mapGetters("core", ["guidedProperties"]),
109112
themeComputed() {
110113
const darkTheme = document.getElementsByTagName("html")[0].className.indexOf("dark") >= 0;
@@ -317,13 +320,20 @@
317320
let model = this.editor.getModel();
318321
const taskType = yamlUtils.getTaskType(model.getValue(),position)
319322
if (taskType && this.pluginSingleList.includes(taskType)) {
320-
if(localStorage.getItem("editorDocumentation") !== "false") {
323+
if (!this.pluginsDocumentation[taskType]) {
321324
this.$store
322325
.dispatch("plugin/load", {cls: taskType})
326+
.then(plugin => {
327+
this.$store.commit("plugin/setPluginsDocumentation", {...this.pluginsDocumentation, [taskType]: plugin});
328+
this.plugin = plugin;
329+
});
330+
} else if (this.pluginsDocumentation[taskType]) {
331+
this.plugin = this.pluginsDocumentation[taskType];
323332
}
324-
this.$store.commit("plugin/setEditorTypeDocumentation", taskType);
333+
this.taskType = taskType;
325334
} else {
326-
this.$store.commit("plugin/setEditorTypeDocumentation", undefined);
335+
this.plugin = undefined;
336+
this.taskType = undefined;
327337
}
328338
});
329339
},
@@ -358,9 +368,17 @@
358368
setShowDocumentation() {
359369
this.editorDocumentation = !this.editorDocumentation;
360370
localStorage.setItem("editorDocumentation", (this.editorDocumentation).toString());
361-
if(this.editorTypeDocumentation) {
362-
this.$store
363-
.dispatch("plugin/load", {cls: this.editorTypeDocumentation})
371+
if (this.taskType) {
372+
if (!this.pluginsDocumentation[this.taskType]) {
373+
this.$store
374+
.dispatch("plugin/load", {cls: this.taskType})
375+
.then(plugin => {
376+
this.$store.commit("plugin/setPluginsDocumentation", {...this.pluginsDocumentation, [this.taskType]: plugin});
377+
this.plugin = plugin;
378+
});
379+
} else if (this.pluginsDocumentation[this.taskType]) {
380+
this.plugin = this.pluginsDocumentation[this.taskType];
381+
}
364382
}
365383
}
366384
},
@@ -486,4 +504,17 @@
486504
padding: calc(var(--spacer)*1.5);
487505
}
488506
507+
div.img {
508+
min-height: 130px;
509+
height: 100%;
510+
511+
&.get-started {
512+
background: url("../../assets/onboarding/onboarding-started-light.svg") no-repeat center;
513+
514+
html.dark & {
515+
background: url("../../assets/onboarding/onboarding-started-dark.svg") no-repeat center;
516+
}
517+
}
518+
}
519+
489520
</style>

Diff for: ui/src/stores/plugins.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
plugins: undefined,
66
pluginSingleList: undefined,
77
icons: undefined,
8-
editorTypeDocumentation: undefined
8+
pluginsDocumentation: {}
99
},
1010
actions: {
1111
list({commit}) {
@@ -48,8 +48,8 @@ export default {
4848
setIcons(state, icons) {
4949
state.icons = icons
5050
},
51-
setEditorTypeDocumentation(state, editorTypeDocumentation) {
52-
state.editorTypeDocumentation = editorTypeDocumentation
51+
setPluginsDocumentation(state, pluginsDocumentation) {
52+
state.pluginsDocumentation = pluginsDocumentation
5353
}
5454
},
5555
getters: {}

Diff for: ui/src/translations.json

+7-5
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@
377377
"show task documentation": "Show Task documentation",
378378
"hide task documentation": "Hide Task documentation",
379379
"show task documentation in editor": "Show Task documentation in editor",
380-
"show documentation": "Show documentation"
380+
"show documentation": "Show documentation",
381+
"focus task": "Focus on any element to see its documentation."
381382
},
382383
"fr": {
383384
"id": "Identifiant",
@@ -755,9 +756,10 @@
755756
"watch demo content": "Obtenez un aperçu de la puissance de Kestra grâce à notre vidéo de démonstration.",
756757
"need help?": "Besoin d'aide?",
757758
"need help? content": "Besoin d'assistance pour une fonctionnalité ou un flow? Notre communauté d'ingénieurs data et de développeurs sont là pour aider.",
758-
"show task documentation": "Show Task documentation",
759-
"hide task documentation": "Hide Task documentation",
760-
"show task documentation in editor": "Show Task documentation in editor",
761-
"show documentation": "Show documentation"
759+
"show task documentation": "Afficher la documentation des tâches",
760+
"hide task documentation": "Cacher la documentation des tâches",
761+
"show task documentation in editor": "Afficher la documentation dans l'éditeur",
762+
"show documentation": "Afficher la documentation",
763+
"focus task": "Cliquer sur une tâche pour voir sa documentation"
762764
}
763765
}

Diff for: ui/src/utils/yamlUtils.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,11 @@ export default class YamlUtils {
166166
const lineCounter = new LineCounter();
167167
const yamlDoc = yaml.parseDocument(source, {lineCounter});
168168
const cursorIndex = lineCounter.lineStarts[position.lineNumber-1] + position.column;
169-
for(const item of yamlDoc.contents.items){
170-
if(item.value instanceof YAMLSeq && item.key.range[0] <= cursorIndex && item.value.range[1] >= cursorIndex){
171-
return YamlUtils._getTaskType(item.value, cursorIndex, null)
169+
if(yamlDoc.contents) {
170+
for (const item of yamlDoc.contents.items) {
171+
if (item.value instanceof YAMLSeq && item.key.range[0] <= cursorIndex && item.value.range[1] >= cursorIndex) {
172+
return YamlUtils._getTaskType(item.value, cursorIndex, null)
173+
}
172174
}
173175
}
174176
}

Diff for: webserver/src/main/java/io/kestra/webserver/controllers/PluginController.java

+12-9
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public Map<String, PluginIcon> icons() {
120120
@Get(uri = "{cls}")
121121
@ExecuteOn(TaskExecutors.IO)
122122
@Operation(tags = {"Plugins"}, summary = "Get plugin documentation")
123-
public Doc pluginDocumentation(
123+
@Cacheable("default")
124+
public HttpResponse<Doc> pluginDocumentation(
124125
@Parameter(description = "The plugin full class name") @PathVariable String cls,
125126
@Parameter(description = "Include all the properties") @QueryValue(value = "all", defaultValue = "false") boolean allProperties
126127
) throws IOException {
@@ -130,14 +131,16 @@ public Doc pluginDocumentation(
130131
allProperties
131132
);
132133

133-
return new Doc(
134-
DocumentationGenerator.render(classPluginDocumentation),
135-
new Schema(
136-
classPluginDocumentation.getPropertiesSchema(),
137-
classPluginDocumentation.getOutputsSchema(),
138-
classPluginDocumentation.getDefs()
139-
)
140-
);
134+
return HttpResponse.ok()
135+
.body(new Doc(
136+
DocumentationGenerator.render(classPluginDocumentation),
137+
new Schema(
138+
classPluginDocumentation.getPropertiesSchema(),
139+
classPluginDocumentation.getOutputsSchema(),
140+
classPluginDocumentation.getDefs()
141+
)
142+
))
143+
.header("Cache-Control", "public, max-age=3600");
141144
}
142145

143146
@SuppressWarnings({"rawtypes", "unchecked"})

0 commit comments

Comments
 (0)