fix: Organizations Admin improvements (#13656)
* Admin improvements * chore: improve spacing --------- Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Udit Takkar <udit222001@gmail.com>
This commit is contained in:
co-authored by
Udit Takkar
Udit Takkar
parent
bb48ccbad9
commit
bafa3c97ac
@@ -2195,7 +2195,7 @@
|
||||
"create_your_org_description": "Upgrade to Enterprise and receive a subdomain, unified billing, Insights, extensive whitelabeling and more",
|
||||
"other_payment_app_enabled": "You can only enable one payment app per event type",
|
||||
"admin_delete_organization_description": "<ul><li>Teams that are member of this organization will also be deleted along with their event-types</li><li>Users that were part of the organization will not be deleted and their event-types will also remain intact.</li><li>Usernames would be changed to allow them to exist outside the organization</li></ul>",
|
||||
"admin_delete_organization_title": "Delete organization?",
|
||||
"admin_delete_organization_title": "Delete {{organizationName}}?",
|
||||
"published": "Published",
|
||||
"unpublished": "Unpublished",
|
||||
"publish": "Publish",
|
||||
|
||||
@@ -73,7 +73,7 @@ function AdminOrgTable() {
|
||||
});
|
||||
};
|
||||
|
||||
const [orgToDelete, setOrgToDelete] = useState<number | null>(null);
|
||||
const [orgToDelete, setOrgToDelete] = useState<(typeof data)[number] | null>(null);
|
||||
return (
|
||||
<div>
|
||||
<Table>
|
||||
@@ -189,7 +189,7 @@ function AdminOrgTable() {
|
||||
id: "delete",
|
||||
label: t("delete"),
|
||||
onClick: () => {
|
||||
setOrgToDelete(org.id);
|
||||
setOrgToDelete(org);
|
||||
},
|
||||
icon: Trash,
|
||||
},
|
||||
@@ -202,12 +202,12 @@ function AdminOrgTable() {
|
||||
</Body>
|
||||
</Table>
|
||||
<DeleteOrgDialog
|
||||
orgId={orgToDelete}
|
||||
org={orgToDelete}
|
||||
onClose={() => setOrgToDelete(null)}
|
||||
onConfirm={() => {
|
||||
if (!orgToDelete) return;
|
||||
deleteMutation.mutate({
|
||||
orgId: orgToDelete,
|
||||
orgId: orgToDelete.id,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
@@ -232,28 +232,35 @@ AdminOrgList.getLayout = getLayout;
|
||||
export default AdminOrgList;
|
||||
|
||||
const DeleteOrgDialog = ({
|
||||
orgId,
|
||||
org,
|
||||
onConfirm,
|
||||
onClose,
|
||||
}: {
|
||||
orgId: number | null;
|
||||
org: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
onConfirm: () => void;
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const { t } = useLocale();
|
||||
|
||||
if (!org) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function -- noop
|
||||
<Dialog name="delete-user" open={!!orgId} onOpenChange={(open) => (open ? () => {} : onClose())}>
|
||||
<Dialog name="delete-user" open={!!org.id} onOpenChange={(open) => (open ? () => {} : onClose())}>
|
||||
<ConfirmationDialogContent
|
||||
title={t("admin_delete_organization_title")}
|
||||
title={t("admin_delete_organization_title", {
|
||||
organizationName: org.name,
|
||||
})}
|
||||
confirmBtnText={t("delete")}
|
||||
cancelBtnText={t("cancel")}
|
||||
variety="danger"
|
||||
onConfirm={onConfirm}>
|
||||
<Trans
|
||||
i18nKey="admin_delete_organization_description"
|
||||
components={{ li: <li />, ul: <ul className="ml-4 list-disc" /> }}>
|
||||
components={{ li: <li />, ul: <ul className="ml-4 mt-5 list-disc space-y-2" /> }}>
|
||||
<ul>
|
||||
<li>
|
||||
Teams that are member of this organization will also be deleted along with their event-types
|
||||
|
||||
@@ -80,9 +80,13 @@ export const deleteDnsRecord = async (domain: string) => {
|
||||
assertCloudflareEnvVars(process.env);
|
||||
|
||||
const dnsRecordToDelete = await getDnsRecordToDelete();
|
||||
await deleteDnsRecord(dnsRecordToDelete);
|
||||
if (dnsRecordToDelete) {
|
||||
await deleteDnsRecord(dnsRecordToDelete);
|
||||
log.info(`Deleted dns-record in Cloudflare: ${domain}`);
|
||||
} else {
|
||||
log.info(`CNAME not found in Cloudflare: ${domain}. Nothing to delete`);
|
||||
}
|
||||
|
||||
log.info(`Deleted dns-record in Cloudflare: ${domain}`);
|
||||
return true;
|
||||
|
||||
async function getDnsRecordToDelete() {
|
||||
@@ -134,7 +138,7 @@ export const deleteDnsRecord = async (domain: string) => {
|
||||
});
|
||||
}
|
||||
|
||||
return searchResult.result[0];
|
||||
return searchResult.result[0] as (typeof searchResult.result)[0] | null;
|
||||
}
|
||||
|
||||
async function deleteDnsRecord(dnsRecordToDelete: { id: string }) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { subdomainSuffix } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import logger from "@calcom/lib/logger";
|
||||
|
||||
import { deleteDnsRecord, addDnsRecord } from "./deploymentServices/cloudflare";
|
||||
import {
|
||||
@@ -6,6 +7,7 @@ import {
|
||||
createDomain as createVercelDomain,
|
||||
} from "./deploymentServices/vercel";
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["domainManager/organization"] });
|
||||
export const deleteDomain = async (slug: string) => {
|
||||
const domain = `${slug}.${subdomainSuffix()}`;
|
||||
// We must have some domain deleted
|
||||
@@ -22,6 +24,7 @@ export const deleteDomain = async (slug: string) => {
|
||||
isDnsRecordDeleted = await deleteDnsRecord(domain);
|
||||
}
|
||||
return isDomainDeleted && isDnsRecordDeleted;
|
||||
return false;
|
||||
};
|
||||
|
||||
export const createDomain = async (slug: string) => {
|
||||
@@ -48,6 +51,10 @@ export const renameDomain = async (oldSlug: string | null, newSlug: string) => {
|
||||
// First create new domain so that if it fails we still have the old domain
|
||||
await createDomain(newSlug);
|
||||
if (oldSlug) {
|
||||
await deleteDomain(oldSlug);
|
||||
try {
|
||||
await deleteDomain(oldSlug);
|
||||
} catch (e) {
|
||||
log.error(`renameDomain: Failed to delete old domain ${oldSlug}. Do a manual deletion if needed`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,7 +40,11 @@ export const adminDeleteHandler = async ({ input }: AdminDeleteOption) => {
|
||||
});
|
||||
|
||||
if (foundOrg.slug) {
|
||||
await deleteDomain(foundOrg.slug);
|
||||
try {
|
||||
await deleteDomain(foundOrg.slug);
|
||||
} catch (e) {
|
||||
log.error(`Failed to delete domain ${foundOrg.slug}. Do a manual deletion if needed`);
|
||||
}
|
||||
}
|
||||
|
||||
await renameUsersToAvoidUsernameConflicts(foundOrg.members.map((member) => member.user));
|
||||
|
||||
Reference in New Issue
Block a user