Skip to content

Commit

Permalink
Organization renaming, deleting and one-click email unsubscribe (#885)
Browse files Browse the repository at this point in the history
* Added the org settings page to the sidebar

* Added loading states when renaming/deleting projects

* Don’t show deleted orgs in the app

* The actual db migration file

* The Org settings page with the actions working

* Don’t remove org members, just leave them

* Don’t show invites from orgs that are deleted

* Allow disabling IntegrationConnections

* Don’t refresh IntegrationConnections that are disabled

* Set all the integrations as disabled

* Updated the unsubscribe checkbox text

* Unsubscribe route

* Use the magic link secret, not the encryption key. Also make the error message more vague

* Only members of the org or project can rename them

* Don’t throw an error if the connection can’t be refreshed, return undefined instead
  • Loading branch information
matt-aitken committed Feb 7, 2024
1 parent 29edcd3 commit 336029b
Show file tree
Hide file tree
Showing 13 changed files with 538 additions and 11 deletions.
8 changes: 8 additions & 0 deletions apps/webapp/app/components/navigation/SideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
organizationBillingPath,
organizationIntegrationsPath,
organizationPath,
organizationSettingsPath,
organizationTeamPath,
personalAccessTokensPath,
projectEnvironmentsPath,
Expand Down Expand Up @@ -209,6 +210,13 @@ export function SideMenu({ user, project, organization, organizations }: SideMen
iconColor="text-green-600"
data-action="usage & billing"
/>
<SideMenuItem
name="Organization settings"
icon="settings"
iconColor="text-teal-500"
to={organizationSettingsPath(organization)}
data-action="organization-settings"
/>
</div>
</div>
<div className="flex flex-col gap-1 border-t border-border p-1">
Expand Down
3 changes: 3 additions & 0 deletions apps/webapp/app/models/member.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ export async function getUsersInvites({ email }: { email: string }) {
return await prisma.orgMemberInvite.findMany({
where: {
email,
organization: {
deletedAt: null,
},
},
include: {
organization: true,
Expand Down
3 changes: 2 additions & 1 deletion apps/webapp/app/presenters/OrganizationsPresenter.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class OrganizationsPresenter {

async #getOrganizations(userId: string) {
const orgs = await this.#prismaClient.organization.findMany({
where: { members: { some: { userId } } },
where: { members: { some: { userId } }, deletedAt: null },
orderBy: { createdAt: "desc" },
select: {
id: true,
Expand Down Expand Up @@ -245,6 +245,7 @@ export class OrganizationsPresenter {
where: {
deletedAt: null,
organization: {
deletedAt: null,
slug: organizationSlug,
members: { some: { userId } },
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { conform, useForm } from "@conform-to/react";
import { parse } from "@conform-to/zod";
import { Form, useActionData } from "@remix-run/react";
import { Form, useActionData, useNavigation } from "@remix-run/react";
import { ActionFunction, json } from "@remix-run/server-runtime";
import { redirect } from "remix-typedjson";
import { r } from "tar";
import { z } from "zod";
import { InlineCode } from "~/components/code/InlineCode";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
Expand All @@ -28,7 +27,7 @@ import {
import { DeleteProjectService } from "~/services/deleteProject.server";
import { logger } from "~/services/logger.server";
import { requireUserId } from "~/services/session.server";
import { organizationPath, projectPath, projectSettingsPath } from "~/utils/pathBuilder";
import { organizationPath, projectPath } from "~/utils/pathBuilder";

export function createSchema(
constraints: {
Expand Down Expand Up @@ -90,6 +89,13 @@ export const action: ActionFunction = async ({ request, params }) => {
await prisma.project.update({
where: {
slug: projectParam,
organization: {
members: {
some: {
userId,
},
},
},
},
data: {
name: submission.value.projectName,
Expand Down Expand Up @@ -130,9 +136,9 @@ export const action: ActionFunction = async ({ request, params }) => {
};

export default function Page() {
const organization = useOrganization();
const project = useProject();
const lastSubmission = useActionData();
const navigation = useNavigation();

const [renameForm, { projectName }] = useForm({
id: "rename-project",
Expand Down Expand Up @@ -161,6 +167,14 @@ export default function Page() {
},
});

const isRenameLoading =
navigation.formData?.get("action") === "rename" &&
(navigation.state === "submitting" || navigation.state === "loading");

const isDeleteLoading =
navigation.formData?.get("action") === "delete" &&
(navigation.state === "submitting" || navigation.state === "loading");

return (
<PageContainer>
<PageHeader>
Expand Down Expand Up @@ -188,7 +202,12 @@ export default function Page() {
</InputGroup>
<FormButtons
confirmButton={
<Button type="submit" variant={"primary/small"}>
<Button
type="submit"
variant={"primary/small"}
disabled={isRenameLoading}
LeadingIcon={isRenameLoading ? "spinner-white" : undefined}
>
Rename project
</Button>
}
Expand Down Expand Up @@ -227,8 +246,9 @@ export default function Page() {
<Button
type="submit"
variant={"danger/small"}
LeadingIcon="trash-can"
LeadingIcon={isDeleteLoading ? "spinner-white" : "trash-can"}
leadingIconClassName="text-white"
disabled={isDeleteLoading}
>
Delete project
</Button>
Expand Down
Loading

0 comments on commit 336029b

Please sign in to comment.