Skip to content

Commit

Permalink
0.3.2: tekton improvments
Browse files Browse the repository at this point in the history
  • Loading branch information
sebt3 committed Apr 26, 2024
1 parent 0f14336 commit 18455a4
Show file tree
Hide file tree
Showing 14 changed files with 307 additions and 31 deletions.
94 changes: 94 additions & 0 deletions front/components/generic/GenericView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,38 @@ const props = withDefaults(defineProps<{model: object, group:string, short:strin
});
const { loader } = await import("../../libs/core/importer")
const { defineAsyncComponent, onMounted, elude, getColor, timeAgo, useItem, getProperties, colorItem, itemDefinition, iconItem, extraColumns } = await loader(props.group,props.short)
const { ref } = await import('vue')
const { useRouter } = await import('vue-router')
const router = useRouter();
const { setNamespacedItemFromRoute, setItemFromRoute } = await import('../../libs/core/navigation.js')
const { $q, can, onlyReadProperties, toParentView, viewer, viewerUpdate, toEdit, writeProperties, namespaced } = useItem(router);
if (namespaced) setNamespacedItemFromRoute();
else setItemFromRoute();
onMounted(() => { viewerUpdate(onlyReadProperties(props.model)) })
const PipelineRun = defineAsyncComponent(() => import( '@/components/tekton/PipelineRun.vue'));
const OpenApiEdit = defineAsyncComponent(() => import( '@/components/openapi/OpenApiEdit.vue'));
const EventList = defineAsyncComponent(() => import( '@/components/core/EventList.vue'));
const MonacoViewer = defineAsyncComponent(() => import( '@/components/core/MonacoViewer.vue'));
const OpenApiNamedIcon = defineAsyncComponent(() => import( '@/components/openapi/OpenApiNamedIcon.vue'));
const logViewTab = ref((
['TaskRun','Job','ReplicaSet','DaemonSet','StatefulSet'].includes(props.short) && props.model.childk8sPod != undefined && props.model.childk8sPod.filter(x=>x!=undefined).map(pod=>pod.childcoreContainer.filter(c=>!c.init)).flat().length>0)?props.model.childk8sPod.filter(x=>x!=undefined).map(pod=>pod.childcoreContainer.filter(c=>!c.init)).flat()[0].name
:(['PipelineRun'].includes(props.short)&& props.model.childtektonTaskRun != undefined && props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0&&Array.isArray(tr.getcoreProblem)).length>0)?props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0&&Array.isArray(tr.getcoreProblem))[0].metadata.name
:(['PipelineRun'].includes(props.short)&& props.model.childtektonTaskRun != undefined && props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0).length>0)?props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0).sort((a,b)=>a.metadata.creationTimestamp<b.metadata.creationTimestamp?-1:1)[0].metadata.name
:'none')
const logViewSplitterModel= ref(20)
if (['Install'].includes(props.short)) console.log(props.model, props.model.metadata.name)
if (['Install'].includes(props.short)) console.log(props.model.usek8sJob)
</script>
<template>
<q-card bordered class="q-ma-sm">
<q-tabs v-model="viewer.tab" :class="`bg-${ colorItem } text-grey-2`" active-color="white" align="justify">
<q-avatar :icon="iconItem" />
<q-tab :label="props.short" name="meta" />
<q-tab :label="$t('container.log')" name="logs" v-if="['TaskRun','Job','Deployment','ReplicaSet','DaemonSet','StatefulSet'].includes(props.short) && props.model.childk8sPod != undefined" />
<q-tab :label="$t('container.log')" name="logs" v-if="['PipelineRun'].includes(props.short) && Array.isArray(props.model.childtektonTaskRun)" />
<q-tab :label="$t('container.log')" name="logs" v-if="['Deployment'].includes(props.short) && Array.isArray(props.model.childk8sReplicaSet) && props.model.childk8sReplicaSet.filter(rs=>Array.isArray(rs.childk8sPod)).length>0" />
<q-tab :label="$t('container.log')" name="logs" v-if="['Install'].includes(props.short) && Array.isArray(props.model.usek8sJob) && props.model.usek8sJob.filter(rs=>Array.isArray(rs.childk8sPod) && rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)).length>0).length>0" />
<q-tab :label="$t('core.events')" name="events" v-if="Array.isArray(model['getcoreEvent'])" />
<q-tab :label="$t('view.tabs.simple')" name="simple" />
<q-tab v-for="prop in writeProperties.filter(prop=>model[prop]!=null && itemDefinition.properties != undefined && itemDefinition.properties[prop] != undefined && (itemDefinition.properties[prop]['type']==undefined || itemDefinition.properties[prop]['type']=='object'))" v-bind:key="prop" :name="prop" :label="prop" />
Expand Down Expand Up @@ -83,6 +98,9 @@ const OpenApiNamedIcon = defineAsyncComponent(() => import( '@/components/openap
</q-field>
</div>
</div>
<div v-if="['PipelineRun'].includes(props.short) && props.model.status != undefined && props.model.status.pipelineSpec != undefined">
<PipelineRun :model="props.model" />
</div>
<q-field label="Problems" stack-label borderless v-if="Array.isArray(model.getcoreProblem) && model.getcoreProblem.length>0">
<template v-slot:prepend><q-icon name="error" /></template>
<template v-slot:control><div class="self-center full-width no-outline" tabindex="0">
Expand Down Expand Up @@ -145,6 +163,82 @@ const OpenApiNamedIcon = defineAsyncComponent(() => import( '@/components/openap
:showdefault="false"
/>
</q-tab-panel>
<q-tab-panel name="logs" :class="`bg-${ colorItem }-${$q.dark.isActive?'10':'1'}`" v-if="['TaskRun','Job','ReplicaSet','DaemonSet','StatefulSet'].includes(props.short) && props.model.childk8sPod != undefined">
<q-splitter v-model="logViewSplitterModel" style="height: 250px" >
<template v-slot:before>
<q-tabs v-model="logViewTab" vertical class="text-teal" switch-indicator active-color="primary">
<q-tab v-for="prop in props.model.childk8sPod.filter(x=>x!=undefined).map(pod=>pod.childcoreContainer.filter(c=>!c.init||['Job','ReplicaSet','DaemonSet','StatefulSet'].includes(props.short))).flat()" v-bind:key="prop.name" :name="prop.name" :label="prop.name" />
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels v-model="logViewTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel v-for="prop in props.model.childk8sPod.filter(x=>x!=undefined).map(pod=>pod.childcoreContainer.filter(c=>!c.init||['Job','ReplicaSet','DaemonSet','StatefulSet'].includes(props.short))).flat()" v-bind:key="prop.name" :name="prop.name" class="bg-black text-white">
<pre v-if="prop.getcoreLog != undefined && Array.isArray(prop.getcoreLog.lines)">
{{ prop.getcoreLog.lines.join('\n') }}
</pre>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-tab-panel>
<q-tab-panel name="logs" :class="`bg-${ colorItem }-${$q.dark.isActive?'10':'1'}`" v-if="['PipelineRun'].includes(props.short)">
<q-splitter v-model="logViewSplitterModel" >
<template v-slot:before>
<q-tabs inline-label v-model="logViewTab" vertical class="text-teal" switch-indicator active-color="primary">
<q-tab v-for="prop in props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0).sort((a,b)=>a.metadata.creationTimestamp<b.metadata.creationTimestamp?-1:1)" v-bind:key="prop.metadata.name" :name="prop.metadata.name" :label="prop.metadata.name.replace(props.model.metadata.name+'-','')" :icon="prop.status.conditions[0].status=='True'?'check':'error'" />
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels v-model="logViewTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel v-for="tr in props.model.childtektonTaskRun.filter(tr=>Array.isArray(tr.childk8sPod)&&tr.childk8sPod.length>0).sort((a,b)=>a.metadata.creationTimestamp<b.metadata.creationTimestamp?-1:1)" v-bind:key="tr.metadata.name" :name="tr.metadata.name" class="bg-black text-white">
<div v-for="cont in tr.childk8sPod.map(po=>po.childcoreContainer.filter(c=>!c.init)).flat()" v-bind:key="cont.name">
<h5>{{ cont.name }}</h5>
<pre v-if="cont.getcoreLog!=undefined && Array.isArray(cont.getcoreLog.lines)">
{{ cont.getcoreLog.lines.join('\n') }}
</pre>
</div>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-tab-panel>
<q-tab-panel name="logs" :class="`bg-${ colorItem }-${$q.dark.isActive?'10':'1'}`" v-if="['Deployment'].includes(props.short) && Array.isArray(props.model.childk8sReplicaSet) && props.model.childk8sReplicaSet.filter(rs=>Array.isArray(rs.childk8sPod)).length>0">
<q-splitter v-model="logViewSplitterModel" >
<template v-slot:before>
<q-tabs inline-label v-model="logViewTab" vertical class="text-teal" switch-indicator active-color="primary">
<q-tab v-for="cont in props.model.childk8sReplicaSet.filter(rs=>Array.isArray(rs.childk8sPod)&&rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)&&po.childcoreContainer.length>0).length>0).map(rs=>rs.childk8sPod.map(po=>po.childcoreContainer.map(cont=>{return {rs:rs.metadata,po:po.metadata, ...cont}}))).flat().flat().sort((a,b)=>a.po.creationTimestamp<b.po.creationTimestamp?-1:1)" v-bind:key="`${cont.po.name}-${cont.name}`" :name="`${cont.po.name}-${cont.name}`" :label="`${cont.name}#${cont.po.name.replace(props.model.metadata.name+'-','')}`" />
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels v-model="logViewTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel v-for="cont in props.model.childk8sReplicaSet.filter(rs=>Array.isArray(rs.childk8sPod)&&rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)&&po.childcoreContainer.length>0).length>0).map(rs=>rs.childk8sPod.map(po=>po.childcoreContainer.map(cont=>{return {rs:rs.metadata,po:po.metadata, ...cont}}))).flat().flat()" v-bind:key="`${cont.po.name}-${cont.name}`" :name="`${cont.po.name}-${cont.name}`" class="bg-black text-white">
<pre v-if="cont.getcoreLog != undefined && Array.isArray(cont.getcoreLog.lines)">
{{ cont.getcoreLog.lines.join('\n') }}
</pre>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-tab-panel>
<q-tab-panel name="logs" :class="`bg-${ colorItem }-${$q.dark.isActive?'10':'1'}`" v-if="['Install'].includes(props.short) && Array.isArray(props.model.usek8sJob) && props.model.usek8sJob.filter(rs=>Array.isArray(rs.childk8sPod) && rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)).length>0).length>0">
<q-splitter v-model="logViewSplitterModel" >
<template v-slot:before>
<q-tabs :no-caps="true" inline-label v-model="logViewTab" vertical class="text-teal" switch-indicator active-color="primary">
<q-tab v-for="cont in props.model.usek8sJob.filter(rs=>Array.isArray(rs.childk8sPod) && rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)).length>0).map(job=>job.childk8sPod.map(po=>po.childcoreContainer.map(cont=>{return {job:job.metadata,po:po.metadata, ...cont}})))
.flat().flat().sort((a,b)=>a.po.creationTimestamp<b.po.creationTimestamp?-1:1)" v-bind:key="`${cont.po.name}-${cont.name}`" :name="`${cont.po.name}-${cont.name}`" :label="`${cont.name}#${cont.po.name.replace(props.model.metadata.name+'-','')}`" />
</q-tabs>
</template>
<template v-slot:after>
<q-tab-panels v-model="logViewTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel v-for="cont in props.model.usek8sJob.filter(rs=>Array.isArray(rs.childk8sPod) && rs.childk8sPod.filter(po=>Array.isArray(po.childcoreContainer)).length>0).map(job=>job.childk8sPod.map(po=>po.childcoreContainer.map(cont=>{return {job:job.metadata,po:po.metadata, ...cont}}))).flat().flat()" v-bind:key="`${cont.po.name}-${cont.name}`" :name="`${cont.po.name}-${cont.name}`" class="bg-black text-white">
<pre v-if="cont.getcoreLog != undefined && Array.isArray(cont.getcoreLog.lines)">
{{ cont.getcoreLog.lines.join('\n') }}
</pre>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
</q-tab-panel>
<q-tab-panel name="events" :class="`bg-${ colorItem }-${$q.dark.isActive?'10':'1'}`" v-if="Array.isArray(model['getcoreEvent'])">
<EventList :model="model['getcoreEvent']"
/>
Expand Down
37 changes: 37 additions & 0 deletions front/components/tekton/PipelineRun.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import {chartSizeOptions,chartMarginOptions} from "../../libs/core"
import * as d3 from "d3";
const {getSizeOptions,getMarginOptions,onlyUnique} = await import("../charts/commonTools")
const props = defineProps<{
options?: chartSizeOptions&chartMarginOptions
model: object
}>();
const marginTop = 10;
const marginRight = 10;
const marginBottom = 30;
const marginLeft = 40;
const defaultHeight = 0;
const defaultWidth = 6*defaultHeight/2;
const marginOptions = getMarginOptions(10,defaultHeight/2-20,props.options);
const options = ref({...getSizeOptions(defaultWidth, defaultHeight, props.options),...marginOptions})
const svgRoot = ref(null);
const taskIsSkipped = name => Array.isArray(props.model.status.skippedTasks) && props.model.status.skippedTasks.filter(s=>s.name==name).length>0
const getTask = name => Array.isArray(props.model.childtektonTaskRun) && Array.isArray(props.model.status.childReferences) && props.model.status.childReferences.filter(c=>c.pipelineTaskName==name).length>0 && props.model.childtektonTaskRun.filter(tr=>tr.metadata.name==props.model.status.childReferences.filter(c=>c.pipelineTaskName==name)[0].name).length>0
?props.model.childtektonTaskRun.filter(tr=>tr.metadata.name==props.model.status.childReferences.filter(c=>c.pipelineTaskName==name)[0].name)[0]
:null;
onMounted(() => {
const svg = d3.select(svgRoot.value);
})
console.log(props.model)
</script>
<template>
<svg ref="svgRoot" :viewBox="[0,0,options.width,options.height]" :width="options.width" :height="options.height" stroke-linejoin="round" stroke-linecap="round" style="width: 100%; height: auto; font: 10px sans-serif;">
<g class="rects">
<rect v-for="task in props.model.status.pipelineSpec.tasks" :key="task.name" />
</g>
<g class="labels" text-anchor="middle" />
<g :transform="`translate(0,${options.height - marginBottom})`" ><g class="axisBottom" /></g>
<g :transform="`translate(${marginLeft}, 0)`"><g class="axisLeft" /></g>
</svg>
</template>
4 changes: 3 additions & 1 deletion front/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"container": {
"init": "Init?",
"memory": "memory",
"cpu": "cpu"
"cpu": "cpu",
"log": "logs"
},
"documentation": {
"typeRequiered": "type: { type }, required.",
Expand Down Expand Up @@ -273,6 +274,7 @@
"tekton": {
"StartTime": "StartTime",
"CompletionTime": "CompletionTime",
"Duration": "Duration",
"Address": "Address"
},
"vynil": {
Expand Down
4 changes: 3 additions & 1 deletion front/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
"container": {
"init": "Init?",
"memory": "memory",
"cpu": "cpu"
"cpu": "cpu",
"log": "logs"
},
"documentation": {
"typeRequiered": "type: { type }, obligatoire.",
Expand Down Expand Up @@ -272,6 +273,7 @@
},
"tekton": {
"StartTime": "Début",
"Duration": "Durée",
"CompletionTime": "Fin",
"Address": "Addresse"
},
Expand Down
20 changes: 20 additions & 0 deletions front/libs/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,23 @@ export function timeAgo(date:string) {
const seconds = Math.floor((delta % (1000 * 60)) / 1000);
return `${days>0?`${i18n.global.t("meta.days",days)} `:''}${hours>0?`${i18n.global.t("meta.hours",hours)} `:''}${minutes>0&&days<10?`${i18n.global.t("meta.minutes",minutes)} `:''}${seconds>0&&days<1&&hours<10?i18n.global.t("meta.seconds",seconds):''}`
}
export function duration(date:string, from:string) {
const delta = new Date(from).getTime() - new Date(date).getTime();
const days = Math.floor(delta / (1000 * 60 * 60 * 24));
const hours = Math.floor((delta % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((delta % (1000 * 60)) / 1000);
return `${days>0?`${i18n.global.t("meta.days",days)} `:''}${hours>0?`${i18n.global.t("meta.hours",hours)} `:''}${minutes>0&&days<10?`${i18n.global.t("meta.minutes",minutes)} `:''}${seconds>0&&days<1&&hours<10?i18n.global.t("meta.seconds",seconds):''}`
}
import * as d3 from "d3";
export const dateTimeFormat = d3.timeFormatLocale({
"dateTime": "%A, le %e %B %Y, %X",
"date": "%Y-%m-%d",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
"shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
"months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
"shortMonths": ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."]
});
export const dateFormat = d => dateTimeFormat.format("%x %X")(new Date(d))
6 changes: 3 additions & 3 deletions front/libs/fluxcd/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export const descriptionHelmRelease = '';
export const shortHelmRelease = 'HelmRelease';

export const extraKustomizationColumns:Array<QTableColumn> = [
{name: 'Children', label: `${i18n.global.t('fluxcd.Children')}`, field: row => row.status?.inventory.entries.length, sortable: true, align: tableColumnAlign.left},
{name: 'lastAppliedRevision', label: `${i18n.global.t('fluxcd.lastAppliedRevision')}`, field: row => row.status?.lastAppliedRevision, sortable: true, align: tableColumnAlign.left},
{name: 'LastChange', label: `${i18n.global.t('fluxcd.LastChange')}`, field: row => timeAgo(row.status?.conditions[0].lastTransitionTime), sortable: true, align: tableColumnAlign.left},
{name: 'Children', label: `${i18n.global.t('fluxcd.Children')}`, field: row => row.status!=undefined&&row.status.inventory!=undefined&&Array.isArray(row.status.inventory.entries)?row.status.inventory.entries.length:0, sortable: true, align: tableColumnAlign.left},
{name: 'lastAppliedRevision', label: `${i18n.global.t('fluxcd.lastAppliedRevision')}`, field: row => row.status!=undefined?row.status.lastAppliedRevision:"", sortable: true, align: tableColumnAlign.left},
{name: 'LastChange', label: `${i18n.global.t('fluxcd.LastChange')}`, field: row => row.status!=undefined&&Array.isArray(row.status.conditions)?timeAgo(row.status.conditions[0].lastTransitionTime):"", sortable: true, align: tableColumnAlign.left},
];
export const extraReceiverColumns:Array<QTableColumn> = [
{name: 'Age', label: `${i18n.global.t('meta.age')}`, field: row => timeAgo(row.metadata.creationTimestamp), sortable: true, align: tableColumnAlign.left},
Expand Down
9 changes: 9 additions & 0 deletions front/libs/projectcalico/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ export const shortBGPFilter = 'BGPFilter';
export const extraBGPConfigurationColumns:Array<QTableColumn> = [
// {name: 'Name', label: 'Name', field: row => row.metadata.name, sortable: true, align: tableColumnAlign.left},
];
export const extraBGPFilterColumns:Array<QTableColumn> = [
// {name: 'Name', label: 'Name', field: row => row.metadata.name, sortable: true, align: tableColumnAlign.left},
];
export const extraBGPPeerColumns:Array<QTableColumn> = [
// {name: 'Name', label: 'Name', field: row => row.metadata.name, sortable: true, align: tableColumnAlign.left},
];
Expand Down Expand Up @@ -134,6 +137,12 @@ export const BGPConfigurationReadExcludes = [
];
export const BGPConfigurationSimpleExcludes = [
];
export const BGPFilterListExcludes = [
];
export const BGPFilterReadExcludes = [
];
export const BGPFilterSimpleExcludes = [
];
export const BGPPeerListExcludes = [
];
export const BGPPeerReadExcludes = [
Expand Down
Loading

0 comments on commit 18455a4

Please sign in to comment.