From 2e52a06e92d14a9488f159bae4dbd48ce5686aa6 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Mon, 6 Jun 2022 10:05:32 +0100 Subject: [PATCH 01/26] Configuration and routing fixes - show correct name with link for services - show warning on config view page if user can't edit due to it relating to a service - ensure all epinio resources use correct, common routing --- pkg/epinio/config/epinio.ts | 2 +- pkg/epinio/edit/configurations.vue | 3 +++ pkg/epinio/models/applications.js | 12 ------------ pkg/epinio/models/configurations.js | 2 +- pkg/epinio/models/epinio-resource.js | 8 ++++++++ 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/pkg/epinio/config/epinio.ts b/pkg/epinio/config/epinio.ts index 95f13fdeff..df89fdf549 100644 --- a/pkg/epinio/config/epinio.ts +++ b/pkg/epinio/config/epinio.ts @@ -298,7 +298,7 @@ export function init($plugin: any, store: any) { headers(EPINIO_TYPES.SERVICE_INSTANCE, [ STATE, - SIMPLE_NAME, + NAME, { name: 'namespace', labelKey: 'epinio.tableHeaders.namespace', diff --git a/pkg/epinio/edit/configurations.vue b/pkg/epinio/edit/configurations.vue index 9930736e59..78717692d7 100644 --- a/pkg/epinio/edit/configurations.vue +++ b/pkg/epinio/edit/configurations.vue @@ -161,6 +161,9 @@ export default Vue.extend({ @finish="save" @cancel="done" > + + {{ t('epinio.configurations.tableHeaders.service.tooltip') }} + Date: Mon, 6 Jun 2022 17:32:42 +0100 Subject: [PATCH 02/26] Usability updates - add an epinio intro screen - show it if the user can't see any namespaces - will introduce product and guide user to creating a namespace - replaces content of applications list - move `configuration` side nav item into an `advanced` group - fix the banner shown on the create services page when there are no namespaces - Note - When https://github.com/rancher/dashboard/pull/6084 merges (with a tweak) users will be able to create the NS when creating other resources - I'd like to tie in user descriptions https://github.com/epinio/ui/issues/127 --- pkg/epinio/components/EpinioIntro.vue | 57 +++++++++++++++++++ pkg/epinio/config/epinio.ts | 13 ++++- pkg/epinio/edit/services.vue | 4 +- pkg/epinio/l10n/en-us.yaml | 7 +++ .../pages/c/_cluster/applications/index.vue | 9 ++- 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 pkg/epinio/components/EpinioIntro.vue diff --git a/pkg/epinio/components/EpinioIntro.vue b/pkg/epinio/components/EpinioIntro.vue new file mode 100644 index 0000000000..11bf57a6ae --- /dev/null +++ b/pkg/epinio/components/EpinioIntro.vue @@ -0,0 +1,57 @@ + + + diff --git a/pkg/epinio/config/epinio.ts b/pkg/epinio/config/epinio.ts index df89fdf549..53060280e2 100644 --- a/pkg/epinio/config/epinio.ts +++ b/pkg/epinio/config/epinio.ts @@ -92,9 +92,14 @@ export function init($plugin: any, store: any) { customRoute: createEpinioRoute('c-cluster-resource', { resource: EPINIO_TYPES.CONFIGURATION }), }); + const ADVANCED_GROUP = 'Advanced'; + + weightGroup(ADVANCED_GROUP, 1, true); + + // Service Group const SERVICE_GROUP = 'Services'; - weightGroup(SERVICE_GROUP, 1, true); + weightGroup(SERVICE_GROUP, 2, true); // Service Instance weightType(EPINIO_TYPES.SERVICE_INSTANCE, 151, true); @@ -135,11 +140,15 @@ export function init($plugin: any, store: any) { EPINIO_TYPES.CATALOG_SERVICE, ], SERVICE_GROUP); + basicType([ + EPINIO_TYPES.CONFIGURATION, + ], ADVANCED_GROUP); + basicType([ EPINIO_TYPES.APP, SERVICE_GROUP, EPINIO_TYPES.NAMESPACE, - EPINIO_TYPES.CONFIGURATION + ADVANCED_GROUP ]); headers(EPINIO_TYPES.APP, [ diff --git a/pkg/epinio/edit/services.vue b/pkg/epinio/edit/services.vue index 4a19f3e7db..aa437e49fb 100644 --- a/pkg/epinio/edit/services.vue +++ b/pkg/epinio/edit/services.vue @@ -12,6 +12,7 @@ import { sortBy } from '@shell/utils/sort'; import NameNsDescription from '@shell/components/form/NameNsDescription.vue'; import EpinioBindAppsMixin from './bind-apps-mixin.js'; import { mapGetters } from 'vuex'; +import Banner from '@shell/components/Banner.vue'; interface Data { } @@ -22,7 +23,8 @@ export default Vue.extend({ Loading, CruResource, LabeledSelect, - NameNsDescription + NameNsDescription, + Banner }, mixins: [CreateEditView, EpinioBindAppsMixin], diff --git a/pkg/epinio/l10n/en-us.yaml b/pkg/epinio/l10n/en-us.yaml index 144aff2338..7d710e4bdb 100644 --- a/pkg/epinio/l10n/en-us.yaml +++ b/pkg/epinio/l10n/en-us.yaml @@ -26,6 +26,13 @@ typeLabel: } epinio: label: Epinio + intro: + welcome: Welcome to Epinio + blurb: The Application Development Engine for Kubernetes + learnMoreLink: https://epinio.io/ + learnMore: Learn more + noNamespaces: Create a Namespace, then create your Applications + getStarted: Get started tableHeaders: namespace: Namespace instances: diff --git a/pkg/epinio/pages/c/_cluster/applications/index.vue b/pkg/epinio/pages/c/_cluster/applications/index.vue index e289ba32ed..231f50a5ea 100644 --- a/pkg/epinio/pages/c/_cluster/applications/index.vue +++ b/pkg/epinio/pages/c/_cluster/applications/index.vue @@ -5,13 +5,15 @@ import Masthead from '@shell/components/ResourceList/Masthead'; import LinkDetail from '@shell/components/formatter/LinkDetail'; import { EPINIO_TYPES } from '../../../../types'; import { createEpinioRoute } from '../../../../utils/custom-routing'; +import EpinioIntro from '../../../../components/EpinioIntro.vue'; export default { components: { Loading, LinkDetail, ResourceTable, - Masthead + Masthead, + EpinioIntro }, async fetch() { @@ -47,6 +49,10 @@ export default { rows() { return this.$store.getters['epinio/all'](this.resource); }, + + hasNamespaces() { + return !!this.$store.getters['epinio/all'](EPINIO_TYPES.NAMESPACE)?.length; + } }, }; @@ -54,6 +60,7 @@ export default { @@ -423,6 +460,10 @@ export default Vue.extend({ margin-left: 5px; } } + + .collapse { + margin-left: -5px; + } } .archive { display: flex; diff --git a/pkg/epinio/config/epinio.ts b/pkg/epinio/config/epinio.ts index 18765cc20f..e0bd5c5767 100644 --- a/pkg/epinio/config/epinio.ts +++ b/pkg/epinio/config/epinio.ts @@ -366,6 +366,12 @@ export function init($plugin: any, store: any) { value: 'description', sort: ['description'], }, + { + name: 'helm_chart', + label: 'Helm Chart', + value: 'helm_chart', + sort: ['helm_chart'], + }, AGE ]); } diff --git a/pkg/epinio/l10n/en-us.yaml b/pkg/epinio/l10n/en-us.yaml index 5bc34ffd99..02b1d047e5 100644 --- a/pkg/epinio/l10n/en-us.yaml +++ b/pkg/epinio/l10n/en-us.yaml @@ -34,7 +34,7 @@ typeDescription: applications: Epinio uses Applications to transition your code, through build, to being deployed. services: Epinio can create instances of your services. Instances can be bound to your applications to provide data, for example a database service bound to an application might provide connection credentials. configurations: Configurations are a way to provide data to Applications. The data becomes available once the configuration is bound to them. - appcharts: Application Charts are a helm basis when deploying Applications + appcharts: Application charts define kube resources created by your application epinio: label: Epinio intro: diff --git a/pkg/epinio/models/applications.js b/pkg/epinio/models/applications.js index 136ce08335..0086817049 100644 --- a/pkg/epinio/models/applications.js +++ b/pkg/epinio/models/applications.js @@ -355,6 +355,7 @@ export default class EpinioApplicationModel extends EpinioMetaResource { data: { name: this.meta.name, configuration: { + appchart: this.configuration.appchart, instances: this.configuration.instances, configurations: this.configuration.configurations, environment: this.configuration.environment, diff --git a/pkg/epinio/pages/c/_cluster/applications/createapp/index.vue b/pkg/epinio/pages/c/_cluster/applications/createapp/index.vue index ca864e2ddc..301b6e1e2a 100644 --- a/pkg/epinio/pages/c/_cluster/applications/createapp/index.vue +++ b/pkg/epinio/pages/c/_cluster/applications/createapp/index.vue @@ -38,7 +38,10 @@ export default Vue.extend({ ], async fetch() { - await this.$store.dispatch('epinio/findAll', { type: EPINIO_TYPES.NAMESPACE }); + await Promise.all([ + this.$store.dispatch('epinio/findAll', { type: EPINIO_TYPES.NAMESPACE }), + this.$store.dispatch('epinio/findAll', { type: EPINIO_TYPES.APP_CHARTS }), + ]); this.originalModel = await this.$store.dispatch(`epinio/create`, { type: EPINIO_TYPES.APP }); // Dissassociate the original model & model. This fixes `Create` after refreshing page with SSR on @@ -97,7 +100,14 @@ export default Vue.extend({ updateSource(changes: EpinioAppSource) { this.source = {}; - this.set(this.source, changes); + const { appChart, ...cleanChanges } = changes; + + if (appChart) { + // app chart actuall belongs in config, so stick it in there + this.value.configuration = this.value.configuration || {}; + this.set(this.value.configuration, { appchart: appChart }); + } + this.set(this.source, cleanChanges); }, updateManifestConfigurations(changes: string[]) { diff --git a/pkg/epinio/types.ts b/pkg/epinio/types.ts index 1771292924..661677c656 100644 --- a/pkg/epinio/types.ts +++ b/pkg/epinio/types.ts @@ -2,6 +2,7 @@ import EpinioApplicationModel from './models/applications'; import EpinioCatalogServiceModel from './models/catalogservices'; import EpinioConfigurationModel from './models/configurations'; import EpinioServiceModel from './models/services'; +import EpinioAppChartModel from './models/appcharts'; export const EPINIO_PRODUCT_NAME = 'epinio'; @@ -66,6 +67,7 @@ export interface EpinioApplicationResource { configuration: { instances: number, configurations: string[], + appchart?: string, environment: Map, routes: string[] }, @@ -84,6 +86,15 @@ export interface EpinioApplicationResource { export type EpinioApplication = EpinioApplicationResource & EpinioApplicationModel & EpinioMetaProperty; +export interface EpinioApplicationChartResource { + meta: EpinioMeta, + description: string, + helm_chart: string, // eslint-disable-line camelcase + short_description: string, // eslint-disable-line camelcase +} + +export type EpinioAppChart = EpinioApplicationChartResource & EpinioAppChartModel & EpinioMetaProperty; + export interface EpinioHelmRepoResource { name: string, url: string, From 02c875949b7b405543a9b7aab0439282cc165c37 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 7 Jun 2022 15:53:57 +0100 Subject: [PATCH 06/26] Minor fixes & tweaks post merge --- pkg/epinio/detail/applications.vue | 25 ++++++++++++------------- pkg/epinio/edit/services.vue | 2 +- pkg/epinio/models/applications.js | 4 ---- pkg/epinio/tsconfig.json | 3 +++ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/pkg/epinio/detail/applications.vue b/pkg/epinio/detail/applications.vue index 267d7c5d9f..cfde92e90c 100644 --- a/pkg/epinio/detail/applications.vue +++ b/pkg/epinio/detail/applications.vue @@ -87,16 +87,15 @@ export default Vue.extend({ @@ -165,15 +164,15 @@ export default Vue.extend({ {{ t('tableHeaders.memory') }} - {{ value.instanceMemory.min }} MiB - {{ value.instanceMemory.max }} MiB - {{ value.instanceMemory.avg }} MiB + {{ value.instanceMemory.min }} + {{ value.instanceMemory.max }} + {{ value.instanceMemory.avg }} {{ t('tableHeaders.cpu') }} - {{ value.instanceCpu.min }} m - {{ value.instanceCpu.max }} m - {{ value.instanceCpu.avg }} m + {{ value.instanceCpu.min }} + {{ value.instanceCpu.max }} + {{ value.instanceCpu.avg }} diff --git a/pkg/epinio/edit/services.vue b/pkg/epinio/edit/services.vue index aa437e49fb..649686d087 100644 --- a/pkg/epinio/edit/services.vue +++ b/pkg/epinio/edit/services.vue @@ -12,7 +12,7 @@ import { sortBy } from '@shell/utils/sort'; import NameNsDescription from '@shell/components/form/NameNsDescription.vue'; import EpinioBindAppsMixin from './bind-apps-mixin.js'; import { mapGetters } from 'vuex'; -import Banner from '@shell/components/Banner.vue'; +import Banner from '@components/Banner/Banner.vue'; interface Data { } diff --git a/pkg/epinio/models/applications.js b/pkg/epinio/models/applications.js index 11a3de1f9b..ae0358fc60 100644 --- a/pkg/epinio/models/applications.js +++ b/pkg/epinio/models/applications.js @@ -213,10 +213,6 @@ export default class EpinioApplicationModel extends EpinioMetaResource { return Object.keys(this.configuration?.environment || []).length; } - get configCount() { - return this.configuration?.configurations.length; - } - get routeCount() { return this.configuration?.routes.length; } diff --git a/pkg/epinio/tsconfig.json b/pkg/epinio/tsconfig.json index c7e99f735a..6ecdf84cbb 100644 --- a/pkg/epinio/tsconfig.json +++ b/pkg/epinio/tsconfig.json @@ -42,6 +42,9 @@ "@shell/models/*": [ "../../shell/models/*" ], + "@components/*": [ + "../../pkg/rancher-components/*" + ], "@pkg/*": [ "./*" ] From 7894d0219ba6b0bddea4f19229c0eb8cd82e5d68 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 7 Jun 2022 16:33:11 +0100 Subject: [PATCH 07/26] App Details Updates - Show bound configs and services - Fixed issues when the app doesn't contain a deployment --- pkg/epinio/detail/applications.vue | 69 ++++++++++++++++++++++++------ pkg/epinio/l10n/en-us.yaml | 5 +++ shell/mixins/brand.js | 2 +- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/pkg/epinio/detail/applications.vue b/pkg/epinio/detail/applications.vue index cfde92e90c..0ffd24bbf1 100644 --- a/pkg/epinio/detail/applications.vue +++ b/pkg/epinio/detail/applications.vue @@ -8,6 +8,8 @@ import ResourceTable from '@shell/components/ResourceTable.vue'; import PlusMinus from '@shell/components/form/PlusMinus.vue'; import { epinioExceptionToErrorsArray } from '../utils/errors'; import ApplicationCard from '@/shell/components/cards/ApplicationCard.vue'; +import Tabbed from '@shell/components/Tabbed/index.vue'; +import Tab from '@shell/components/Tabbed/Tab.vue'; interface Data { } @@ -19,7 +21,9 @@ export default Vue.extend({ ConsumptionGauge, ResourceTable, PlusMinus, - ApplicationCard + ApplicationCard, + Tabbed, + Tab, }, props: { value: { @@ -35,12 +39,35 @@ export default Vue.extend({ required: true }, }, + fetch() { + this.$store.dispatch(`epinio/findAll`, { type: EPINIO_TYPES.SERVICE_INSTANCE }); + this.$store.dispatch(`epinio/findAll`, { type: EPINIO_TYPES.CONFIGURATION }); + }, + data() { + const appInstanceSchema = this.$store.getters[`${ EPINIO_PRODUCT_NAME }/schemaFor`](EPINIO_TYPES.APP_INSTANCE); + const servicesSchema = this.$store.getters[`${ EPINIO_PRODUCT_NAME }/schemaFor`](EPINIO_TYPES.SERVICE_INSTANCE); + const servicesHeaders: [] = this.$store.getters['type-map/headersFor'](servicesSchema); + const configsSchema = this.$store.getters[`${ EPINIO_PRODUCT_NAME }/schemaFor`](EPINIO_TYPES.CONFIGURATION); + const configsHeaders: [] = this.$store.getters['type-map/headersFor'](configsSchema); + return { - appInstanceSchema: this.$store.getters[`${ EPINIO_PRODUCT_NAME }/schemaFor`](EPINIO_TYPES.APP_INSTANCE), saving: false, + appInstance: { + schema: appInstanceSchema, + headers: this.$store.getters['type-map/headersFor'](appInstanceSchema), + }, + services: { + schema: servicesSchema, + headers: servicesHeaders.filter((h: any) => !['namespace', 'boundApps'].includes(h.name)), + }, + configs: { + schema: configsSchema, + headers: configsHeaders.filter((h: any) => !['namespace', 'boundApps', 'service'].includes(h.name)), + } }; }, + methods: { async updateInstances(newInstances: number) { this.$set(this, 'saving', true); @@ -58,6 +85,12 @@ export default Vue.extend({ return `${ matchGithub?.[4] }/${ matchGithub?.[5] }`; } + }, + + computed: { + sourceIcon(): string { + return this.value.sourceInfo?.icon || 'icon-epinio'; + } } }); @@ -68,7 +101,7 @@ export default Vue.extend({ @@ -100,11 +133,11 @@ export default Vue.extend({ -

