diff --git a/CHANGELOG.md b/CHANGELOG.md index c97e4b84b..64b42a33d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan - [#164](https://github.com/kobsio/kobs/pull/164): Improve chart handling across plugins. - [#167](https://github.com/kobsio/kobs/pull/167): Improve styling across plugins. - [#169](https://github.com/kobsio/kobs/pull/169): Rework home page to include plugins, applications and teams. +- [#173](https://github.com/kobsio/kobs/pull/173): Move CRD interfaces to core plugin, so that we can use them within the plugin. ## [v0.5.0](https://github.com/kobsio/kobs/releases/tag/v0.5.0) (2021-08-03) diff --git a/plugins/applications/src/components/home/Home.tsx b/plugins/applications/src/components/home/Home.tsx index 5367fa9be..e023cb8b7 100644 --- a/plugins/applications/src/components/home/Home.tsx +++ b/plugins/applications/src/components/home/Home.tsx @@ -18,8 +18,14 @@ import { import { QueryObserverResult, useQuery } from 'react-query'; import React, { useContext, useState } from 'react'; -import { ClustersContext, IClusterContext, IPluginPageProps, LinkWrapper, useDebounce } from '@kobsio/plugin-core'; -import { IApplication } from '../../utils/interfaces'; +import { + ClustersContext, + IApplication, + IClusterContext, + IPluginPageProps, + LinkWrapper, + useDebounce, +} from '@kobsio/plugin-core'; const Home: React.FunctionComponent = () => { const [searchTerm, setSearchTerm] = useState(''); diff --git a/plugins/applications/src/components/page/Application.tsx b/plugins/applications/src/components/page/Application.tsx index f9919d6c3..64c6d6556 100644 --- a/plugins/applications/src/components/page/Application.tsx +++ b/plugins/applications/src/components/page/Application.tsx @@ -19,9 +19,8 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; import { UsersIcon } from '@patternfly/react-icons'; -import { ExternalLink, Title } from '@kobsio/plugin-core'; +import { ExternalLink, IApplication, Title } from '@kobsio/plugin-core'; import { DashboardsWrapper } from '@kobsio/plugin-dashboards'; -import { IApplication } from '../../utils/interfaces'; interface IApplicationsParams { cluster: string; diff --git a/plugins/applications/src/components/panel/ApplicationsGallery.tsx b/plugins/applications/src/components/panel/ApplicationsGallery.tsx index 0c1c36f1b..7fd09d530 100644 --- a/plugins/applications/src/components/panel/ApplicationsGallery.tsx +++ b/plugins/applications/src/components/panel/ApplicationsGallery.tsx @@ -3,14 +3,13 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { memo } from 'react'; import { useHistory } from 'react-router-dom'; -import { IApplication, IReference } from '../../utils/interfaces'; +import { IApplication, IApplicationReference, IPluginTimes } from '@kobsio/plugin-core'; import ApplicationsGalleryItem from './ApplicationsGalleryItem'; -import { IPluginTimes } from '@kobsio/plugin-core'; interface IApplicationsGalleryProps { clusters: string[]; namespaces: string[]; - team?: IReference; + team?: IApplicationReference; } // ApplicationsGallery is the component to display all applications inside a gallery view. diff --git a/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx b/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx index 77ea14650..b227a7c28 100644 --- a/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx +++ b/plugins/applications/src/components/panel/ApplicationsGalleryItem.tsx @@ -1,8 +1,7 @@ import { Badge, Card, CardBody, CardTitle } from '@patternfly/react-core'; import React from 'react'; -import { IPluginTimes, LinkWrapper, PluginPreview } from '@kobsio/plugin-core'; -import { IApplication } from '../../utils/interfaces'; +import { IApplication, IPluginTimes, LinkWrapper, PluginPreview } from '@kobsio/plugin-core'; interface IApplicationsGalleryItemProps { times: IPluginTimes; diff --git a/plugins/applications/src/components/panel/details/Details.tsx b/plugins/applications/src/components/panel/details/Details.tsx index d884d0db5..ddf24776f 100644 --- a/plugins/applications/src/components/panel/details/Details.tsx +++ b/plugins/applications/src/components/panel/details/Details.tsx @@ -15,10 +15,9 @@ import { TopologyIcon, UsersIcon } from '@patternfly/react-icons'; import { Link } from 'react-router-dom'; import React from 'react'; -import { ExternalLink, Title } from '@kobsio/plugin-core'; +import { ExternalLink, IApplication, Title } from '@kobsio/plugin-core'; import { DashboardsWrapper } from '@kobsio/plugin-dashboards'; import DetailsLink from './DetailsLink'; -import { IApplication } from '../../../utils/interfaces'; interface IDetailsProps { application: IApplication; diff --git a/plugins/applications/src/components/panel/details/DetailsLink.tsx b/plugins/applications/src/components/panel/details/DetailsLink.tsx index 325cf8507..5badb7e8a 100644 --- a/plugins/applications/src/components/panel/details/DetailsLink.tsx +++ b/plugins/applications/src/components/panel/details/DetailsLink.tsx @@ -1,8 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; -import { DrawerLink } from '@kobsio/plugin-core'; -import { IApplication } from '../../../utils/interfaces'; +import { DrawerLink, IApplication } from '@kobsio/plugin-core'; interface IDetailsLinkProps { application: IApplication; diff --git a/plugins/applications/src/utils/interfaces.ts b/plugins/applications/src/utils/interfaces.ts index 7ffd11725..1734d3b55 100644 --- a/plugins/applications/src/utils/interfaces.ts +++ b/plugins/applications/src/utils/interfaces.ts @@ -1,40 +1,6 @@ -import { IDashboardReference, IPlugin } from '@kobsio/plugin-dashboards'; import cytoscape from 'cytoscape'; -// IApplication implements the Application CR, which can be created by a user to describe an application. While we have -// to omit the cluster, namespace and name field in the Go implementation of the CR, we can assume that these fields are -// present in the frontend, because they will always be set when an application is returned from the Kubernetes API. -export interface IApplication { - cluster: string; - namespace: string; - name: string; - description?: string; - tags?: string[]; - links?: ILink[]; - teams?: IReference[]; - dependencies?: IReference[]; - preview?: IPreview; - dashboards?: IDashboardReference[]; -} - -export interface IPreview { - title: string; - plugin: IPlugin; -} - -export interface ILink { - title: string; - link: string; -} - -// IReference is the interface, which is used to create a reference to an team or an application. Will the team can be -// used to describe the ownership of the application, the application references are used to identify dependencies. -export interface IReference { - cluster?: string; - namespace?: string; - name: string; - description?: string; -} +import { IApplication, IApplicationReference } from '@kobsio/plugin-core'; // TView are the two options we have to present a list of applications to the user. This can be a gallery view, where // it will be possible add a single plugin to the card or the topology view, which can be used to display the @@ -47,7 +13,7 @@ export interface IPanelOptions { view?: TView; clusters?: string[]; namespaces?: string[]; - team?: IReference; + team?: IApplicationReference; } // INode is a single node for the topology graph. It implements the ElementDefinition interface from cytoscape. diff --git a/plugins/core/src/components/app/Account.tsx b/plugins/core/src/components/app/Account.tsx deleted file mode 100644 index 3d14e36e1..000000000 --- a/plugins/core/src/components/app/Account.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Avatar, Card, CardBody, PageSection, PageSectionVariants } from '@patternfly/react-core'; -import React, { useContext } from 'react'; - -import { AuthContext, IAuthContext } from '../../context/AuthContext'; -import AccountTeams from './AccountTeams'; -import { getGravatarImageUrl } from '../../utils/gravatar'; - -const Account: React.FunctionComponent = () => { - const authContext = useContext(AuthContext); - - return ( - - - - -
- -
{authContext.user.profile.fullName}
-
{authContext.user.profile.position}
-
-
-
-
- - {authContext.user.profile.teams && } -
- ); -}; - -export default Account; diff --git a/plugins/core/src/components/app/App.tsx b/plugins/core/src/components/app/App.tsx index 0df238a69..5465f1a3e 100644 --- a/plugins/core/src/components/app/App.tsx +++ b/plugins/core/src/components/app/App.tsx @@ -10,7 +10,7 @@ import '@patternfly/patternfly/patternfly-addons.css'; import { IPluginComponents, PluginsContextProvider } from '../../context/PluginsContext'; import { AuthContextProvider } from '../../context/AuthContext'; import { ClustersContextProvider } from '../../context/ClustersContext'; -import HomePage from './HomePage'; +import Home from './Home'; import { PluginPage } from '../plugin/PluginPage'; import { TerminalsContextProvider } from '../../context/TerminalsContext'; @@ -50,7 +50,7 @@ export const App: React.FunctionComponent = ({ plugins }: IAppProps) - + diff --git a/plugins/core/src/components/app/HomePage.tsx b/plugins/core/src/components/app/Home.tsx similarity index 70% rename from plugins/core/src/components/app/HomePage.tsx rename to plugins/core/src/components/app/Home.tsx index 1566c4dd0..9268ef3c5 100644 --- a/plugins/core/src/components/app/HomePage.tsx +++ b/plugins/core/src/components/app/Home.tsx @@ -1,5 +1,7 @@ import { - Divider, + Avatar, + Card, + CardBody, Grid, GridItem, Menu, @@ -14,8 +16,9 @@ import { useHistory, useLocation } from 'react-router-dom'; import { AuthContext, IAuthContext } from '../../context/AuthContext'; import { IPluginsContext, PluginsContext } from '../../context/PluginsContext'; -import Account from './Account'; -import Plugins from './Plugins'; +import Account from './account/Account'; +import Plugins from './plugins/Plugins'; +import { getGravatarImageUrl } from '../../utils/gravatar'; const HomePage: React.FunctionComponent = () => { const history = useHistory(); @@ -57,6 +60,29 @@ const HomePage: React.FunctionComponent = () => { + {authContext.user.hasProfile && ( + + changeActivePage(undefined, 'account')} + > + +
+ +
{authContext.user.profile.fullName}
+
{authContext.user.profile.position}
+
+
+
+

 

+
+ )} @@ -66,12 +92,6 @@ const HomePage: React.FunctionComponent = () => { {plugin.displayName} ))} - {authContext.user.hasProfile && ( - - - My Account - - )} diff --git a/plugins/core/src/components/app/account/Account.tsx b/plugins/core/src/components/app/account/Account.tsx new file mode 100644 index 000000000..21c06914e --- /dev/null +++ b/plugins/core/src/components/app/account/Account.tsx @@ -0,0 +1,34 @@ +import { Avatar, Card, CardBody } from '@patternfly/react-core'; +import React, { useContext } from 'react'; + +import { AuthContext, IAuthContext } from '../../../context/AuthContext'; +import AccountTeams from './AccountTeams'; +import { getGravatarImageUrl } from '../../../utils/gravatar'; + +const Account: React.FunctionComponent = () => { + const authContext = useContext(AuthContext); + + return ( + + + +
+ +
{authContext.user.profile.fullName}
+
{authContext.user.profile.position}
+
+
+
+ +

 

+ + {authContext.user.profile.teams && } +
+ ); +}; + +export default Account; diff --git a/plugins/core/src/components/app/AccountTeams.tsx b/plugins/core/src/components/app/account/AccountTeams.tsx similarity index 55% rename from plugins/core/src/components/app/AccountTeams.tsx rename to plugins/core/src/components/app/account/AccountTeams.tsx index 3252d5ad5..9b947af5f 100644 --- a/plugins/core/src/components/app/AccountTeams.tsx +++ b/plugins/core/src/components/app/account/AccountTeams.tsx @@ -1,16 +1,17 @@ -import { Gallery, GalleryItem, PageSection, PageSectionVariants } from '@patternfly/react-core'; +import { Gallery, GalleryItem } from '@patternfly/react-core'; import React from 'react'; import { useQuery } from 'react-query'; -import { IAuthProfile, IAuthProfileTeam } from '../../context/AuthContext'; import AccountTeamsItem from './AccountTeamsItem'; +import { ITeam } from '../../../crds/team'; +import { IUser } from '../../../crds/user'; export interface IAccountTeamsProps { - user: IAuthProfile; + user: IUser; } const AccountTeams: React.FunctionComponent = ({ user }: IAccountTeamsProps) => { - const { isError, isLoading, data } = useQuery(['users/teams', user], async () => { + const { isError, isLoading, data } = useQuery(['users/teams', user], async () => { try { const response = await fetch(`/api/plugins/users/teams?cluster=${user.cluster}&namespace=${user.namespace}`, { body: JSON.stringify({ @@ -39,21 +40,19 @@ const AccountTeams: React.FunctionComponent = ({ user }: IAc } return ( - - - {data.map((team, index) => ( - - - - ))} - - + + {data.map((team, index) => ( + + + + ))} + ); }; diff --git a/plugins/core/src/components/app/AccountTeamsItem.tsx b/plugins/core/src/components/app/account/AccountTeamsItem.tsx similarity index 89% rename from plugins/core/src/components/app/AccountTeamsItem.tsx rename to plugins/core/src/components/app/account/AccountTeamsItem.tsx index 7f7f6f130..80ce08407 100644 --- a/plugins/core/src/components/app/AccountTeamsItem.tsx +++ b/plugins/core/src/components/app/account/AccountTeamsItem.tsx @@ -1,8 +1,8 @@ import { Avatar, Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core'; import React from 'react'; -import { LinkWrapper } from '../misc/LinkWrapper'; -import teamsIcon from '../../assets/teamsIcon.png'; +import { LinkWrapper } from '../../misc/LinkWrapper'; +import teamsIcon from '../../../assets/teamsIcon.png'; interface IAccountTeamsItemProps { cluster: string; diff --git a/plugins/core/src/components/app/PluginItem.tsx b/plugins/core/src/components/app/plugins/PluginItem.tsx similarity index 93% rename from plugins/core/src/components/app/PluginItem.tsx rename to plugins/core/src/components/app/plugins/PluginItem.tsx index 231851c85..e47735bda 100644 --- a/plugins/core/src/components/app/PluginItem.tsx +++ b/plugins/core/src/components/app/plugins/PluginItem.tsx @@ -1,8 +1,8 @@ import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core'; import React, { useContext } from 'react'; -import { IPluginData, IPluginsContext, PluginsContext } from '../../context/PluginsContext'; -import { LinkWrapper } from '../misc/LinkWrapper'; +import { IPluginData, IPluginsContext, PluginsContext } from '../../../context/PluginsContext'; +import { LinkWrapper } from '../../misc/LinkWrapper'; // IPluginItemProps is the interface for an item on the home page. Each item contains a title, body, link and icon. interface IPluginItemProps { diff --git a/plugins/core/src/components/app/Plugins.tsx b/plugins/core/src/components/app/plugins/Plugins.tsx similarity index 83% rename from plugins/core/src/components/app/Plugins.tsx rename to plugins/core/src/components/app/plugins/Plugins.tsx index 029b18c5a..e838d5ecf 100644 --- a/plugins/core/src/components/app/Plugins.tsx +++ b/plugins/core/src/components/app/plugins/Plugins.tsx @@ -1,8 +1,8 @@ import { Gallery, GalleryItem } from '@patternfly/react-core'; import React, { useContext } from 'react'; -import { AuthContext, IAuthContext } from '../../context/AuthContext'; -import { IPluginData } from '../../context/PluginsContext'; +import { AuthContext, IAuthContext } from '../../../context/AuthContext'; +import { IPluginData } from '../../../context/PluginsContext'; import PluginItem from './PluginItem'; export interface IPluginsProps { diff --git a/plugins/core/src/context/AuthContext.tsx b/plugins/core/src/context/AuthContext.tsx index af495f6e3..5431b6143 100644 --- a/plugins/core/src/context/AuthContext.tsx +++ b/plugins/core/src/context/AuthContext.tsx @@ -2,39 +2,15 @@ import { Alert, AlertActionLink, AlertVariant, Spinner } from '@patternfly/react import { QueryObserverResult, useQuery } from 'react-query'; import React from 'react'; +import { IUser } from '../crds/user'; + export interface IAuth { id: string; hasProfile: boolean; - profile: IAuthProfile; + profile: IUser; permissions: IAuthPermissions; } -export interface IAuthProfile { - cluster: string; - namespace: string; - name: string; - id: string; - fullName: string; - email: string; - position?: string; - bio?: string; - teams?: IAuthProfileTeamReference[]; -} - -export interface IAuthProfileTeamReference { - cluster?: string; - namespace?: string; - name: string; -} - -export interface IAuthProfileTeam { - cluster: string; - namespace: string; - name: string; - description?: string; - logo?: string; -} - export interface IAuthPermissions { plugins: string[]; resources: IAuthPermissionsResources[]; diff --git a/plugins/core/src/crds/application.ts b/plugins/core/src/crds/application.ts new file mode 100644 index 000000000..c044a8609 --- /dev/null +++ b/plugins/core/src/crds/application.ts @@ -0,0 +1,37 @@ +import { IReference as IDashboardReference, IPlugin } from './dashboard'; + +// IApplication implements the Application CR, which can be created by a user to describe an application. While we have +// to omit the cluster, namespace and name field in the Go implementation of the CR, we can assume that these fields are +// present in the frontend, because they will always be set when an application is returned from the Kubernetes API. +export interface IApplication { + cluster: string; + namespace: string; + name: string; + description?: string; + tags?: string[]; + links?: IApplicationLink[]; + teams?: IApplicationReference[]; + dependencies?: IApplicationReference[]; + preview?: IPreview; + dashboards?: IDashboardReference[]; +} + +export interface IPreview { + title: string; + plugin: IPlugin; +} + +export interface IApplicationLink { + title: string; + link: string; +} + +// The IApplicationReference is the interface, which is used to create a reference to a team or an application. While +// the team can be used to describe the ownership of the application, the application references are used to identify +// dependencies between applications. +export interface IApplicationReference { + cluster?: string; + namespace?: string; + name: string; + description?: string; +} diff --git a/plugins/core/src/crds/dashboard.ts b/plugins/core/src/crds/dashboard.ts new file mode 100644 index 000000000..79859b3ba --- /dev/null +++ b/plugins/core/src/crds/dashboard.ts @@ -0,0 +1,67 @@ +// IDashboard is the interface for the Dashboards CR, like it is implemented in the Go code. In contrast to the Go +// implementation we are sure that the cluster, namespace and name for the dashboard is set, because the values are set +// each time a dashboard is retrieved from the Kubernetes API. +export interface IDashboard { + cluster: string; + namespace: string; + name: string; + title: string; + description?: string; + placeholders?: IPlaceholder[]; + variables?: IVariable[]; + rows: IRow[]; +} + +export interface IPlaceholder { + name: string; + description?: string; +} + +export interface IVariable { + name: string; + label?: string; + hide?: boolean; + plugin: IPlugin; +} + +export interface IRow { + title?: string; + description?: string; + size?: number; + panels: IPanel[]; +} + +export interface IPanel { + title: string; + description?: string; + colSpan?: number; + rowSpan?: number; + plugin: IPlugin; +} + +export interface IPlugin { + name: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + options?: any; +} + +// IReference is the interface for a dashboard reference in the Team or Application CR. If the cluster or namespace is +// not specified in the reference we assume the dashboard is in the same namespace as the team or application. +export interface IReference { + cluster?: string; + namespace?: string; + name?: string; + title: string; + description?: string; + placeholders?: IPlaceholders; + inline?: IReferenceInline; +} + +export interface IPlaceholders { + [key: string]: string; +} + +export interface IReferenceInline { + variables?: IVariable[]; + rows: IRow[]; +} diff --git a/plugins/core/src/crds/team.ts b/plugins/core/src/crds/team.ts new file mode 100644 index 000000000..7acd8f6fc --- /dev/null +++ b/plugins/core/src/crds/team.ts @@ -0,0 +1,17 @@ +import { IReference as IDashboardReference } from './dashboard'; + +// The ITeam interface implements the Team CRD. +export interface ITeam { + cluster: string; + namespace: string; + name: string; + description?: string; + links?: ITeamLink[]; + logo?: string; + dashboards?: IDashboardReference[]; +} + +export interface ITeamLink { + title: string; + link: string; +} diff --git a/plugins/core/src/crds/user.ts b/plugins/core/src/crds/user.ts new file mode 100644 index 000000000..fa544c490 --- /dev/null +++ b/plugins/core/src/crds/user.ts @@ -0,0 +1,18 @@ +// The IUser interface implements the User CRD. +export interface IUser { + cluster: string; + namespace: string; + name: string; + id: string; + fullName: string; + email: string; + position?: string; + bio?: string; + teams?: IUserTeamReference[]; +} + +export interface IUserTeamReference { + cluster?: string; + namespace?: string; + name: string; +} diff --git a/plugins/core/src/index.ts b/plugins/core/src/index.ts index 033dee46b..a1d05d8a8 100644 --- a/plugins/core/src/index.ts +++ b/plugins/core/src/index.ts @@ -21,6 +21,11 @@ export * from './context/ClustersContext'; export * from './context/PluginsContext'; export * from './context/TerminalsContext'; +export * from './crds/application'; +export * from './crds/dashboard'; +export * from './crds/team'; +export * from './crds/user'; + export * from './utils/chart'; export * from './utils/colors'; export * from './utils/gravatar'; diff --git a/plugins/dashboards/src/components/dashboards/Dashboard.tsx b/plugins/dashboards/src/components/dashboards/Dashboard.tsx index ead1d406a..9d3bfd5d3 100644 --- a/plugins/dashboards/src/components/dashboards/Dashboard.tsx +++ b/plugins/dashboards/src/components/dashboards/Dashboard.tsx @@ -6,15 +6,17 @@ import { InView } from 'react-intersection-observer'; import { ClustersContext, IClusterContext, + IDashboard, IPluginDefaults, IPluginTimes, IPluginsContext, + IRow, PluginPanel, PluginsContext, } from '@kobsio/plugin-core'; -import { IDashboard, IRow, IVariableValues } from '../../utils/interfaces'; import { interpolate, rowHeight, toGridSpans } from '../../utils/dashboard'; import DashboardToolbar from './DashboardToolbar'; +import { IVariableValues } from '../../utils/interfaces'; interface IDashboardProps { activeKey: string; diff --git a/plugins/dashboards/src/components/dashboards/DashboardWrapper.tsx b/plugins/dashboards/src/components/dashboards/DashboardWrapper.tsx index 976d6f8ca..fb72968a4 100644 --- a/plugins/dashboards/src/components/dashboards/DashboardWrapper.tsx +++ b/plugins/dashboards/src/components/dashboards/DashboardWrapper.tsx @@ -1,8 +1,7 @@ import React, { useRef } from 'react'; -import { IPluginDefaults, useDimensions } from '@kobsio/plugin-core'; +import { IDashboard, IPluginDefaults, useDimensions } from '@kobsio/plugin-core'; import Dashboard from './Dashboard'; -import { IDashboard } from '../../utils/interfaces'; interface IDashboardWrapperProps { defaults: IPluginDefaults; diff --git a/plugins/dashboards/src/components/dashboards/Dashboards.tsx b/plugins/dashboards/src/components/dashboards/Dashboards.tsx index 541999926..cc99b6232 100644 --- a/plugins/dashboards/src/components/dashboards/Dashboards.tsx +++ b/plugins/dashboards/src/components/dashboards/Dashboards.tsx @@ -13,9 +13,9 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { useEffect, useState } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; -import { IDashboard, IDashboardsOptions, IReference } from '../../utils/interfaces'; +import { IDashboard, IPluginDefaults, IReference } from '@kobsio/plugin-core'; import Dashboard from './Dashboard'; -import { IPluginDefaults } from '@kobsio/plugin-core'; +import { IDashboardsOptions } from '../../utils/interfaces'; import { getOptionsFromSearch } from '../../utils/dashboard'; interface IDashboardsProps { diff --git a/plugins/dashboards/src/components/dashboards/DashboardsWrapper.tsx b/plugins/dashboards/src/components/dashboards/DashboardsWrapper.tsx index c5fe99515..3f1051520 100644 --- a/plugins/dashboards/src/components/dashboards/DashboardsWrapper.tsx +++ b/plugins/dashboards/src/components/dashboards/DashboardsWrapper.tsx @@ -1,8 +1,7 @@ import React, { useRef } from 'react'; -import { IPluginDefaults, useDimensions } from '@kobsio/plugin-core'; +import { IPluginDefaults, IReference, useDimensions } from '@kobsio/plugin-core'; import Dashboards from './Dashboards'; -import { IReference } from '../../utils/interfaces'; interface IDashboardsWrapperProps { defaults: IPluginDefaults; diff --git a/plugins/dashboards/src/components/page/Dashboard.tsx b/plugins/dashboards/src/components/page/Dashboard.tsx index 3134cd186..ee3f0b2a5 100644 --- a/plugins/dashboards/src/components/page/Dashboard.tsx +++ b/plugins/dashboards/src/components/page/Dashboard.tsx @@ -13,10 +13,9 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; import { useHistory, useLocation, useParams } from 'react-router-dom'; +import { IDashboard, Title } from '@kobsio/plugin-core'; import { getDefaultsFromSearch, getPlaceholdersFromSearch } from '../../utils/dashboard'; import DashboardWrapper from '../dashboards/DashboardWrapper'; -import { IDashboard } from '../../utils/interfaces'; -import { Title } from '@kobsio/plugin-core'; interface IDashboardParams { cluster: string; diff --git a/plugins/dashboards/src/components/page/Dashboards.tsx b/plugins/dashboards/src/components/page/Dashboards.tsx index b1fe57037..13209aaf0 100644 --- a/plugins/dashboards/src/components/page/Dashboards.tsx +++ b/plugins/dashboards/src/components/page/Dashboards.tsx @@ -13,12 +13,11 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; +import { IDashboard, useDebounce } from '@kobsio/plugin-core'; import DashboardsItem from './DashboardsItem'; import DashboardsModal from './DashboardsModal'; import DashboardsToolbar from './DashboardsToolbar'; -import { IDashboard } from '../../utils/interfaces'; import { filterDashboards } from '../../utils/dashboard'; -import { useDebounce } from '@kobsio/plugin-core'; export interface IDashboardsProps { displayName: string; diff --git a/plugins/dashboards/src/components/page/DashboardsItem.tsx b/plugins/dashboards/src/components/page/DashboardsItem.tsx index c7a0c8249..b0e867b6f 100644 --- a/plugins/dashboards/src/components/page/DashboardsItem.tsx +++ b/plugins/dashboards/src/components/page/DashboardsItem.tsx @@ -1,7 +1,7 @@ import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core'; import React from 'react'; -import { IDashboard } from '../../utils/interfaces'; +import { IDashboard } from '@kobsio/plugin-core'; interface IDashboardsItemProps { dashboard: IDashboard; diff --git a/plugins/dashboards/src/components/page/DashboardsModal.tsx b/plugins/dashboards/src/components/page/DashboardsModal.tsx index 4e760a1dc..c920ba55c 100644 --- a/plugins/dashboards/src/components/page/DashboardsModal.tsx +++ b/plugins/dashboards/src/components/page/DashboardsModal.tsx @@ -14,8 +14,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { useHistory } from 'react-router-dom'; import { useQuery } from 'react-query'; -import { ClustersContext, IClusterContext } from '@kobsio/plugin-core'; -import { IDashboard, IPlaceholders } from '../../utils/interfaces'; +import { ClustersContext, IClusterContext, IDashboard, IPlaceholders } from '@kobsio/plugin-core'; import { getPlaceholdersObject } from '../../utils/dashboard'; interface IDashboardsModalProps { diff --git a/plugins/dashboards/src/components/panel/Panel.tsx b/plugins/dashboards/src/components/panel/Panel.tsx index 58206cea8..f86baba71 100644 --- a/plugins/dashboards/src/components/panel/Panel.tsx +++ b/plugins/dashboards/src/components/panel/Panel.tsx @@ -1,8 +1,7 @@ import { Gallery, GalleryItem } from '@patternfly/react-core'; import React, { memo } from 'react'; -import { IPluginPanelProps, PluginCard, PluginOptionsMissing } from '@kobsio/plugin-core'; -import { IReference } from '../../utils/interfaces'; +import { IPluginPanelProps, IReference, PluginCard, PluginOptionsMissing } from '@kobsio/plugin-core'; import PanelItem from './PanelItem'; interface IPanelProps extends IPluginPanelProps { diff --git a/plugins/dashboards/src/components/panel/PanelItem.tsx b/plugins/dashboards/src/components/panel/PanelItem.tsx index 2c51c0a7c..efea8a03f 100644 --- a/plugins/dashboards/src/components/panel/PanelItem.tsx +++ b/plugins/dashboards/src/components/panel/PanelItem.tsx @@ -1,8 +1,7 @@ import { Card, CardBody, CardHeader, CardTitle } from '@patternfly/react-core'; import React from 'react'; -import { IPluginDefaults, LinkWrapper } from '@kobsio/plugin-core'; -import { IReference } from '../../utils/interfaces'; +import { IPluginDefaults, IReference, LinkWrapper } from '@kobsio/plugin-core'; interface IPanelItemProps { defaults: IPluginDefaults; diff --git a/plugins/dashboards/src/index.ts b/plugins/dashboards/src/index.ts index 878955f7d..af0670b50 100644 --- a/plugins/dashboards/src/index.ts +++ b/plugins/dashboards/src/index.ts @@ -4,7 +4,6 @@ import './assets/dashboards.css'; import icon from './assets/icon.png'; -import { IPlugin as IPluginInternal, IReference } from './utils/interfaces'; import Page from './components/page/Page'; import Panel from './components/panel/Panel'; @@ -19,5 +18,3 @@ const dashboardsPlugin: IPluginComponents = { export default dashboardsPlugin; export * from './components/dashboards/DashboardsWrapper'; -export type IDashboardReference = IReference; -export type IPlugin = IPluginInternal; diff --git a/plugins/dashboards/src/utils/dashboard.ts b/plugins/dashboards/src/utils/dashboard.ts index 2d16a0d28..1cb6a1360 100644 --- a/plugins/dashboards/src/utils/dashboard.ts +++ b/plugins/dashboards/src/utils/dashboard.ts @@ -1,7 +1,7 @@ import { gridSpans } from '@patternfly/react-core'; -import { IDashboard, IDashboardsOptions, IPlaceholders, IReference, IVariableValues } from './interfaces'; -import { IPluginDefaults } from '@kobsio/plugin-core'; +import { IDashboard, IPlaceholders, IPluginDefaults, IReference } from '@kobsio/plugin-core'; +import { IDashboardsOptions, IVariableValues } from './interfaces'; // toGridSpans is used to convert the provided col and row span value to the corresponding gridSpans value, so that it // can be used within the Patternfly Grid component. The function requires a default value which is 12 for columns and diff --git a/plugins/dashboards/src/utils/interfaces.ts b/plugins/dashboards/src/utils/interfaces.ts index fef274b39..c5f7061ad 100644 --- a/plugins/dashboards/src/utils/interfaces.ts +++ b/plugins/dashboards/src/utils/interfaces.ts @@ -1,70 +1,4 @@ -// IDashboard is the interface for the Dashboards CR, like it is implemented in the Go code. In contrast to the Go -// implementation we are sure that the cluster, namespace and name for the dashboard is set, because the values are set -// each time a dashboard is retrieved from the Kubernetes API. -export interface IDashboard { - cluster: string; - namespace: string; - name: string; - title: string; - description?: string; - placeholders?: IPlaceholder[]; - variables?: IVariable[]; - rows: IRow[]; -} - -export interface IPlaceholder { - name: string; - description?: string; -} - -export interface IVariable { - name: string; - label?: string; - hide?: boolean; - plugin: IPlugin; -} - -export interface IRow { - title?: string; - description?: string; - size?: number; - panels: IPanel[]; -} - -export interface IPanel { - title: string; - description?: string; - colSpan?: number; - rowSpan?: number; - plugin: IPlugin; -} - -export interface IPlugin { - name: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - options?: any; -} - -// IReference is the interface for a dashboard reference in the Team or Application CR. If the cluster or namespace is -// not specified in the reference we assume the dashboard is in the same namespace as the team or application. -export interface IReference { - cluster?: string; - namespace?: string; - name?: string; - title: string; - description?: string; - placeholders?: IPlaceholders; - inline?: IReferenceInline; -} - -export interface IPlaceholders { - [key: string]: string; -} - -export interface IReferenceInline { - variables?: IVariable[]; - rows: IRow[]; -} +import { IVariable } from '@kobsio/plugin-core'; // IVariableValues is an extension of the IVariable interface. It contains the additional fields for the selected // variable value and all possible variable values. diff --git a/plugins/resources/src/components/panel/details/Dashboards.tsx b/plugins/resources/src/components/panel/details/Dashboards.tsx index f103f869f..122f63a3d 100644 --- a/plugins/resources/src/components/panel/details/Dashboards.tsx +++ b/plugins/resources/src/components/panel/details/Dashboards.tsx @@ -3,12 +3,13 @@ import { IRow } from '@patternfly/react-table'; import { JSONPath } from 'jsonpath-plus'; import React from 'react'; -import { DashboardsWrapper, IDashboardReference } from '@kobsio/plugin-dashboards'; +import { DashboardsWrapper } from '@kobsio/plugin-dashboards'; +import { IReference } from '@kobsio/plugin-core'; // getDashboards parses the kobs.io/dashboards annotation of a Kubernetes resources and returns all provided dashboards. // Before we are returning the dashboards we are checking all the provided placeholder and if one of the placeholders // uses an JSONPath we are replacing it with the correct value. -const getDashboards = (resource: IRow): IDashboardReference[] | undefined => { +const getDashboards = (resource: IRow): IReference[] | undefined => { try { if ( resource.props && @@ -16,7 +17,7 @@ const getDashboards = (resource: IRow): IDashboardReference[] | undefined => { resource.props.metadata.annotations && resource.props.metadata.annotations['kobs.io/dashboards'] ) { - const dashboards: IDashboardReference[] = JSON.parse( + const dashboards: IReference[] = JSON.parse( resource.props.metadata.annotations['kobs.io/dashboards'], resource.props, ); diff --git a/plugins/teams/src/components/home/Home.tsx b/plugins/teams/src/components/home/Home.tsx index 6a88b22fb..e2c9f60a3 100644 --- a/plugins/teams/src/components/home/Home.tsx +++ b/plugins/teams/src/components/home/Home.tsx @@ -15,8 +15,7 @@ import { import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; -import { IPluginPageProps, useDebounce } from '@kobsio/plugin-core'; -import { ITeam } from '../../utils/interfaces'; +import { IPluginPageProps, ITeam, useDebounce } from '@kobsio/plugin-core'; import TeamsItem from '../page/TeamsItem'; const Home: React.FunctionComponent = () => { diff --git a/plugins/teams/src/components/page/Team.tsx b/plugins/teams/src/components/page/Team.tsx index 14c33c739..2a9e9dbf9 100644 --- a/plugins/teams/src/components/page/Team.tsx +++ b/plugins/teams/src/components/page/Team.tsx @@ -16,9 +16,8 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; import { useHistory, useParams } from 'react-router-dom'; -import { ExternalLink, Title } from '@kobsio/plugin-core'; +import { ExternalLink, ITeam, Title } from '@kobsio/plugin-core'; import { DashboardsWrapper } from '@kobsio/plugin-dashboards'; -import { ITeam } from '../../utils/interfaces'; interface ITeamParams { cluster: string; diff --git a/plugins/teams/src/components/page/Teams.tsx b/plugins/teams/src/components/page/Teams.tsx index b6ac10766..7a2058c01 100644 --- a/plugins/teams/src/components/page/Teams.tsx +++ b/plugins/teams/src/components/page/Teams.tsx @@ -16,7 +16,7 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React from 'react'; import { useHistory } from 'react-router-dom'; -import { ITeam } from '../../utils/interfaces'; +import { ITeam } from '@kobsio/plugin-core'; import TeamsItem from './TeamsItem'; export interface ITeamsProps { diff --git a/plugins/teams/src/components/panel/Teams.tsx b/plugins/teams/src/components/panel/Teams.tsx index 2f9a24138..9b24814af 100644 --- a/plugins/teams/src/components/panel/Teams.tsx +++ b/plugins/teams/src/components/panel/Teams.tsx @@ -2,7 +2,7 @@ import { Alert, AlertActionLink, AlertVariant, Gallery, GalleryItem, Spinner } f import { QueryObserverResult, useQuery } from 'react-query'; import React from 'react'; -import { ITeam } from '../../utils/interfaces'; +import { ITeam } from '@kobsio/plugin-core'; import TeamsItem from '../page/TeamsItem'; // The Teams component is used to load all teams within the teams panel component. It is very similar to the Teams diff --git a/plugins/teams/src/index.ts b/plugins/teams/src/index.ts index 300c363ab..0134150dd 100644 --- a/plugins/teams/src/index.ts +++ b/plugins/teams/src/index.ts @@ -6,7 +6,6 @@ import Home from './components/home/Home'; import Page from './components/page/Page'; import Panel from './components/panel/Panel'; -import { ITeam } from './utils/interfaces'; import TeamsItem from './components/page/TeamsItem'; const teamsPlugin: IPluginComponents = { @@ -21,4 +20,3 @@ const teamsPlugin: IPluginComponents = { export default teamsPlugin; export { TeamsItem }; -export type ITeamTeam = ITeam; diff --git a/plugins/teams/src/utils/interfaces.ts b/plugins/teams/src/utils/interfaces.ts deleted file mode 100644 index b249aece3..000000000 --- a/plugins/teams/src/utils/interfaces.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IDashboardReference } from '@kobsio/plugin-dashboards'; - -// ITeam is the interface for a Team CR. The interface must implement the same fields as the Teams CRD. the only -// different is that we can be sure that the cluster, namespace and name of a team is always present in the frontend, -// because it will be set when a team is retrieved from the Kubernetes API. -export interface ITeam { - cluster: string; - namespace: string; - name: string; - description?: string; - links?: ILink[]; - logo?: string; - dashboards?: IDashboardReference[]; -} - -export interface ILink { - title: string; - link: string; -} diff --git a/plugins/users/src/components/home/Home.tsx b/plugins/users/src/components/home/Home.tsx index a6767e629..c71a1c2a7 100644 --- a/plugins/users/src/components/home/Home.tsx +++ b/plugins/users/src/components/home/Home.tsx @@ -15,14 +15,14 @@ import { import { QueryObserverResult, useQuery } from 'react-query'; import React, { useState } from 'react'; -import { IAuthProfile, IPluginPageProps, useDebounce } from '@kobsio/plugin-core'; +import { IPluginPageProps, IUser, useDebounce } from '@kobsio/plugin-core'; import UsersItem from '../page/UsersItem'; const Home: React.FunctionComponent = () => { const [searchTerm, setSearchTerm] = useState(''); const debouncedSearchTerm = useDebounce(searchTerm, 500); - const { isError, isLoading, error, data, refetch } = useQuery(['users/users'], async () => { + const { isError, isLoading, error, data, refetch } = useQuery(['users/users'], async () => { try { const response = await fetch(`/api/plugins/users/users`, { method: 'get' }); const json = await response.json(); @@ -56,7 +56,7 @@ const Home: React.FunctionComponent = () => { title="Could not get users" actionLinks={ - > => refetch()}> + > => refetch()}> Retry diff --git a/plugins/users/src/components/page/Teams.tsx b/plugins/users/src/components/page/Teams.tsx index b192562be..973f457eb 100644 --- a/plugins/users/src/components/page/Teams.tsx +++ b/plugins/users/src/components/page/Teams.tsx @@ -2,15 +2,15 @@ import { Gallery, GalleryItem, PageSection, PageSectionVariants } from '@pattern import React from 'react'; import { useQuery } from 'react-query'; -import { ITeamTeam, TeamsItem } from '@kobsio/plugin-teams'; -import { IAuthProfile } from '@kobsio/plugin-core'; +import { ITeam, IUser } from '@kobsio/plugin-core'; +import { TeamsItem } from '@kobsio/plugin-teams'; export interface ITeamsProps { - user: IAuthProfile; + user: IUser; } const Teams: React.FunctionComponent = ({ user }: ITeamsProps) => { - const { isError, isLoading, data } = useQuery(['users/teams', user], async () => { + const { isError, isLoading, data } = useQuery(['users/teams', user], async () => { try { const response = await fetch(`/api/plugins/users/teams?cluster=${user.cluster}&namespace=${user.namespace}`, { body: JSON.stringify({ diff --git a/plugins/users/src/components/page/User.tsx b/plugins/users/src/components/page/User.tsx index d93daaaad..1e87fdc18 100644 --- a/plugins/users/src/components/page/User.tsx +++ b/plugins/users/src/components/page/User.tsx @@ -15,7 +15,7 @@ import { useHistory, useParams } from 'react-router-dom'; import React from 'react'; import ReactMarkdown from 'react-markdown'; -import { IAuthProfile, getGravatarImageUrl } from '@kobsio/plugin-core'; +import { IUser, getGravatarImageUrl } from '@kobsio/plugin-core'; import Teams from './Teams'; interface IUserParams { @@ -30,7 +30,7 @@ const User: React.FunctionComponent = () => { const history = useHistory(); const params = useParams(); - const { isError, isLoading, error, data, refetch } = useQuery( + const { isError, isLoading, error, data, refetch } = useQuery( ['users/user', params.cluster, params.namespace, params.name], async () => { try { @@ -72,7 +72,7 @@ const User: React.FunctionComponent = () => { history.push('/')}>Home history.push('/users')}>Users - > => refetch()}> + > => refetch()}> Retry diff --git a/plugins/users/src/components/page/Users.tsx b/plugins/users/src/components/page/Users.tsx index c4969d374..dc6a86501 100644 --- a/plugins/users/src/components/page/Users.tsx +++ b/plugins/users/src/components/page/Users.tsx @@ -16,7 +16,7 @@ import { QueryObserverResult, useQuery } from 'react-query'; import React from 'react'; import { useHistory } from 'react-router-dom'; -import { IAuthProfile } from '@kobsio/plugin-core'; +import { IUser } from '@kobsio/plugin-core'; import UsersItem from './UsersItem'; export interface IUsersProps { @@ -29,7 +29,7 @@ export interface IUsersProps { const Users: React.FunctionComponent = ({ displayName, description }: IUsersProps) => { const history = useHistory(); - const { isError, isLoading, error, data, refetch } = useQuery(['users/users'], async () => { + const { isError, isLoading, error, data, refetch } = useQuery(['users/users'], async () => { try { const response = await fetch(`/api/plugins/users/users`, { method: 'get' }); const json = await response.json(); @@ -72,7 +72,7 @@ const Users: React.FunctionComponent = ({ displayName, description actionLinks={ history.push('/')}>Home - > => refetch()}> + > => refetch()}> Retry diff --git a/plugins/users/src/components/panel/Users.tsx b/plugins/users/src/components/panel/Users.tsx index 9edc951be..0dc507f07 100644 --- a/plugins/users/src/components/panel/Users.tsx +++ b/plugins/users/src/components/panel/Users.tsx @@ -2,7 +2,7 @@ import { Alert, AlertActionLink, AlertVariant, Gallery, GalleryItem, Spinner } f import { QueryObserverResult, useQuery } from 'react-query'; import React from 'react'; -import { IAuthProfile } from '@kobsio/plugin-core'; +import { IUser } from '@kobsio/plugin-core'; import UsersItem from '../page/UsersItem'; interface IUsersProps { @@ -13,7 +13,7 @@ interface IUsersProps { // The Users component is used to load all users for the specified team. const Users: React.FunctionComponent = ({ cluster, namespace, name }: IUsersProps) => { - const { isError, isLoading, error, data, refetch } = useQuery( + const { isError, isLoading, error, data, refetch } = useQuery( ['users/team', cluster, namespace, name], async () => { try { @@ -52,7 +52,7 @@ const Users: React.FunctionComponent = ({ cluster, namespace, name title="Could not get users" actionLinks={ - > => refetch()}> + > => refetch()}> Retry diff --git a/plugins/users/src/utils/interfaces.ts b/plugins/users/src/utils/interfaces.ts index 0afd8e9f7..f71ebd606 100644 --- a/plugins/users/src/utils/interfaces.ts +++ b/plugins/users/src/utils/interfaces.ts @@ -1,3 +1,5 @@ +// IPanelOptions is the interface for the options for a users panel used within a dashboard. It contains all required +// fields to reference a team. export interface IPanelOptions { cluster?: string; namespace?: string;