Commit d0e23af2 by Tobias Skarhed Committed by GitHub

Angular/Forms migration: Orgs list (#23821)

* Create new components

* Fix async issues

* Remove comments

* Update public/app/features/admin/AdminOrgsTable.tsx

* Update public/app/features/admin/AdminListOrgsPage.tsx

* Update public/app/features/admin/AdminListOrgsPage.tsx

* Remove angular code

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
parent b09b49fb
import { getBackendSrv } from '@grafana/runtime';
import { NavModelSrv } from 'app/core/core';
import { Scope, CoreEvents, AppEventEmitter } from 'app/types';
import { promiseToDigest } from 'app/core/utils/promiseToDigest';
export default class AdminListOrgsCtrl {
/** @ngInject */
constructor($scope: Scope & AppEventEmitter, navModelSrv: NavModelSrv) {
$scope.init = async () => {
$scope.navModel = navModelSrv.getNav('admin', 'global-orgs', 0);
await $scope.getOrgs();
};
$scope.getOrgs = async () => {
const orgs = await promiseToDigest($scope)(getBackendSrv().get('/api/orgs'));
$scope.orgs = orgs;
};
$scope.deleteOrg = (org: any) => {
$scope.appEvent(CoreEvents.showConfirmModal, {
title: 'Delete',
text: `Do you want to delete organization ${org.name}?`,
text2: 'All dashboards for this organization will be removed!',
icon: 'trash-alt',
yesText: 'Delete',
onConfirm: async () => {
await getBackendSrv().delete('/api/orgs/' + org.id);
await $scope.getOrgs();
},
});
};
$scope.init();
}
}
import React, { FC, useEffect } from 'react';
import { getNavModel } from 'app/core/selectors/navModel';
import Page from 'app/core/components/Page/Page';
import { useSelector } from 'react-redux';
import { StoreState } from 'app/types/store';
import { LinkButton } from '@grafana/ui';
import { getBackendSrv } from '@grafana/runtime';
import { AdminOrgsTable } from './AdminOrgsTable';
import useAsyncFn from 'react-use/lib/useAsyncFn';
const deleteOrg = async (orgId: number) => {
return await getBackendSrv().delete('/api/orgs/' + orgId);
};
const getOrgs = async () => {
return await getBackendSrv().get('/api/orgs');
};
export const AdminListOrgsPages: FC = () => {
const navIndex = useSelector((state: StoreState) => state.navIndex);
const navModel = getNavModel(navIndex, 'global-orgs');
const [state, fetchOrgs] = useAsyncFn(async () => await getOrgs(), []);
useEffect(() => {
fetchOrgs();
}, []);
return (
<Page navModel={navModel}>
<Page.Contents>
<>
<div className="page-action-bar">
<div className="page-action-bar__spacer"></div>
<LinkButton icon="plus" href="org/new">
New org
</LinkButton>
</div>
{state.loading && 'Fetching organizations'}
{state.error}
{state.value && (
<AdminOrgsTable
orgs={state.value}
onDelete={orgId => {
deleteOrg(orgId);
fetchOrgs();
}}
/>
)}
</>
</Page.Contents>
</Page>
);
};
export default AdminListOrgsPages;
import React, { FC, useState } from 'react';
import { Organization } from 'app/types';
import { Button, ConfirmModal } from '@grafana/ui';
interface Props {
orgs: Organization[];
onDelete: (orgId: number) => void;
}
export const AdminOrgsTable: FC<Props> = ({ orgs, onDelete }) => {
const [deleteOrg, setDeleteOrg] = useState<Organization>();
return (
<table className="filter-table form-inline filter-table--hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th style={{ width: '1%' }}></th>
</tr>
</thead>
<tbody>
{orgs.map(org => (
<tr key={`${org.id}-${org.name}`}>
<td className="link-td">
<a href={`admin/orgs/edit/${org.id}`}>{org.id}</a>
</td>
<td className="link-td">
<a href={`admin/orgs/edit/${org.id}`}>{org.name}</a>
</td>
<td className="text-right">
<Button variant="destructive" size="sm" icon="times" onClick={() => setDeleteOrg(org)} />
</td>
</tr>
))}
</tbody>
{deleteOrg && (
<ConfirmModal
isOpen
icon="trash-alt"
title="Delete"
body={
<div>
Are you sure you want to delete `${deleteOrg.name}`?
<br /> <small>All dashboards for this organization will be removed!</small>
</div>
}
confirmText="Delete"
onDismiss={() => setDeleteOrg(null)}
onConfirm={() => {
onDelete(deleteOrg.id);
setDeleteOrg(null);
}}
/>
)}
</table>
);
};
import AdminEditUserCtrl from './AdminEditUserCtrl';
import AdminListOrgsCtrl from './AdminListOrgsCtrl';
import AdminEditOrgCtrl from './AdminEditOrgCtrl';
import coreModule from 'app/core/core_module';
......@@ -15,6 +14,5 @@ class AdminHomeCtrl {
}
coreModule.controller('AdminEditUserCtrl', AdminEditUserCtrl);
coreModule.controller('AdminListOrgsCtrl', AdminListOrgsCtrl);
coreModule.controller('AdminEditOrgCtrl', AdminEditOrgCtrl);
coreModule.controller('AdminHomeCtrl', AdminHomeCtrl);
<page-header model="navModel"></page-header>
<div class="page-container page-body">
<div class="page-action-bar">
<div class="page-action-bar__spacer"></div>
<a class="page-header__cta btn btn-primary" href="org/new">
New org
</a>
</div>
<table class="filter-table form-inline filter-table--hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th style="width:1%"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="org in orgs">
<td class="link-td">
<a href="admin/orgs/edit/{{org.id}}">
{{org.id}}
</a>
</td>
<td class="link-td">
<a href="admin/orgs/edit/{{org.id}}">
{{org.name}}
</a>
</td>
<td class="text-right">
<a ng-click="deleteOrg(org)" class="btn btn-danger btn-small">
<icon name="'times'" size="sm" style="margin-bottom: 0;"></icon>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<footer />
......@@ -344,9 +344,11 @@ export function setupAngularRoutes($routeProvider: route.IRouteProvider, $locati
},
})
.when('/admin/orgs', {
templateUrl: 'public/app/features/admin/partials/orgs.html',
controller: 'AdminListOrgsCtrl',
controllerAs: 'ctrl',
template: '<react-container />',
resolve: {
component: () =>
SafeDynamicImport(import(/* webpackChunkName: "AdminListOrgsPage" */ 'app/features/admin/AdminListOrgsPage')),
},
})
.when('/admin/orgs/edit/:id', {
template: '<react-container />',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment