Skip to content

Commit

Permalink
Adding monaco editor for vynil
Browse files Browse the repository at this point in the history
  • Loading branch information
sebt3 committed Jan 21, 2024
1 parent 6b2fa3d commit 28077c9
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 34 deletions.
38 changes: 38 additions & 0 deletions front/components/core/MonacoEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script setup lang="ts">
import * as monaco from 'monaco-editor'
import { ref, onMounted, nextTick } from "vue";
const emit = defineEmits(['update:text'])
const props = withDefaults(defineProps<{
text: string
lang?: string
theme?: string
wordWrap?: "wordWrapColumn" | "off" | "on" | "bounded"
wrappingIndent?: "indent" | "none" | "same" | "deepIndent"
lineNumber?: boolean
automaticLayout?: boolean,
}>(),{
lang: "yaml",
theme: "vs-dark",
lineNumber: true,
wrappingIndent: "indent",
wordWrap: "wordWrapColumn",
automaticLayout: true,
});
const height = window.innerHeight - 300;
const code=ref(null);
onMounted(() => {
const editor = monaco.editor.create(code.value as unknown as HTMLElement, {
value: props.text,
theme: props.theme,
language: props.lang,
lineNumbers: props.lineNumber?"on":"off",
wordWrap: props.wordWrap,
wrappingIndent: props.wrappingIndent,
});
editor.focus();
editor.onDidBlurEditorText(() => {console.log('blur');emit('update:text', editor.getValue())})
});
</script>
<template>
<div ref="code" :style="`min-height: 400px;height:${height}px;width:100%;`"></div>
</template>
12 changes: 10 additions & 2 deletions front/components/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useRouter } from 'vue-router'
import { useQuasar } from 'quasar'
import { setupTableWidget } from './tableSetup.js'
import { setupItem } from './itemSetup.js'
import { stringify } from 'yaml'
import { stringify, parse } from 'yaml'
import { ref } from 'vue'

