diff --git a/src/components/dialog/GlobalDialog.vue b/src/components/dialog/GlobalDialog.vue index afc056d61..bb3b98478 100644 --- a/src/components/dialog/GlobalDialog.vue +++ b/src/components/dialog/GlobalDialog.vue @@ -4,7 +4,12 @@ v-for="item in dialogStore.dialogStack" :key="item.key" v-model:visible="item.visible" - class="global-dialog" + :class="[ + 'global-dialog', + item.key === 'global-settings' && teamWorkspacesEnabled + ? 'settings-dialog-workspace' + : '' + ]" v-bind="item.dialogComponentProps" :pt="item.dialogComponentProps.pt" :aria-labelledby="item.key" @@ -38,8 +43,13 @@ @@ -55,4 +65,27 @@ const dialogStore = useDialogStore() @apply p-2 2xl:p-[var(--p-dialog-content-padding)]; @apply pt-0; } + +/* Workspace mode: wider settings dialog */ +.settings-dialog-workspace { + width: 100%; + max-width: 1440px; +} + +.settings-dialog-workspace .p-dialog-content { + width: 100%; +} + +.manager-dialog { + height: 80vh; + max-width: 1724px; + max-height: 1026px; +} + +@media (min-width: 3000px) { + .manager-dialog { + max-width: 2200px; + max-height: 1320px; + } +} diff --git a/src/components/dialog/content/setting/MembersPanelContent.vue b/src/components/dialog/content/setting/MembersPanelContent.vue new file mode 100644 index 000000000..0056ce2b5 --- /dev/null +++ b/src/components/dialog/content/setting/MembersPanelContent.vue @@ -0,0 +1,483 @@ + + + diff --git a/src/components/dialog/content/setting/WorkspacePanel.vue b/src/components/dialog/content/setting/WorkspacePanel.vue new file mode 100644 index 000000000..aff8f3733 --- /dev/null +++ b/src/components/dialog/content/setting/WorkspacePanel.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/components/dialog/content/setting/WorkspacePanelContent.vue b/src/components/dialog/content/setting/WorkspacePanelContent.vue new file mode 100644 index 000000000..59128ef97 --- /dev/null +++ b/src/components/dialog/content/setting/WorkspacePanelContent.vue @@ -0,0 +1,201 @@ + + + diff --git a/src/components/dialog/content/setting/WorkspaceSidebarItem.vue b/src/components/dialog/content/setting/WorkspaceSidebarItem.vue new file mode 100644 index 000000000..cab92c7a8 --- /dev/null +++ b/src/components/dialog/content/setting/WorkspaceSidebarItem.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/components/toast/WorkspaceCreatedToast.vue b/src/components/toast/WorkspaceCreatedToast.vue new file mode 100644 index 000000000..16f9189db --- /dev/null +++ b/src/components/toast/WorkspaceCreatedToast.vue @@ -0,0 +1,44 @@ + + + diff --git a/src/components/topbar/CurrentUserPopoverWorkspace.vue b/src/components/topbar/CurrentUserPopoverWorkspace.vue new file mode 100644 index 000000000..227d7098b --- /dev/null +++ b/src/components/topbar/CurrentUserPopoverWorkspace.vue @@ -0,0 +1,347 @@ + + + + diff --git a/src/components/topbar/WorkspaceSwitcherPopover.vue b/src/components/topbar/WorkspaceSwitcherPopover.vue new file mode 100644 index 000000000..68d6941db --- /dev/null +++ b/src/components/topbar/WorkspaceSwitcherPopover.vue @@ -0,0 +1,192 @@ + + + diff --git a/src/locales/en/main.json b/src/locales/en/main.json index fa557ee96..bcdc9fabc 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1,6 +1,7 @@ { "g": { "user": "User", + "you": "You", "currentUser": "Current user", "empty": "Empty", "noWorkflowsFound": "No workflows found.", @@ -1264,7 +1265,10 @@ "Scene": "Scene", "3D": "3D", "Light": "Light", - "User": "User", + "Profile": "Profile", + "Workspace": "Workspace", + "WorkspacePlan": "Plan & Credits", + "WorkspaceMembers": "Members", "Credits": "Credits", "API Nodes": "API Nodes", "Notification Preferences": "Notification Preferences", @@ -1997,6 +2001,8 @@ "renewsDate": "Renews {date}", "expiresDate": "Expires {date}", "manageSubscription": "Manage subscription", + "managePayment": "Manage Payment", + "cancelSubscription": "Cancel Subscription", "partnerNodesBalance": "\"Partner Nodes\" Credit Balance", "partnerNodesDescription": "For running commercial/proprietary models", "totalCredits": "Total credits", @@ -2051,6 +2057,9 @@ "subscribeToRunFull": "Subscribe to Run", "subscribeNow": "Subscribe Now", "subscribeToComfyCloud": "Subscribe to Comfy Cloud", + "workspaceNotSubscribed": "This workspace is not on a subscription", + "subscriptionRequiredMessage": "A subscription is required for members to run workflows on Cloud", + "contactOwnerToSubscribe": "Contact the workspace owner to subscribe", "description": "Choose the best plan for you", "haveQuestions": "Have questions or wondering about enterprise?", "contactUs": "Contact us", @@ -2086,12 +2095,132 @@ "userSettings": { "title": "My Account Settings", "accountSettings": "Account settings", + "workspaceSettings": "Workspace settings", "name": "Name", "email": "Email", "provider": "Sign-in Provider", "notSet": "Not set", "updatePassword": "Update Password" }, + "workspacePanel": { + "invite": "Invite", + "inviteMember": "Invite member", + "inviteLimitReached": "You've reached the maximum of 50 members", + "tabs": { + "dashboard": "Dashboard", + "planCredits": "Plan & Credits", + "membersCount": "Members ({count})" + }, + "dashboard": { + "placeholder": "Dashboard workspace settings" + }, + "members": { + "membersCount": "{count}/50 Members", + "pendingInvitesCount": "{count} pending invite | {count} pending invites", + "tabs": { + "active": "Active", + "pendingCount": "Pending ({count})" + }, + "columns": { + "inviteDate": "Invite date", + "expiryDate": "Expiry date", + "joinDate": "Join date" + }, + "actions": { + "copyLink": "Copy invite link", + "revokeInvite": "Revoke invite", + "removeMember": "Remove member" + }, + "noInvites": "No pending invites", + "noMembers": "No members", + "personalWorkspaceMessage": "You can't invite other members to your personal workspace right now. To add members to a workspace,", + "createNewWorkspace": "create a new one." + }, + "menu": { + "editWorkspace": "Edit workspace details", + "leaveWorkspace": "Leave Workspace", + "deleteWorkspace": "Delete Workspace", + "deleteWorkspaceDisabledTooltip": "Cancel your workspace's active subscription first" + }, + "editWorkspaceDialog": { + "title": "Edit workspace details", + "nameLabel": "Workspace name", + "save": "Save" + }, + "leaveDialog": { + "title": "Leave this workspace?", + "message": "You won't be able to join again unless you contact the workspace owner.", + "leave": "Leave" + }, + "deleteDialog": { + "title": "Delete this workspace?", + "message": "Any unused credits or unsaved assets will be lost. This action cannot be undone.", + "messageWithName": "Delete \"{name}\"? Any unused credits or unsaved assets will be lost. This action cannot be undone." + }, + "removeMemberDialog": { + "title": "Remove this member?", + "message": "This member will be removed from your workspace. Credits they've used will not be refunded.", + "remove": "Remove member" + }, + "revokeInviteDialog": { + "title": "Uninvite this person?", + "message": "This member won't be able to join your workspace anymore. Their invite link will be invalidated.", + "revoke": "Uninvite" + }, + "inviteMemberDialog": { + "title": "Invite a person to this workspace", + "message": "Create a shareable invite link to send to someone", + "placeholder": "Enter the person's email", + "createLink": "Create link", + "linkStep": { + "title": "Send this link to the person", + "message": "Make sure their account uses this email.", + "copyLink": "Copy Link", + "done": "Done" + }, + "linkCopied": "Copied", + "linkCopyFailed": "Failed to copy link" + }, + "createWorkspaceDialog": { + "title": "Create a new workspace", + "message": "Workspaces let members share a single credits pool. You'll become the owner after creating this.", + "nameLabel": "Workspace name*", + "namePlaceholder": "Enter workspace name", + "create": "Create" + }, + "toast": { + "workspaceCreated": { + "title": "Workspace created", + "message": "Subscribe to a plan, invite teammates, and start collaborating.", + "subscribe": "Subscribe" + }, + "workspaceUpdated": { + "title": "Workspace updated", + "message": "Workspace details have been saved." + }, + "workspaceDeleted": { + "title": "Workspace deleted", + "message": "The workspace has been permanently deleted." + }, + "workspaceLeft": { + "title": "Left workspace", + "message": "You have left the workspace." + }, + "failedToUpdateWorkspace": "Failed to update workspace", + "failedToCreateWorkspace": "Failed to create workspace", + "failedToDeleteWorkspace": "Failed to delete workspace", + "failedToLeaveWorkspace": "Failed to leave workspace", + "failedToFetchWorkspaces": "Failed to load workspaces" + } + }, + "workspaceSwitcher": { + "switchWorkspace": "Switch workspace", + "subscribe": "Subscribe", + "roleOwner": "Owner", + "roleMember": "Member", + "createWorkspace": "Create new workspace", + "maxWorkspacesReached": "You can only own 10 workspaces. Delete one to create a new one." + }, "selectionToolbox": { "executeButton": { "tooltip": "Execute to selected output nodes (Highlighted with orange border)", @@ -2608,7 +2737,10 @@ "unsavedChanges": { "title": "Unsaved Changes", "message": "You have unsaved changes. Do you want to discard them and switch workspaces?" - } + }, + "inviteAccepted": "Invite Accepted", + "addedToWorkspace": "You have been added to {workspaceName}", + "inviteFailed": "Failed to Accept Invite" }, "workspaceAuth": { "errors": { @@ -2619,4 +2751,4 @@ "tokenExchangeFailed": "Failed to authenticate with workspace: {error}" } } -} \ No newline at end of file +} diff --git a/src/platform/cloud/subscription/components/SubscriptionPanel.vue b/src/platform/cloud/subscription/components/SubscriptionPanel.vue index 7a521b504..e395cb7d1 100644 --- a/src/platform/cloud/subscription/components/SubscriptionPanel.vue +++ b/src/platform/cloud/subscription/components/SubscriptionPanel.vue @@ -17,208 +17,10 @@ -
-
-
-
-
-
- {{ subscriptionTierName }} -
-
- ${{ tierPrice }} - {{ - $t('subscription.perMonth') - }} -
-
- - -
-
- - - - - -
-
- -
-
-
-
- - -
-
- {{ $t('subscription.totalCredits') }} -
- -
- {{ totalCredits }} -
-
- - - - - - - - - - - - - -
- - {{ includedCreditsDisplay }} - - {{ creditsRemainingLabel }} -
- - {{ prepaidCredits }} - - {{ $t('subscription.creditsYouveAdded') }} -
- -
- - {{ $t('subscription.viewUsageHistory') }} - - -
-
-
-
- -
-
- {{ $t('subscription.yourPlanIncludes') }} -
- -
-
- - - {{ benefit.value }} - - - {{ benefit.label }} - -
-
-
-
-
- - - -
+ + + +
- - diff --git a/src/platform/cloud/subscription/components/SubscriptionPanelContentLegacy.vue b/src/platform/cloud/subscription/components/SubscriptionPanelContentLegacy.vue new file mode 100644 index 000000000..a6d5f063b --- /dev/null +++ b/src/platform/cloud/subscription/components/SubscriptionPanelContentLegacy.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/platform/cloud/subscription/components/SubscriptionPanelContentWorkspace.vue b/src/platform/cloud/subscription/components/SubscriptionPanelContentWorkspace.vue new file mode 100644 index 000000000..7605849e8 --- /dev/null +++ b/src/platform/cloud/subscription/components/SubscriptionPanelContentWorkspace.vue @@ -0,0 +1,435 @@ + + + + + diff --git a/src/platform/settings/components/SettingDialogContent.vue b/src/platform/settings/components/SettingDialogContent.vue index 13da10437..00d213004 100644 --- a/src/platform/settings/components/SettingDialogContent.vue +++ b/src/platform/settings/components/SettingDialogContent.vue @@ -1,6 +1,18 @@