+

{{ t('epinio.applications.detail.deployment.label') }}

-
+
({
+ +

+ {{ t('epinio.applications.detail.tables.label') }} +

+
- - - - + + + + + + + + + + + + + +
@@ -291,7 +337,6 @@ export default Vue.extend({ } .deployment { - margin-bottom: 60px; .simple-box { width: 100%; margin-bottom: 0; diff --git a/pkg/epinio/l10n/en-us.yaml b/pkg/epinio/l10n/en-us.yaml index 71803e8d28..44c97694f5 100644 --- a/pkg/epinio/l10n/en-us.yaml +++ b/pkg/epinio/l10n/en-us.yaml @@ -77,6 +77,11 @@ epinio: instances: Instances memory: Memory cpu: CPU + tables: + label: Resources + instances: Instances + services: Services + configs: Configurations create: title: Application titleSubText: Epinio diff --git a/shell/mixins/brand.js b/shell/mixins/brand.js index a1464c2e93..8db9a80008 100644 --- a/shell/mixins/brand.js +++ b/shell/mixins/brand.js @@ -12,7 +12,7 @@ export default { }, data() { - return { globalSettings: [], apps: [] }; + return { apps: [] }; }, computed: { From 71907b93a5f685e01b59b7da33b81024e3275de8 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 7 Jun 2022 16:37:34 +0100 Subject: [PATCH 08/26] Show app chart in app details page --- pkg/epinio/models/applications.js | 39 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/pkg/epinio/models/applications.js b/pkg/epinio/models/applications.js index ae0358fc60..0dde7fd809 100644 --- a/pkg/epinio/models/applications.js +++ b/pkg/epinio/models/applications.js @@ -241,30 +241,43 @@ export default class EpinioApplicationModel extends EpinioMetaResource { if (!this.origin) { return undefined; } + const appChart = { + label: 'App Chart', + value: this.configuration.appchart + }; + switch (this.origin.Kind) { // APPLICATION_MANIFEST_SOURCE_TYPE case APPLICATION_MANIFEST_SOURCE_TYPE.PATH: - return { label: 'File system', icon: 'icon-file' }; + return { + label: 'File system', + icon: 'icon-file', + details: [ + appChart + ] + }; case APPLICATION_MANIFEST_SOURCE_TYPE.GIT: return { label: 'Git', icon: 'icon-file', - details: [{ - label: 'Url', - value: this.origin.git.repository - }, { - label: 'Revision', - icon: 'icon-github', - value: this.origin.git.revision - }] + details: [ + appChart, { + label: 'Url', + value: this.origin.git.repository + }, { + label: 'Revision', + icon: 'icon-github', + value: this.origin.git.revision + }] }; case APPLICATION_MANIFEST_SOURCE_TYPE.CONTAINER: return { label: 'Container', icon: 'icon-docker', - details: [{ - label: 'Image', - value: this.origin.Container || this.origin.container - }] + details: [ + appChart, { + label: 'Image', + value: this.origin.Container || this.origin.container + }] }; default: return undefined; From da4c4d42ce06ab09c1e076a294956198e8276460 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 8 Jun 2022 15:16:35 +0100 Subject: [PATCH 09/26] Fix folder source when there is only a single file in the folder - https://github.com/epinio/ui/issues/130 - if multiple and directory are off if should return a single file, if either are on it should return an array. however the current logic is synced with line 103 below which would mean a lot of testing to validate - so just make the handler function array safe --- pkg/epinio/components/application/AppSource.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/epinio/components/application/AppSource.vue b/pkg/epinio/components/application/AppSource.vue index 50512dc09d..9d702772d5 100644 --- a/pkg/epinio/components/application/AppSource.vue +++ b/pkg/epinio/components/application/AppSource.vue @@ -54,6 +54,11 @@ export interface EpinioAppSource { appChart: string, } +interface FileWithRelativePath extends File { + // For some reason TS throws this as missing at transpile time .. so recreate it + readonly webkitRelativePath: string; +} + const DEFAULT_BUILD_PACK = 'paketobuildpacks/builder:full'; // Data, Methods, Computed, Props @@ -174,11 +179,12 @@ export default Vue.extend({ } }, - onFolderSelected(files: any[]) { + onFolderSelected(files: FileWithRelativePath | FileWithRelativePath[]) { + const safeFiles = Array.isArray(files) ? files : [files]; let folderName: string = ''; // Determine parent folder name - for (const f of files) { + for (const f of safeFiles) { const paths = f.webkitRelativePath.split('/'); if (paths.length > 1) { @@ -193,7 +199,7 @@ export default Vue.extend({ } } - const filesToZip = files.reduce((res, f) => { + const filesToZip = safeFiles.reduce((res, f) => { let path = f.webkitRelativePath; if (folderName) { From 76cf91ca300fbfe40543bb004d492c4ca456f5aa Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 8 Jun 2022 15:22:41 +0100 Subject: [PATCH 10/26] Multiple small tweaks - Fix nuxt.config - add description for catalog service - change app charts to app templates --- nuxt.config.js | 2 +- pkg/epinio/l10n/en-us.yaml | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/nuxt.config.js b/nuxt.config.js index 383094eb2e..6229dfa685 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,7 +1,7 @@ import config from './shell/nuxt.config'; export default config(__dirname, { - excludes: ['epinio', 'rancher-components'], + excludes: ['rancher-components'], // excludes: ['fleet', 'example'] // autoLoad: ['fleet', 'example'] }); diff --git a/pkg/epinio/l10n/en-us.yaml b/pkg/epinio/l10n/en-us.yaml index 44c97694f5..815e4f1061 100644 --- a/pkg/epinio/l10n/en-us.yaml +++ b/pkg/epinio/l10n/en-us.yaml @@ -11,8 +11,8 @@ typeLabel: } appcharts: |- {count, plural, - one { Application Charts } - other { Application Charts } + one { Application Templates } + other { Application Templates } } "services": |- {count, plural, @@ -33,8 +33,9 @@ typeDescription: namespaces: Namespaces group your applications, services and other resources. Deleting a namespace will delete all of it's resources. applications: Epinio uses Applications to transition your code, through build, to being deployed. services: Epinio can create instances of your services. Instances can be bound to your applications to provide data, for example a database service bound to an application might provide connection credentials. - configurations: Configurations are a way to provide data to Applications. The data becomes available once the configuration is bound to them. - appcharts: Application charts define kube resources created by your application + configurations: Configurations are a way to provide data to applications. The data becomes available once the configuration is bound to them. + appcharts: Application Templates define kube resources created by your application + catalogservices: Catalog Services provide additional, common functionality to applications. For example an instance of a database Catalog Service can be bound to an application. epinio: label: Epinio intro: From edbb97713205b0ad957d7b4bb49d72596cb591b7 Mon Sep 17 00:00:00 2001 From: scures Date: Fri, 10 Jun 2022 13:08:24 +0200 Subject: [PATCH 11/26] Show list of apps in cards --- pkg/epinio/list/catalogservices.vue | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 pkg/epinio/list/catalogservices.vue diff --git a/pkg/epinio/list/catalogservices.vue b/pkg/epinio/list/catalogservices.vue new file mode 100644 index 0000000000..a9c0bc77dd --- /dev/null +++ b/pkg/epinio/list/catalogservices.vue @@ -0,0 +1,52 @@ + + + From c67cb943f1974cd6bc1746d449f617fb2375e156 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Mon, 13 Jun 2022 14:18:32 +0100 Subject: [PATCH 12/26] Fix epinio namespace filter - epinio standalone won't have a current cluster (a rancher mgmt cluster resource type) - so take this into account with the same property using with NamespaceFilter --- shell/components/nav/Header.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/components/nav/Header.vue b/shell/components/nav/Header.vue index 55392b7430..2d81bd5ab5 100644 --- a/shell/components/nav/Header.vue +++ b/shell/components/nav/Header.vue @@ -331,7 +331,7 @@ export default {
From f223b1da25e05023c6827936bda8111c5daf6756 Mon Sep 17 00:00:00 2001 From: scures Date: Wed, 15 Jun 2022 09:48:40 +0200 Subject: [PATCH 13/26] Service detaills --- nuxt.config.js | 2 +- pkg/epinio/list/catalogservices.vue | 10 +- pkg/epinio/pages/c/_cluster/catalog/index.vue | 161 ++++++++++++++++++ pkg/epinio/routing/epinio-routing.ts | 5 + 4 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 pkg/epinio/pages/c/_cluster/catalog/index.vue diff --git a/nuxt.config.js b/nuxt.config.js index 383094eb2e..6229dfa685 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,7 +1,7 @@ import config from './shell/nuxt.config'; export default config(__dirname, { - excludes: ['epinio', 'rancher-components'], + excludes: ['rancher-components'], // excludes: ['fleet', 'example'] // autoLoad: ['fleet', 'example'] }); diff --git a/pkg/epinio/list/catalogservices.vue b/pkg/epinio/list/catalogservices.vue index a9c0bc77dd..73e05898d4 100644 --- a/pkg/epinio/list/catalogservices.vue +++ b/pkg/epinio/list/catalogservices.vue @@ -2,6 +2,7 @@ import { EPINIO_TYPES, EPINIO_PRODUCT_NAME } from '../types'; import Loading from '@shell/components/Loading'; import SelectIconGrid from '@shell/components/SelectIconGrid'; +import { CHART } from '@shell/config/query-params'; export default { name: 'EpinioCatalogList', @@ -18,15 +19,10 @@ export default { methods: { showDetails(chart) { - console.log('chart: ', chart); this.$router.push({ name: `${ EPINIO_PRODUCT_NAME }-c-cluster-catalog`, - params: { - cluster: this.$route.params.cluster, - product: this.$store.getters['productId'], - chart: this.chart - }, - query: {} + params: { cluster: this.$route.params.cluster, chart }, + query: { [CHART]: chart } }); }, }, diff --git a/pkg/epinio/pages/c/_cluster/catalog/index.vue b/pkg/epinio/pages/c/_cluster/catalog/index.vue new file mode 100644 index 0000000000..14a2e93c9e --- /dev/null +++ b/pkg/epinio/pages/c/_cluster/catalog/index.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/pkg/epinio/routing/epinio-routing.ts b/pkg/epinio/routing/epinio-routing.ts index ff8df4948c..3f35f18e35 100644 --- a/pkg/epinio/routing/epinio-routing.ts +++ b/pkg/epinio/routing/epinio-routing.ts @@ -4,6 +4,7 @@ import { EPINIO_PRODUCT_NAME } from '../types'; import CreateApp from '../pages/c/_cluster/applications/createapp/index.vue'; import ListApp from '../pages/c/_cluster/applications/index.vue'; +import CatalogDetails from '../pages/c/_cluster/catalog/index.vue'; import ListEpinio from '../pages/index.vue'; import ListEpinioResource from '../pages/c/_cluster/_resource/index.vue'; import CreateEpinioResource from '../pages/c/_cluster/_resource/create.vue'; @@ -22,6 +23,10 @@ const routes: RouteConfig[] = [{ name: `${ EPINIO_PRODUCT_NAME }`, path: `/:product`, component: ListEpinio, +}, { + name: `${ EPINIO_PRODUCT_NAME }-c-cluster-catalog`, + path: `/:product/c/:cluster/catalog/`, + component: CatalogDetails, }, { name: `${ EPINIO_PRODUCT_NAME }-c-cluster-resource`, path: `/:product/c/:cluster/:resource`, From df13cc217c574ed5cda3ed64c314ffa97c5a50f5 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Wed, 15 Jun 2022 13:00:50 +0100 Subject: [PATCH 14/26] Fixes after NameNsDescription changes - Wire in new create - Create as part of CruResource for config / services - Create as part of final step for app - Ensure first ns is selected (as first is no longer selected by default) - Remove 'no namespaces' blockers --- pkg/epinio/components/application/AppInfo.vue | 30 ++++++----------- .../components/application/AppProgress.vue | 33 +++++++++++++------ pkg/epinio/edit/configurations.vue | 8 ++--- pkg/epinio/edit/services.vue | 10 ++---- pkg/epinio/l10n/en-us.yaml | 5 ++- pkg/epinio/models/application-action.js | 12 ++++++- pkg/epinio/models/namespaces.js | 5 ++- pkg/epinio/store/epinio-store/actions.ts | 10 +++++- 8 files changed, 65 insertions(+), 48 deletions(-) diff --git a/pkg/epinio/components/application/AppInfo.vue b/pkg/epinio/components/application/AppInfo.vue index ab2fd4fa66..8a6c083b5a 100644 --- a/pkg/epinio/components/application/AppInfo.vue +++ b/pkg/epinio/components/application/AppInfo.vue @@ -5,7 +5,7 @@ import NameNsDescription from '@shell/components/form/NameNsDescription.vue'; import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue'; import KeyValue from '@shell/components/form/KeyValue.vue'; import ArrayList from '@shell/components/form/ArrayList.vue'; -import Banner from '@components/Banner/Banner.vue'; +import Loading from '@shell/components/Loading.vue'; import { EPINIO_TYPES } from '../../types'; import { sortBy } from '@shell/utils/sort'; @@ -24,7 +24,7 @@ export interface EpinioAppInfo { interface Data { errors: string[], - values: EpinioAppInfo + values?: EpinioAppInfo } // Data, Methods, Computed, Props @@ -35,7 +35,7 @@ export default Vue.extend({ NameNsDescription, LabeledInput, KeyValue, - Banner + Loading }, props: { @@ -52,17 +52,7 @@ export default Vue.extend({ data() { return { errors: [], - values: { - meta: { - name: this.application.meta?.name, - namespace: this.application.meta?.namespace - }, - configuration: { - instances: this.application.configuration?.instances || 1, - environment: this.application.configuration?.environment || {}, - routes: this.application.configuration?.routes || [], - }, - } + values: undefined }; }, @@ -70,7 +60,7 @@ export default Vue.extend({ this.values = { meta: { name: this.application.meta?.name, - namespace: this.application.meta?.namespace + namespace: this.application.meta?.namespace || this.namespaces[0].metadata.name }, configuration: { instances: this.application.configuration?.instances || 1, @@ -105,6 +95,9 @@ export default Vue.extend({ }, valid() { + if (!this.values) { + return false; + } const validName = !!this.values.meta?.name; const validNamespace = !!this.values.meta?.namespace; const validInstances = typeof this.values.configuration?.instances !== 'string' && this.values.configuration?.instances >= 0; @@ -127,11 +120,7 @@ export default Vue.extend({