diff --git a/packages/grafana-data/src/types/navModel.ts b/packages/grafana-data/src/types/navModel.ts index 7d23f222e14..ff6ca48f501 100644 --- a/packages/grafana-data/src/types/navModel.ts +++ b/packages/grafana-data/src/types/navModel.ts @@ -16,9 +16,21 @@ export interface NavModelItem { showOrgSwitcher?: boolean; } +/** + * Interface used to describe different kinds of page titles and page navigation. Navmodels are usually generated in the backend and stored in Redux. + */ export interface NavModel { + /** + * Main page. that wraps the navigation. Generate the `children` property generate tabs when used with the Page component. + */ main: NavModelItem; + /** + * This is the current active tab/navigation. + */ node: NavModelItem; + /** + * Describes breadcrumbs that are used in places such as data source settings., folder page and plugins page. + */ breadcrumbs?: NavModelItem[]; } diff --git a/public/app/features/org/NewOrgCtrl.ts b/public/app/features/org/NewOrgCtrl.ts deleted file mode 100644 index 0694873c819..00000000000 --- a/public/app/features/org/NewOrgCtrl.ts +++ /dev/null @@ -1,26 +0,0 @@ -import angular from 'angular'; -import config from 'app/core/config'; -import { getBackendSrv } from '@grafana/runtime'; -import { NavModelSrv } from 'app/core/core'; - -export class NewOrgCtrl { - /** @ngInject */ - constructor($scope: any, $http: any, navModelSrv: NavModelSrv) { - $scope.navModel = navModelSrv.getNav('admin', 'global-orgs', 0); - $scope.newOrg = { name: '' }; - - $scope.createOrg = () => { - getBackendSrv() - .post('/api/orgs/', $scope.newOrg) - .then((result: any) => { - getBackendSrv() - .post('/api/user/using/' + result.orgId) - .then(() => { - window.location.href = config.appSubUrl + '/org'; - }); - }); - }; - } -} - -angular.module('grafana.controllers').controller('NewOrgCtrl', NewOrgCtrl); diff --git a/public/app/features/org/NewOrgPage.tsx b/public/app/features/org/NewOrgPage.tsx new file mode 100644 index 00000000000..9059ad10b16 --- /dev/null +++ b/public/app/features/org/NewOrgPage.tsx @@ -0,0 +1,85 @@ +import React, { FC } from 'react'; +import { getBackendSrv } from '@grafana/runtime'; +import Page from 'app/core/components/Page/Page'; +import { Forms } from '@grafana/ui'; +import { getConfig } from 'app/core/config'; +import { StoreState } from 'app/types'; +import { hot } from 'react-hot-loader'; +import { connect } from 'react-redux'; +import { NavModel } from '@grafana/data'; +import { getNavModel } from '../../core/selectors/navModel'; + +const createOrg = async (newOrg: { name: string }) => { + const result = await getBackendSrv().post('/api/orgs/', newOrg); + + await getBackendSrv().post('/api/user/using/' + result.orgId); + window.location.href = getConfig().appSubUrl + '/org'; +}; + +const validateOrg = async (orgName: string) => { + try { + await getBackendSrv().get(`api/orgs/name/${encodeURI(orgName)}`); + } catch (error) { + if (error.status === 404) { + error.isHandled = true; + return true; + } + return 'Something went wrong'; + } + return 'Organization already exists'; +}; + +interface PropsWithState { + navModel: NavModel; +} + +interface CreateOrgFormDTO { + name: string; +} + +export const NewOrgPage: FC = ({ navModel }) => { + return ( + + +

New Organization

+ +

+ Each organization contains their own dashboards, data sources and configuration, and cannot be shared between + orgs. While users may belong to more than one, multiple organization are most frequently used in multi-tenant + deployments.{' '} +

+ + onSubmit={createOrg}> + {({ register, errors }) => { + return ( + <> + + await validateOrg(orgName), + })} + /> + + Create + + ); + }} + +
+
+ ); +}; + +const mapStateToProps = (state: StoreState) => { + return { navModel: getNavModel(state.navIndex, 'global-orgs') }; +}; + +export default hot(module)(connect(mapStateToProps)(NewOrgPage)); diff --git a/public/app/features/org/all.ts b/public/app/features/org/all.ts index 92de5eba2aa..ecdaf0b7d55 100644 --- a/public/app/features/org/all.ts +++ b/public/app/features/org/all.ts @@ -1,2 +1 @@ import './SelectOrgCtrl'; -import './NewOrgCtrl'; diff --git a/public/app/features/org/partials/newOrg.html b/public/app/features/org/partials/newOrg.html deleted file mode 100644 index ce0645b6297..00000000000 --- a/public/app/features/org/partials/newOrg.html +++ /dev/null @@ -1,24 +0,0 @@ - - -
-

- New Organization -

- -

Each organization contains their own dashboards, data sources and configuration, and cannot be shared between orgs. While users may belong to more than one, multiple organization are most frequently used in multi-tenant deployments.

- -
-
-
- Org. name - -
-
-
- -
-
-
-
- -