export * from './itemSetup.js'
Expand All @@ -23,9 +23,17 @@ export function useCore() {
full: '',
spec: ''
});
const editor = ref({
tab: 'simple',
yaml: '',
spec: {},
setSpec: (s) => {editor.value.spec = s;editor.value.yaml = stringify(s)},
setYaml: (y) => {editor.value.yaml = y;editor.value.spec = parse(y);console.log(editor.value.spec)},
updateFromQuery: (res: object, obj: object) => {if(!res['loading'])editor.value.setSpec(obj)},
});
return {
router, $q, pagination, setNamespaceFromRoute, setItemFromRoute, setNamespacedItemFromRoute,
viewer, viewerUpdate: (res, obj) => {
editor, viewer, viewerUpdate: (res, obj) => {
if(!res.loading) {
viewer.value.full=gqlDataToYaml(obj)
viewer.value.spec=gqlDataToYaml({spec: obj.spec})
Expand Down
4 changes: 2 additions & 2 deletions front/components/vynil/Distrib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export const packageColumns:Array<QTableColumn> = [
];

export function useDistrib() {
const { viewer, viewerUpdate, router, $q, pagination, setItemFromRoute, onErrorHandler, notify, notifySuccess, notifyError, notifyWorking } = useCore();
const { editor, viewer, viewerUpdate, router, $q, pagination, setItemFromRoute, onErrorHandler, notify, notifySuccess, notifyError, notifyWorking } = useCore();
return {
navigation: useNavigationStoreRef(),
viewer, viewerUpdate, router, pagination, setItemFromRoute, notify, notifySuccess, notifyError, notifyWorking, onErrorHandler,
editor, viewer, viewerUpdate, router, pagination, setItemFromRoute, notify, notifySuccess, notifyError, notifyWorking, onErrorHandler,
onNotDistribFound: (res) => {
if ( !res.loading && res.data.vynilDistrib == null) {
const matched = router.currentRoute.value.matched
Expand Down
33 changes: 20 additions & 13 deletions front/components/vynil/DistribEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import vynilDistribQuery from '@/queries/vynil/DistribView.graphql'
import distribEdit from '@/queries/vynil/DistribEdit.graphql'
import MetadataView from '../core/MetadataView.vue';
import OpenApiEdit from '../core/OpenApiEdit.vue';
import MonacoEditor from '../core/MonacoEditor.vue';
import { ref, useQuery, useMutation, useDistrib, sanitizeData, getProperties } from './Distrib.js'
const data = ref({});
const { patchDone, patchError, notifyWorking, onNotDistribFound, setItemFromRoute, navigation, onErrorHandler } = useDistrib();setItemFromRoute();
const { editor, patchDone, patchError, notifyWorking, onNotDistribFound, setItemFromRoute, navigation, onErrorHandler } = useDistrib();setItemFromRoute();
const { result, loading, onResult, onError } = useQuery(vynilDistribQuery, {"name": navigation.currentItem}, { pollInterval: 500 });
const { mutate: patchDistrib, onDone: onPatchDistrib, onError: onPatchError } = useMutation(distribEdit);
function onSubmit() {
notifyWorking('Update in progress');
patchDistrib({"name": result.value.vynilDistrib.metadata.name, "spec": sanitizeData(data.value)});
patchDistrib({"name": result.value.vynilDistrib.metadata.name, "spec": sanitizeData(editor.value.tab=='simple'?data.value:editor.value.spec)});
}
onError(onErrorHandler);onResult(onNotDistribFound);onPatchDistrib(patchDone);onPatchError(patchError);
onError(onErrorHandler);onResult(res => {onNotDistribFound(res);editor.value.updateFromQuery(res, res.loading?{}:{options: res.data.vynilDistrib.metadata.obj.spec})});onPatchDistrib(patchDone);onPatchError(patchError);
</script>
<template>
<div class="row q-mb-sm q-ml-sm">
Expand Down Expand Up @@ -52,16 +53,22 @@ onError(onErrorHandler);onResult(onNotDistribFound);onPatchDistrib(patchDone);on
</div>
<q-form @submit="onSubmit" class="q-gutter-md q-pt-sm q-ml-sm">
<q-card bordered v-if="!loading && result.vynilDistrib!=null" class="q-ma-sm">
<q-card-section>
<div class="text-h6 text-grey-8 q-mt-none q-mb-none q-pt-none q-pb-none">Specification</div>
</q-card-section>
<q-card-section>
<OpenApiEdit
v-model:out="data"
:in="result.vynilDistrib"
:properties="getProperties(result.customResourceDefinition.versions.filter(v => v.served)[0].schema.openAPIV3Schema.properties.spec)"
/>
</q-card-section>
<q-tabs v-model="editor.tab" class="bg-primary text-white">
<q-tab label="Options" name="simple" />
<q-tab label="Specifications" name="spec" />
</q-tabs>
<q-tab-panels v-model="editor.tab" animated>
<q-tab-panel name="simple">
<OpenApiEdit
v-model:out="data"
:in="result.vynilDistrib"
:properties="getProperties(result.customResourceDefinition.versions.filter(v => v.served)[0].schema.openAPIV3Schema.properties.spec)"
/>
</q-tab-panel>
<q-tab-panel name="spec">
<MonacoEditor :text="editor.yaml" :key="editor.yaml" @update:text="v=>editor.setYaml(v)" />
</q-tab-panel>
</q-tab-panels>
<q-card-actions>
<q-btn label="Submit" type="submit" color="primary"/>
</q-card-actions>
Expand Down
4 changes: 2 additions & 2 deletions front/components/vynil/Install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ export const installAllColumns = ([
] as Array<QTableColumn>).concat(installColumns);

export function useInstall() {
const { viewer, viewerUpdate, router, $q, pagination, setNamespaceFromRoute, setItemFromRoute, onErrorHandler, notify, notifySuccess, notifyError, notifyWorking, setNamespacedItemFromRoute } = useCore();
const { editor, viewer, viewerUpdate, router, $q, pagination, setNamespaceFromRoute, setItemFromRoute, onErrorHandler, notify, notifySuccess, notifyError, notifyWorking, setNamespacedItemFromRoute } = useCore();
return {
navigation: useNavigationStoreRef(),
viewer, viewerUpdate, router, pagination, setNamespaceFromRoute, setItemFromRoute, setNamespacedItemFromRoute, notify, notifySuccess, notifyError, notifyWorking, onErrorHandler,
editor, viewer, viewerUpdate, router, pagination, setNamespaceFromRoute, setItemFromRoute, setNamespacedItemFromRoute, notify, notifySuccess, notifyError, notifyWorking, onErrorHandler,
onNotInstallFound: (res) => {
if ( !res.loading && res.data.vynilInstall == null) {
const matched = router.currentRoute.value.matched
Expand Down
37 changes: 22 additions & 15 deletions front/components/vynil/InstallEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import vynilInstallQuery from '@/queries/vynil/InstallView.graphql'
import installEdit from '@/queries/vynil/InstallEdit.graphql'
import MetadataView from '../core/MetadataView.vue';
import OpenApiEdit from '../core/OpenApiEdit.vue';
import MonacoEditor from '../core/MonacoEditor.vue';
import { useInstall, ref, useMutation, useQuery, sanitizeData } from './Install.js'
const { onNotInstallFound, onErrorHandler, navigation, setNamespacedItemFromRoute, patchDone, patchError, notifyWorking } = useInstall();setNamespacedItemFromRoute();
const { editor, onNotInstallFound, onErrorHandler, navigation, setNamespacedItemFromRoute, patchDone, patchError, notifyWorking } = useInstall();setNamespacedItemFromRoute();
const { result, loading, onResult, onError } = useQuery(vynilInstallQuery, {"namespace": navigation.currentNamespace, "name": navigation.currentItem}, { pollInterval: 500 });
const { mutate: patchInstall, onDone: onPatchInstall, onError: onPatchError } = useMutation(installEdit);
const data = ref({});
Expand All @@ -19,16 +20,16 @@ function onSubmit() {
"distrib":result.value.vynilInstall.distrib.metadata.name,
"component":result.value.vynilInstall.component.name,
...spec,
"options": {
"options": editor.value.tab=='simple'?{
...result.value.vynilInstall.options,
...sanitizeData(data.value)
}
}:sanitizeData(editor.value.spec['options'])
}
}
console.log(payload)
patchInstall(payload);
}
onError(onErrorHandler);onResult(onNotInstallFound);onPatchInstall(patchDone);onPatchError(patchError);
onError(onErrorHandler);onResult(res => {onNotInstallFound(res);editor.value.updateFromQuery(res, res.loading?{}:{options: res.data.vynilInstall.metadata.obj.spec.options})});onPatchInstall(patchDone);onPatchError(patchError);
</script>
<template>
<div class="row q-mb-sm q-ml-sm">
Expand Down Expand Up @@ -88,17 +89,23 @@ onError(onErrorHandler);onResult(onNotInstallFound);onPatchInstall(patchDone);on
</div>
</div>
<q-form @submit="onSubmit" class="q-gutter-md q-pt-sm q-ml-sm">
<q-card v-if="!loading && result!=null && result.vynilInstall!=null">
<q-card-section>
<div class="text-h5 q-mt-none q-mb-none">Options</div>
</q-card-section>
<q-card-section>
<OpenApiEdit
:in="result.vynilInstall.options"
v-model:out="data"
:properties="new Map(Object.entries(result.vynilInstall.component.options))"
/>
</q-card-section>
<q-card v-if="!loading && result!=null && result.vynilInstall!=null" class="q-ma-sm">
<q-tabs v-model="editor.tab" class="bg-primary text-white">
<q-tab label="Options" name="simple" />
<q-tab label="Specifications" name="spec" />
</q-tabs>
<q-tab-panels v-model="editor.tab" animated>
<q-tab-panel name="simple">
<OpenApiEdit
:in="result.vynilInstall.options"
v-model:out="data"
:properties="new Map(Object.entries(result.vynilInstall.component.options))"
/>
</q-tab-panel>
<q-tab-panel name="spec">
<MonacoEditor :text="editor.yaml" :key="editor.yaml" @update:text="v=>editor.setYaml(v)" />
</q-tab-panel>
</q-tab-panels>
<q-card-actions>
<q-btn label="Submit" type="submit" color="primary"/>
</q-card-actions>
Expand Down
24 changes: 24 additions & 0 deletions front/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import { useNavigationStore } from './stores/navigation'
import { useConfigStore } from './stores/config'
import { usePermissionStore } from './stores/permission'
import { useCRDStore } from './stores/crds'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'

self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json') {
return new jsonWorker()
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker()
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker()
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
}
return new editorWorker()
}
}

const apolloClient = new ApolloClient({
uri: () => {return window.location.origin+'/graphql'},
cache: new InMemoryCache(),
Expand Down

0 comments on commit 28077c9

Please sign in to comment.