Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update server region metadata #3433

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions packages/frontend-2/components/settings/server/Regions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,24 @@
<div class="flex flex-col space-y-6">
<div class="flex flex-row-reverse">
<div v-tippy="disabledMessage">
<FormButton
:disabled="!canCreateRegion"
@click="isAddEditDialogOpen = true"
>
<FormButton :disabled="!canCreateRegion" @click="onCreate">
Create
</FormButton>
</div>
</div>
<SettingsServerRegionsTable :items="tableItems" />
<SettingsServerRegionsTable :items="tableItems" @edit="onEditRegion" />
</div>
</div>
<SettingsServerRegionsAddEditDialog
v-model="editModel"
v-model:open="isAddEditDialogOpen"
:available-region-keys="availableKeys"
/>
</section>
</template>
<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable'
import type { SettingsServerRegionsTable_ServerRegionItemFragment } from '~/lib/common/generated/gql/graphql'
import { graphql } from '~~/lib/common/generated/gql'

const isAddEditDialogOpen = ref(false)
Expand All @@ -45,6 +44,8 @@ const query = graphql(`
}
`)

const editModel = ref<SettingsServerRegionsTable_ServerRegionItemFragment>()

const pageFetchPolicy = usePageQueryStandardFetchPolicy()
const { result } = useQuery(query, undefined, () => ({
fetchPolicy: pageFetchPolicy.value
Expand All @@ -62,4 +63,14 @@ const disabledMessage = computed(() => {

return undefined
})

const onCreate = () => {
editModel.value = undefined
isAddEditDialogOpen.value = true
}

const onEditRegion = (item: SettingsServerRegionsTable_ServerRegionItemFragment) => {
editModel.value = item
isAddEditDialogOpen.value = true
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ import type { LayoutDialogButton } from '@speckle/ui-components'
import { graphql } from '~/lib/common/generated/gql'
import type { SettingsServerRegionsAddEditDialog_ServerRegionItemFragment } from '~/lib/common/generated/gql/graphql'
import { useForm } from 'vee-validate'
import { useCreateRegion } from '~/lib/multiregion/composables/management'
import {
useCreateRegion,
useUpdateRegion
} from '~/lib/multiregion/composables/management'
import { useMutationLoading } from '@vue/apollo-composable'

graphql(`
Expand All @@ -72,6 +75,7 @@ const open = defineModel<boolean>('open', { required: true })
const model = defineModel<DialogModel>()
const { handleSubmit, setValues } = useForm<DialogModel>()
const createRegion = useCreateRegion()
const updateRegion = useUpdateRegion()
const loading = useMutationLoading()

const dialogButtons = computed((): LayoutDialogButton[] => {
Expand All @@ -82,7 +86,7 @@ const dialogButtons = computed((): LayoutDialogButton[] => {
onClick: () => (open.value = false)
},
{
text: 'Create',
text: isEditMode.value ? 'Update' : 'Create',
props: {
submit: true,
disabled: loading.value
Expand All @@ -94,11 +98,15 @@ const dialogButtons = computed((): LayoutDialogButton[] => {
const isEditMode = computed(() => !!model.value)

const onSubmit = handleSubmit(async (values) => {
if (isEditMode.value) return // TODO:

const res = await createRegion({
input: values
const action = isEditMode.value ? updateRegion : createRegion
const res = await action({
input: {
key: values.key,
name: values.name,
description: values.description
}
})

if (res?.id) {
open.value = false
}
Expand All @@ -109,6 +117,8 @@ watch(
(newVal, oldVal) => {
if (newVal && newVal !== oldVal) {
setValues(newVal)
} else if (!newVal && oldVal) {
setValues({ name: '', description: '', key: '' })
}
},
{ immediate: true }
Expand Down
19 changes: 14 additions & 5 deletions packages/frontend-2/components/settings/server/regions/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,12 @@
<span class="text-foreground-2">{{ item.description }}</span>
</template>
<template #actions="{ item }">
<template v-if="true">
<!-- Hiding actions for now -->
&nbsp;
</template>
<LayoutMenu
v-else
v-model:open="showActionsMenu[item.id]"
:items="actionItems"
mount-menu-on-body
:menu-position="HorizontalDirection.Left"
@chosen="({ item: actionItem }) => onActionChosen(actionItem, item)"
>
<FormButton
:color="showActionsMenu[item.id] ? 'outline' : 'subtle'"
Expand Down Expand Up @@ -62,6 +58,10 @@ enum ActionTypes {
Edit = 'edit'
}

const emit = defineEmits<{
edit: [item: SettingsServerRegionsTable_ServerRegionItemFragment]
}>()

defineProps<{
items: SettingsServerRegionsTable_ServerRegionItemFragment[] | undefined
}>()
Expand All @@ -74,4 +74,13 @@ const actionItems: LayoutMenuItem[][] = [
const toggleMenu = (itemId: string) => {
showActionsMenu.value[itemId] = !showActionsMenu.value[itemId]
}

const onActionChosen = (
actionItem: LayoutMenuItem,
item: SettingsServerRegionsTable_ServerRegionItemFragment
) => {
if (actionItem.id === ActionTypes.Edit) {
emit('edit', item)
}
}
</script>
5 changes: 5 additions & 0 deletions packages/frontend-2/lib/common/generated/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ const documents = {
"\n subscription ProjectVersionGendoAIRenderCreated($id: String!, $versionId: String!) {\n projectVersionGendoAIRenderCreated(id: $id, versionId: $versionId) {\n id\n createdAt\n updatedAt\n status\n gendoGenerationId\n prompt\n camera\n }\n }\n": types.ProjectVersionGendoAiRenderCreatedDocument,
"\n subscription ProjectVersionGendoAIRenderUpdated($id: String!, $versionId: String!) {\n projectVersionGendoAIRenderUpdated(id: $id, versionId: $versionId) {\n id\n projectId\n modelId\n versionId\n createdAt\n updatedAt\n gendoGenerationId\n status\n prompt\n camera\n responseImage\n }\n }\n": types.ProjectVersionGendoAiRenderUpdatedDocument,
"\n mutation CreateNewRegion($input: CreateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n create(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n": types.CreateNewRegionDocument,
"\n mutation UpdateRegion($input: UpdateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n update(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n": types.UpdateRegionDocument,
"\n fragment ProjectPageTeamInternals_Project on Project {\n id\n role\n invitedTeam {\n id\n title\n role\n inviteId\n user {\n role\n ...LimitedUserAvatar\n }\n }\n team {\n role\n user {\n id\n role\n ...LimitedUserAvatar\n }\n }\n }\n": types.ProjectPageTeamInternals_ProjectFragmentDoc,
"\n fragment ProjectPageTeamInternals_Workspace on Workspace {\n id\n team {\n items {\n id\n role\n user {\n id\n }\n }\n }\n }\n": types.ProjectPageTeamInternals_WorkspaceFragmentDoc,
"\n fragment ProjectDashboardItemNoModels on Project {\n id\n name\n createdAt\n updatedAt\n role\n team {\n id\n user {\n id\n name\n avatar\n }\n }\n ...ProjectPageModelsCardProject\n }\n": types.ProjectDashboardItemNoModelsFragmentDoc,
Expand Down Expand Up @@ -1062,6 +1063,10 @@ export function graphql(source: "\n subscription ProjectVersionGendoAIRenderUpd
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation CreateNewRegion($input: CreateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n create(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n"): (typeof documents)["\n mutation CreateNewRegion($input: CreateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n create(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation UpdateRegion($input: UpdateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n update(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n"): (typeof documents)["\n mutation UpdateRegion($input: UpdateServerRegionInput!) {\n serverInfoMutations {\n multiRegion {\n update(input: $input) {\n id\n ...SettingsServerRegionsAddEditDialog_ServerRegionItem\n ...SettingsServerRegionsTable_ServerRegionItem\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
21 changes: 21 additions & 0 deletions packages/frontend-2/lib/common/generated/gql/graphql.ts

Large diffs are not rendered by default.

38 changes: 36 additions & 2 deletions packages/frontend-2/lib/multiregion/composables/management.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useMutation } from '@vue/apollo-composable'
import type { CreateNewRegionMutationVariables } from '~/lib/common/generated/gql/graphql'
import type {
CreateNewRegionMutationVariables,
UpdateRegionMutationVariables
} from '~/lib/common/generated/gql/graphql'
import { modifyObjectField, ROOT_QUERY } from '~/lib/common/helpers/graphql'
import { createNewRegionMutation } from '~/lib/multiregion/graphql/mutations'
import {
createNewRegionMutation,
updateRegionMutation
} from '~/lib/multiregion/graphql/mutations'

export const useCreateRegion = () => {
const { mutate } = useMutation(createNewRegionMutation)
Expand Down Expand Up @@ -49,3 +55,31 @@ export const useCreateRegion = () => {
return res?.data?.serverInfoMutations.multiRegion.create
}
}

export const useUpdateRegion = () => {
const { mutate } = useMutation(updateRegionMutation)
const { activeUser, isAdmin } = useActiveUser()
const { triggerNotification } = useGlobalToast()

return async (input: UpdateRegionMutationVariables) => {
if (!activeUser.value || !isAdmin.value) return

const res = await mutate(input).catch(convertThrowIntoFetchResult)

if (res?.data?.serverInfoMutations.multiRegion.update.id) {
triggerNotification({
type: ToastNotificationType.Success,
title: 'Region successfully updated'
})
} else {
const errMsg = getFirstGqlErrorMessage(res?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Failed to update region',
description: errMsg
})
}

return res?.data?.serverInfoMutations.multiRegion.update
}
}
14 changes: 14 additions & 0 deletions packages/frontend-2/lib/multiregion/graphql/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,17 @@ export const createNewRegionMutation = graphql(`
}
}
`)

export const updateRegionMutation = graphql(`
mutation UpdateRegion($input: UpdateServerRegionInput!) {
serverInfoMutations {
multiRegion {
update(input: $input) {
id
...SettingsServerRegionsAddEditDialog_ServerRegionItem
...SettingsServerRegionsTable_ServerRegionItem
}
}
}
}
`)
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ input CreateServerRegionInput {
description: String
}

input UpdateServerRegionInput {
key: String!
name: String
description: String
}

type ServerRegionMutations {
create(input: CreateServerRegionInput!): ServerRegionItem!
update(input: UpdateServerRegionInput!): ServerRegionItem!
}

type ServerInfoMutations {
Expand Down
15 changes: 15 additions & 0 deletions packages/server/modules/core/graph/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2894,13 +2894,19 @@ export type ServerRegionItem = {
export type ServerRegionMutations = {
__typename?: 'ServerRegionMutations';
create: ServerRegionItem;
update: ServerRegionItem;
};


export type ServerRegionMutationsCreateArgs = {
input: CreateServerRegionInput;
};


export type ServerRegionMutationsUpdateArgs = {
input: UpdateServerRegionInput;
};

export enum ServerRole {
ServerAdmin = 'SERVER_ADMIN',
ServerArchivedUser = 'SERVER_ARCHIVED_USER',
Expand Down Expand Up @@ -3494,6 +3500,12 @@ export type UpdateModelInput = {
projectId: Scalars['ID']['input'];
};

export type UpdateServerRegionInput = {
description?: InputMaybe<Scalars['String']['input']>;
key: Scalars['String']['input'];
name?: InputMaybe<Scalars['String']['input']>;
};

/** Only non-null values will be updated */
export type UpdateVersionInput = {
message?: InputMaybe<Scalars['String']['input']>;
Expand Down Expand Up @@ -4645,6 +4657,7 @@ export type ResolversTypes = {
TriggeredAutomationsStatus: ResolverTypeWrapper<TriggeredAutomationsStatusGraphQLReturn>;
UpdateAutomateFunctionInput: UpdateAutomateFunctionInput;
UpdateModelInput: UpdateModelInput;
UpdateServerRegionInput: UpdateServerRegionInput;
UpdateVersionInput: UpdateVersionInput;
User: ResolverTypeWrapper<UserGraphQLReturn>;
UserAutomateInfo: ResolverTypeWrapper<UserAutomateInfoGraphQLReturn>;
Expand Down Expand Up @@ -4900,6 +4913,7 @@ export type ResolversParentTypes = {
TriggeredAutomationsStatus: TriggeredAutomationsStatusGraphQLReturn;
UpdateAutomateFunctionInput: UpdateAutomateFunctionInput;
UpdateModelInput: UpdateModelInput;
UpdateServerRegionInput: UpdateServerRegionInput;
UpdateVersionInput: UpdateVersionInput;
User: UserGraphQLReturn;
UserAutomateInfo: UserAutomateInfoGraphQLReturn;
Expand Down Expand Up @@ -5994,6 +6008,7 @@ export type ServerRegionItemResolvers<ContextType = GraphQLContext, ParentType e

export type ServerRegionMutationsResolvers<ContextType = GraphQLContext, ParentType extends ResolversParentTypes['ServerRegionMutations'] = ResolversParentTypes['ServerRegionMutations']> = {
create?: Resolver<ResolversTypes['ServerRegionItem'], ParentType, ContextType, RequireFields<ServerRegionMutationsCreateArgs, 'input'>>;
update?: Resolver<ResolversTypes['ServerRegionItem'], ParentType, ContextType, RequireFields<ServerRegionMutationsUpdateArgs, 'input'>>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2875,13 +2875,19 @@ export type ServerRegionItem = {
export type ServerRegionMutations = {
__typename?: 'ServerRegionMutations';
create: ServerRegionItem;
update: ServerRegionItem;
};


export type ServerRegionMutationsCreateArgs = {
input: CreateServerRegionInput;
};


export type ServerRegionMutationsUpdateArgs = {
input: UpdateServerRegionInput;
};

export enum ServerRole {
ServerAdmin = 'SERVER_ADMIN',
ServerArchivedUser = 'SERVER_ARCHIVED_USER',
Expand Down Expand Up @@ -3475,6 +3481,12 @@ export type UpdateModelInput = {
projectId: Scalars['ID']['input'];
};

export type UpdateServerRegionInput = {
description?: InputMaybe<Scalars['String']['input']>;
key: Scalars['String']['input'];
name?: InputMaybe<Scalars['String']['input']>;
};

/** Only non-null values will be updated */
export type UpdateVersionInput = {
message?: InputMaybe<Scalars['String']['input']>;
Expand Down
8 changes: 8 additions & 0 deletions packages/server/modules/multiregion/domain/operations.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UpdateServerRegionInput } from '@/modules/core/graph/generated/graphql'
import { MultiRegionConfig, ServerRegion } from '@/modules/multiregion/domain/types'
import { InsertableRegionRecord } from '@/modules/multiregion/helpers/types'
import { Optional } from '@speckle/shared'
Expand All @@ -7,6 +8,10 @@ export type GetRegion = (params: { key: string }) => Promise<Optional<ServerRegi
export type StoreRegion = (params: {
region: InsertableRegionRecord
}) => Promise<ServerRegion>
export type UpdateRegion = (params: {
regionKey: string
region: Partial<ServerRegion>
}) => Promise<ServerRegion>

export type GetAvailableRegionConfigs = () => Promise<MultiRegionConfig>
export type GetAvailableRegionKeys = () => Promise<string[]>
Expand All @@ -15,3 +20,6 @@ export type GetFreeRegionKeys = () => Promise<string[]>
export type CreateAndValidateNewRegion = (params: {
region: InsertableRegionRecord
}) => Promise<ServerRegion>
export type UpdateAndValidateRegion = (params: {
input: UpdateServerRegionInput
}) => Promise<ServerRegion>
6 changes: 6 additions & 0 deletions packages/server/modules/multiregion/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ export class RegionCreateError extends BaseError {
static defaultMessage = 'An error occurred while creating the region'
static statusCode = 400
}

export class RegionUpdateError extends BaseError {
static code = 'REGION_UPDATE_ERROR'
static defaultMessage = 'An error occurred while updating the region'
static statusCode = 400
}
Loading