diff --git a/.gitignore b/.gitignore index 75e801ba..15d976a7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ !/front/components/vynil/CategoryMeta.vue /front/libs/**/*.ts !/front/libs/*/custom.ts +!/front/libs/i18n/* !/front/libs/core/* /front/pages/**/*.vue !/front/pages/install/vynil/DistribView.vue diff --git a/back/resolvers/vynil/Package.ts b/back/resolvers/vynil/Package.ts index be586da0..88e655db 100644 --- a/back/resolvers/vynil/Package.ts +++ b/back/resolvers/vynil/Package.ts @@ -4,6 +4,17 @@ import {kc, cache, applyFilter, applyFieldSelection, getByPath, getMeta } from ' import { gramoConfig } from '../../config.js' import { lists as distribQueries } from './Distrib.js'; +function derefOptions(ret: object, dists) { + Object.keys(ret).forEach((name) => { + if (ret[name]!=null && ret[name]['type']=='object' && !['',null,undefined].includes(ret[name]['x-vynil-category']) && !['',null,undefined].includes(ret[name]['x-vynil-package']) && dists.filter(d=>d.status.components[ret[name]['x-vynil-category']]!=undefined&&d.status.components[ret[name]['x-vynil-category']][ret[name]['x-vynil-package']]!=undefined).length>0) { + Object.assign(ret[name]['properties'], dists.filter(d=>d.status.components[ret[name]['x-vynil-category']]!=undefined&&d.status.components[ret[name]['x-vynil-category']][ret[name]['x-vynil-package']]!=undefined)[0].status.components[ret[name]['x-vynil-category']][ret[name]['x-vynil-package']]['options']) + } + if (ret[name]!=null && ret[name]['type']=='object' && ret[name]['properties']!=undefined) Object.keys(ret[name]['properties']).forEach(key=>derefOptions(ret[name]['properties'][key], dists)) + if (ret[name]!=null && ret[name]['type']=='array' && ret[name]['items']!=undefined) Object.keys(ret[name]['items']).forEach(key=>derefOptions(ret[name]['items'][key], dists)) + }) + return ret +} + const k8sApi = kc.makeApiClient(k8s.CustomObjectsApi); export const mutations = { @@ -23,13 +34,18 @@ export const lists = { item.name = name; item.distrib = distName as string; item.category = category; + item.options = derefOptions(Object.assign({}, pkg['options']), dists); (lst as object[]).push(item) }) }) }); cache.set('vynilPackage', lst, 2); } catch (err) { - console.error((err as object)['body']); + if (typeof err === 'object' && (err as object)['body'] !=undefined && (err as object)['statusCode'] !=undefined) { + if ((err as object)['statusCode'] != 404 && (err as object)['body']['reason']!='Forbidden') { + console.error('error', (err as object)['body']); + } + } else {console.error('error', err)} return [] } } diff --git a/front/components/core/MonacoEditor.vue b/front/components/core/MonacoEditor.vue index f2790fc8..89b81c29 100644 --- a/front/components/core/MonacoEditor.vue +++ b/front/components/core/MonacoEditor.vue @@ -20,6 +20,7 @@ const props = withDefaults(defineProps<{ wordWrap: "wordWrapColumn", automaticLayout: true, }); +console.log('xxx', props.properties) const height = window.innerHeight - 300; const code=ref(null); onMounted(() => { diff --git a/front/components/core/OpenApiEditUndefObject.vue b/front/components/core/OpenApiEditUndefObject.vue index 6501d4a4..84c540e4 100644 --- a/front/components/core/OpenApiEditUndefObject.vue +++ b/front/components/core/OpenApiEditUndefObject.vue @@ -42,8 +42,8 @@ function onAdd() { - - + + diff --git a/front/components/core/OpenApiNamedIcon.vue b/front/components/core/OpenApiNamedIcon.vue index 31e7645e..9e9711da 100644 --- a/front/components/core/OpenApiNamedIcon.vue +++ b/front/components/core/OpenApiNamedIcon.vue @@ -1,25 +1,30 @@ diff --git a/front/components/core/TableHeader.vue b/front/components/core/TableHeader.vue index b841dc7c..4d5bc531 100644 --- a/front/components/core/TableHeader.vue +++ b/front/components/core/TableHeader.vue @@ -26,13 +26,13 @@ withDefaults(defineProps<{ - Show filter + {{ $t('list.showFilter') }} - Refresh data + {{ $t('list.refresh') }} - - Create a new {{ itemtype }} + + {{ $t('new.cluster', {name: itemtype}) }} diff --git a/front/components/navigation/RelatedLinks.vue b/front/components/navigation/RelatedLinks.vue index ef1222a1..dfd2ac72 100644 --- a/front/components/navigation/RelatedLinks.vue +++ b/front/components/navigation/RelatedLinks.vue @@ -6,7 +6,7 @@ const route = useRoute(); const namespace = ref(useNavigationStore().namespace) \ No newline at end of file diff --git a/utils/generator/front/grp.custom.def.ts.hbs b/utils/generator/front/grp.custom.def.ts.hbs index fd73f898..5ea1260b 100644 --- a/utils/generator/front/grp.custom.def.ts.hbs +++ b/utils/generator/front/grp.custom.def.ts.hbs @@ -1,5 +1,6 @@ import { QTableColumn } from 'quasar' import { tableColumnAlign } from '../core' +import { i18n } from "../i18n" import { {{#each categories}}{{this}}Color, {{this}}Icon,{{/each}} } from '../../routes/custom'; export const {{ name }}Icon = 'apps'; export const {{ name }}Title = '{{ name }}'; @@ -14,7 +15,7 @@ export const extra{{short}}Columns:Array = [ {{#if (defined additionalColumns)}} {{#each additionalColumns}} {{#unless (contain jsonPath '[')}} - {name: '{{name}}', label: '{{name}}', field: row => row{{jsonPath}}, sortable: true, align: tableColumnAlign.left}, + {name: '{{name}}', label: `${i18n.global.t('{{../group}}.{{name}}')}`, field: row => row{{jsonPath}}, sortable: true, align: tableColumnAlign.left}, {{/unless}} {{/each}} {{else}} diff --git a/utils/generator/front/grp.pages.dashboard.vue.hbs b/utils/generator/front/grp.pages.dashboard.vue.hbs index bee35255..d8d1dc9c 100644 --- a/utils/generator/front/grp.pages.dashboard.vue.hbs +++ b/utils/generator/front/grp.pages.dashboard.vue.hbs @@ -101,7 +101,7 @@ onResult((res) => {
- + import('../../pages/{{category}}/{{ name }}/{{category}}Dashboard.vue'), meta: { - breadcrumb: 'Dashboard', icon: {{ name }}Icon, ns: false, - title: () => '{{ category }}/{{ name }} Dashboard', + breadcrumb: i18n.global.t('overview.dashboardBreadcrumb'), icon: {{ name }}Icon, ns: false, + title: () => i18n.global.t('overview.dashboardTitle',{name: '{{ category }}/{{ name }}'}), related: [ - {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (ns) => `{{ name }} Dashboard for ${ns} namespace`}, - {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (ns) => `{{ name }} Advices for ${ns} namespace`}, - {target: '{{ category }}{{ name }}Advices', ns: false, display: () => `{{ name }} Advices for all namespaces`}, + {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (namespace) => i18n.global.t('overview.dashboardNSTitle',{name: '{{ name }}', namespace})}, + {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (namespace) => i18n.global.t('overview.adviceNSTitle',{name: '{{ name }}', namespace})}, + {target: '{{ category }}{{ name }}Advices', ns: false, display: () => i18n.global.t('overview.adviceTitle',{name: '{{ name }}'})}, ] }, }, @@ -46,12 +47,12 @@ export const route = { name: '{{ category }}{{ name }}NSDashboard', component: () => import('../../pages/{{category}}/{{ name }}/{{category}}Dashboard.vue'), meta: { - breadcrumb: 'Dashboard', icon: {{ name }}Icon, ns: true, - title: (namespace) => `{{ category }}/{{ name }} Dashboard for namespace ${namespace}`, + breadcrumb: i18n.global.t('overview.dashboardBreadcrumb'), icon: {{ name }}Icon, ns: true, + title: (namespace) => i18n.global.t('overview.dashboardNSTitle',{name: '{{ category }}/{{ name }}', namespace}), related: [ - {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => `{{ name }} Dashboard for all namespaces`}, - {target: '{{ category }}{{ name }}Advices', ns: false, display: () => `{{ name }} Advices for all namespaces`}, - {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (ns) => `{{ name }} Advices for ${ns} namespace`}, + {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => i18n.global.t('overview.dashboardTitle',{name: '{{ name }}'})}, + {target: '{{ category }}{{ name }}Advices', ns: false, display: () => i18n.global.t('overview.adviceTitle',{name: '{{ name }}'})}, + {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (namespace) => i18n.global.t('overview.adviceNSTitle',{name: '{{ name }}', namespace})}, ] }, }, @@ -60,12 +61,12 @@ export const route = { name: '{{ category }}{{ name }}Advices', component: () => import('../../pages/{{category}}/{{ name }}/{{category}}Advices.vue'), meta: { - breadcrumb: 'Advices', icon: {{ name }}Icon, ns: false, - title: () => '{{ category }}/{{ name }} Advices', + breadcrumb: i18n.global.t('overview.adviceBreadcrumb'), icon: {{ name }}Icon, ns: false, + title: () => i18n.global.t('overview.adviceTitle',{name: '{{ category }}/{{ name }}'}), related: [ - {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => `{{ name }} Dashboard for all namespaces`}, - {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (ns) => `{{ name }} Dashboard for ${ns} namespace`}, - {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (ns) => `{{ name }} Advices for ${ns} namespace`}, + {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => i18n.global.t('overview.dashboardTitle',{name: '{{ name }}'})}, + {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (namespace) => i18n.global.t('overview.dashboardNSTitle',{name: '{{ name }}', namespace})}, + {target: '{{ category }}{{ name }}NSAdvices', ns: true, display: (namespace) => i18n.global.t('overview.adviceNSTitle',{name: '{{ name }}', namespace})}, ] }, }, @@ -74,12 +75,12 @@ export const route = { name: '{{ category }}{{ name }}NSAdvices', component: () => import('../../pages/{{category}}/{{ name }}/{{category}}Advices.vue'), meta: { - breadcrumb: 'Advices', icon: {{ name }}Icon, ns: true, - title: (namespace) => `{{ category }}/{{ name }} Advices for namespace ${namespace}`, + breadcrumb: i18n.global.t('overview.adviceBreadcrumb'), icon: {{ name }}Icon, ns: true, + title: (namespace) => i18n.global.t('overview.adviceNSTitle',{name: '{{ category }}/{{ name }}', namespace}), related: [ - {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (ns) => `{{ name }} Dashboard for ${ns} namespace`}, - {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => `{{ name }} Dashboard for all namespaces`}, - {target: '{{ category }}{{ name }}Advices', ns: false, display: () => `{{ name }} Advices for all namespaces`}, + {target: '{{ category }}{{ name }}NSDashboard', ns: true, display: (namespace) => i18n.global.t('overview.dashboardNSTitle',{name: '{{ name }}', namespace})}, + {target: '{{ category }}{{ name }}Dashboard', ns: false, display: () => i18n.global.t('overview.dashboardTitle',{name: '{{ name }}'})}, + {target: '{{ category }}{{ name }}Advices', ns: false, display: () => i18n.global.t('overview.adviceTitle',{name: '{{ name }}'})}, ] }, }], @@ -95,12 +96,12 @@ export const route = { name: '{{ group }}{{ short }}AllTable', component: () => import('../../pages/{{category}}/{{ group }}/{{ short }}List.vue'), meta: { - breadcrumb: 'All', icon: 'list', ns: false, - title: () => 'List all {{ short }}', + breadcrumb: i18n.global.t('list.all'), icon: 'list', ns: false, + title: () => i18n.global.t('overview.titleList',{short: '{{ short }}'}), related: [ - {target: '{{ group }}{{ short }}Table', ns: true, display: (ns) => `List {{ short }} in namespace ${ns}`}, - {target: '{{ ../category }}{{ ../name }}Dashboard', ns: false, display: () => `{{ group }} Dashboard for all namespaces`}, - {target: '{{ ../category }}{{ ../name }}Advices', ns: false, display: () => `{{ group }} Advices for all namespaces`}, + {target: '{{ group }}{{ short }}Table', ns: true, display: (namespace) => i18n.global.t('overview.titleList',{short: '{{ short }}', namespace})}, + {target: '{{ ../category }}{{ ../name }}Dashboard', ns: false, display: () => i18n.global.t('overview.dashboardTitle',{name: '{{ group }}'})}, + {target: '{{ ../category }}{{ ../name }}Advices', ns: false, display: () => i18n.global.t('overview.adviceTitle',{name: '{{ group }}'})}, ] }, }, @@ -110,16 +111,16 @@ export const route = { name: '{{ group }}{{ short }}Table', component: () => import('../../pages/{{category}}/{{ group }}/{{ short }}List.vue'), meta: { - breadcrumb: 'List', icon: 'list', ns: {{toJson namespaced}}, - title: ({{#if namespaced}}namespace{{/if}}) => `List {{ short }} {{#if namespaced}}in namespace ${namespace}{{/if}}`, + breadcrumb: i18n.global.t('list.breadcrumb'), icon: 'list', ns: {{toJson namespaced}}, + title: ({{#if namespaced}}namespace{{/if}}) => i18n.global.t('list.{{#if namespaced}}namespaced{{else}}cluster{{/if}}',{short: '{{ short }}'{{#if namespaced}}, namespace{{/if}} }), related: [ {{#if namespaced}} - {target: '{{ group }}{{ short }}AllTable', ns: false, display: () => `List all {{ short }}`}, - {target: '{{ ../category }}{{ ../name }}NSDashboard', ns: true, display: (ns) => `{{ group }} Dashboard for ${ns} namespace`}, - {target: '{{ ../category }}{{ ../name }}NSAdvices', ns: true, display: (ns) => `{{ group }} Advices for ${ns} namespace`}, + {target: '{{ group }}{{ short }}AllTable', ns: false, display: () => i18n.global.t('overview.titleAllList',{short: '{{ short }}'})}, + {target: '{{ ../category }}{{ ../name }}NSDashboard', ns: true, display: (namespace) => i18n.global.t('overview.dashboardNSTitle',{name: '{{ group }}', namespace})}, + {target: '{{ ../category }}{{ ../name }}NSAdvices', ns: true, display: (ns) => i18n.global.t('overview.adviceNSTitle',{name: '{{ group }}', namespace})}, {{else}} - {target: '{{ ../category }}{{ ../name }}Dashboard', ns: false, display: () => `{{ group }} Dashboard for all namespaces`}, - {target: '{{ ../category }}{{ ../name }}Advices', ns: false, display: () => `{{ group }} Advices for all namespaces`}, + {target: '{{ ../category }}{{ ../name }}Dashboard', ns: false, display: () => i18n.global.t('overview.dashboardTitle',{name: '{{ group }}'})}, + {target: '{{ ../category }}{{ ../name }}Advices', ns: false, display: () => i18n.global.t('overview.adviceTitle',{name: '{{ group }}'})}, {{/if}} ] }, @@ -129,8 +130,8 @@ export const route = { name: '{{ group }}{{ short }}View', component: () => import('../../pages/{{category}}/{{ group }}/{{ short }}View.vue'), meta: { - breadcrumb: 'View', icon: icon{{ short }}, ns: {{toJson namespaced}}, useName: true, - title: ({{#if namespaced}}namespace, {{/if}}name) => `{{ short }} {{#if namespaced}}(${namespace}){{/if}}${name}` + breadcrumb: i18n.global.t('view.breadcrumb'), icon: icon{{ short }}, ns: {{toJson namespaced}}, useName: true, + title: ({{#if namespaced}}namespace, {{/if}}name) => i18n.global.t('view.{{#if namespaced}}namespaced{{else}}cluster{{/if}}',{short: '{{ short }}',name{{#if namespaced}}, namespace{{/if}} }) }, children: [ {{#each resolvers}} @@ -143,8 +144,8 @@ export const route = { name: '{{ group }}{{ short }}Edit', component: () => import('../../pages/{{category}}/{{ group }}/{{ short }}Edit.vue'), meta: { - breadcrumb: 'Edit', icon: 'visibility', ns: {{toJson namespaced}}, useName: true, - title: ({{#if namespaced}}namespace, {{/if}}name) => `Edit {{ short }} {{#if namespaced}}(${namespace}){{/if}}${name}` + breadcrumb: i18n.global.t('edit.breadcrumb'), icon: 'visibility', ns: {{toJson namespaced}}, useName: true, + title: ({{#if namespaced}}namespace, {{/if}}name) => i18n.global.t('edit.{{#if namespaced}}namespaced{{else}}cluster{{/if}}',{short: '{{ short }}',name{{#if namespaced}}, namespace{{/if}} }) }, }, { @@ -152,8 +153,8 @@ export const route = { name: '{{ group }}{{ short }}Create', component: () => import('../../pages/{{category}}/{{ group }}/{{ short }}New.vue'), meta: { - breadcrumb: 'Create', icon: 'add', ns: {{toJson namespaced}}, - title: ({{#if namespaced}}namespace{{/if}}) => `Create a new {{ short }} {{#if namespaced}}in namespace: ${namespace}{{/if}}` + breadcrumb: i18n.global.t('new.breadcrumb'), icon: 'add', ns: {{toJson namespaced}}, + title: ({{#if namespaced}}namespace{{/if}}) => i18n.global.t('new.{{#if namespaced}}namespaced{{else}}cluster{{/if}}',{short: '{{ short }}'{{#if namespaced}}, namespace{{/if}} }) }, } ] diff --git a/utils/generator/front/obj.components.edit.vue.hbs b/utils/generator/front/obj.components.edit.vue.hbs index 9a4e731b..3d4dd140 100644 --- a/utils/generator/front/obj.components.edit.vue.hbs +++ b/utils/generator/front/obj.components.edit.vue.hbs @@ -3,8 +3,9 @@ import { onMounted } from "vue"; import { defineAsyncComponent } from 'vue' const OpenApiEdit = defineAsyncComponent(() => import( '@/components/core/OpenApiEdit.vue')); const MonacoEditor = defineAsyncComponent(() => import( '@/components/core/MonacoEditor.vue')); +const OpenApiNamedIcon = defineAsyncComponent(() => import( '@/components/core/OpenApiNamedIcon.vue')); import { use{{ short }}, sanitizeData, getProperties, {{ short }}Definition } from '../../libs/{{ group }}/{{ short }}.js' -import { color{{ short }}, icon{{ short }} } from '../../libs/{{ group }}/custom.js' +import { color{{ short }}, icon{{ short }}, extra{{ short }}Columns } from '../../libs/{{ group }}/custom.js' import { useQuasar } from 'quasar' const $q = useQuasar() {{#if namespaced}} @@ -27,11 +28,11 @@ const setYaml = (v) => editor.value.setYaml(v) - - + + - - Submit + + \{{ $t('edit.submitTooltip') }} @@ -68,7 +69,7 @@ const setYaml = (v) => editor.value.setYaml(v) - + diff --git a/utils/generator/front/obj.components.list.vue.hbs b/utils/generator/front/obj.components.list.vue.hbs index 1c3eaf04..162c8c74 100644 --- a/utils/generator/front/obj.components.list.vue.hbs +++ b/utils/generator/front/obj.components.list.vue.hbs @@ -107,17 +107,17 @@ withDefaults(defineProps<{model: object[], useAction?:boolean, useRefresh?: bool - Edit {{ short }} \{{ props.row.metadata.name }} + \{{ $t('core.editTooltip', {short: '{{ short }}', name: props.row.metadata.name}) }} - Delete {{ short }} \{{ props.row.metadata.name }} + \{{ $t('core.deleteTooltip', {short: '{{ short }}', name: props.row.metadata.name}) }} - View parent \{{ props.row.parentReference.short }} \{{ props.row.parentReference.name }} + \{{ $t('core.viewParentTooltip', {short: props.row.parentReference.short, name: props.row.parentReference.name}) }} diff --git a/utils/generator/front/obj.components.meta.vue.hbs b/utils/generator/front/obj.components.meta.vue.hbs index ac2f03a1..2164b4b2 100644 --- a/utils/generator/front/obj.components.meta.vue.hbs +++ b/utils/generator/front/obj.components.meta.vue.hbs @@ -1,8 +1,10 @@