Compare commits

...

3 Commits

Author SHA1 Message Date
Oğuzhan Koral 8788a942f2 Merge branch 'main' into oguzhan/cnx-2027-ui-work 2025-06-19 20:07:46 +03:00
oguzhankoral 90de018915 Patch the model after settings change 2025-06-19 14:34:38 +03:00
oguzhankoral db4f7c89e6 Receive settings for POC for now 2025-06-19 11:51:47 +03:00
8 changed files with 143 additions and 17 deletions
+9
View File
@@ -52,7 +52,9 @@
:model-id="modelCard.modelId"
:workspace-slug="modelCard.workspaceSlug"
:selected-version-id="modelCard.selectedVersionId"
:settings="modelCard.settings"
@next="handleVersionSelection"
@update:settings="handleUpdateSettings"
/>
</CommonDialog>
<template #states>
@@ -95,6 +97,7 @@ import type { VersionListItemFragment } from '~/lib/common/generated/gql/graphql
import { useMixpanel } from '~/lib/core/composables/mixpanel'
import { useInterval, watchOnce } from '@vueuse/core'
import { useAccountStore } from '~~/store/accounts'
import type { CardSetting } from '~/lib/models/card/setting'
const { trackEvent } = useMixpanel()
const app = useNuxtApp()
@@ -122,6 +125,12 @@ const isExpired = computed(() => {
return props.modelCard.latestVersionId !== props.modelCard.selectedVersionId
})
const handleUpdateSettings = async (settings: CardSetting[]) => {
await store.patchModel(props.modelCard.modelCardId, {
settings
})
}
// Cancels any in progress receive AND load selected version
const handleVersionSelection = async (
selectedVersion: VersionListItemFragment,
@@ -27,28 +27,29 @@ import type { CardSetting, CardSettingValue } from '~/lib/models/card/setting'
import type { JsonFormsChangeEvent } from '@jsonforms/vue'
import { cloneDeep, omit } from 'lodash-es'
import type { JsonSchema } from '@jsonforms/core'
import { useHostAppStore } from '~/store/hostApp'
// import { useHostAppStore } from '~/store/hostApp'
const props = defineProps<{
settings?: CardSetting[]
defaultSettings: CardSetting[]
expandable: boolean
}>()
const emit = defineEmits<{ (e: 'update:settings', value: CardSetting[]): void }>()
const store = useHostAppStore()
// const store = useHostAppStore()
const defaultSendSettings = computed(() => store.sendSettings)
const sendSettings = ref<CardSetting[] | undefined>(
cloneDeep(props.settings ?? defaultSendSettings.value) // need to prevent mutation!
// const defaultSendSettings = computed(() => store.sendSettings)
const settings = ref<CardSetting[] | undefined>(
cloneDeep(props.settings ?? props.defaultSettings) // need to prevent mutation!
)
const showSettings = ref(!props.expandable)
const settingsJsonForms = computed(() => {
if (sendSettings.value === undefined) return {}
if (settings.value === undefined) return {}
const obj: JsonSchema = { type: 'object', properties: {} }
sendSettings.value.forEach((setting: CardSetting) => {
settings.value.forEach((setting: CardSetting) => {
const mappedSetting = omit({ ...setting, $id: setting.id }, ['id'])
if (obj && obj.properties) {
obj.properties[setting.id] = mappedSetting
@@ -60,8 +61,8 @@ const settingsJsonForms = computed(() => {
type DataType = Record<string, unknown>
const data = computed(() => {
const settingValues = {} as DataType
if (sendSettings.value) {
sendSettings.value.forEach((setting) => {
if (settings.value) {
settings.value.forEach((setting) => {
settingValues[setting.id as string] = setting.value
})
}
@@ -69,14 +70,14 @@ const data = computed(() => {
})
const onParamsFormChange = (e: JsonFormsChangeEvent) => {
if (sendSettings.value === undefined) return
sendSettings.value?.forEach((setting) => {
if (settings.value === undefined) return
settings.value?.forEach((setting) => {
if (setting) {
if (setting.value !== (e.data as DataType)[setting.id]) {
setting.value = (e.data as DataType)[setting.id] as CardSettingValue
}
}
})
emit('update:settings', sendSettings.value)
emit('update:settings', settings.value)
}
</script>
+8
View File
@@ -37,6 +37,7 @@
:workspace-slug="selectedWorkspace?.slug"
:from-wizard="true"
@next="selectVersionAndAddModel"
@update:settings="handleUpdateSettings"
/>
</div>
</div>
@@ -57,6 +58,7 @@ import { ReceiverModelCard } from '~/lib/models/card/receiver'
import { useMixpanel } from '~/lib/core/composables/mixpanel'
import { useAddByUrl } from '~/lib/core/composables/addByUrl'
import { getSlugFromHostAppNameAndVersion } from '~/lib/common/helpers/hostAppSlug'
import type { CardSetting } from '~/lib/models/card/setting'
const { trackEvent } = useMixpanel()
@@ -83,6 +85,7 @@ const selectedAccountId = ref<string>(activeAccount.value?.accountInfo.id as str
const selectedWorkspace = ref<WorkspaceListWorkspaceItemFragment>()
const selectedProject = ref<ProjectListProjectItemFragment>()
const selectedModel = ref<ModelListModelItemFragment>()
const receieveSettings = ref<CardSetting[] | undefined>(undefined)
const { tryParseUrl, urlParsedData, urlParseError } = useAddByUrl()
const updateSearchText = (text: string | undefined) => {
@@ -131,6 +134,10 @@ const title = computed(() => {
return ''
})
const handleUpdateSettings = (settings: CardSetting[]) => {
receieveSettings.value = settings
}
// accountId, serverUrl, ModelListModelItemFragment, VersionListItemFragment
const selectVersionAndAddModel = async (
version: VersionListItemFragment,
@@ -173,6 +180,7 @@ const selectVersionAndAddModel = async (
)
const modelCard = new ReceiverModelCard()
modelCard.settings = receieveSettings.value
modelCard.accountId = selectedAccountId.value
modelCard.serverUrl = activeAccount.value.accountInfo.serverInfo.url
+3 -2
View File
@@ -1,11 +1,12 @@
<template>
<div class="space-y-4">
<FilterListSelect @update:filter="updateFilter" />
<SendSettings
<ModelSettings
v-if="hasSendSettings"
expandable
:default-settings="(store.sendSettings as unknown as CardSetting[])"
@update:settings="updateSettings"
></SendSettings>
></ModelSettings>
</div>
</template>
<script setup lang="ts">
+3 -2
View File
@@ -6,11 +6,12 @@
:title="`Settings`"
fullscreen="none"
>
<SendSettings
<ModelSettings
:expandable="false"
:default-settings="(store.sendSettings as unknown as CardSetting[])"
:settings="props.settings"
@update:settings="updateSettings"
></SendSettings>
></ModelSettings>
<div class="mt-4 flex justify-end items-center space-x-2">
<FormButton size="sm" color="outline" @click="showSettingsDialog = false">
Cancel
+25 -1
View File
@@ -13,6 +13,17 @@
Upgrade
</FormButton>
</div>
<div v-if="hasReceiveSettings">
<ModelSettings
class="mb-2"
expandable
:settings="settings"
:default-settings="(store.receiveSettings as unknown as CardSetting[])"
@update:settings="updateSettings"
></ModelSettings>
<hr />
</div>
<div v-if="latestVersion" class="grid grid-cols-2 gap-3 max-[275px]:grid-cols-1">
<WizardListVersionCard
v-for="(version, index) in versions"
@@ -44,27 +55,40 @@ import { useQuery } from '@vue/apollo-composable'
import { modelVersionsQuery } from '~/lib/graphql/mutationsAndQueries'
import type { VersionListItemFragment } from '~/lib/common/generated/gql/graphql'
import { useAccountStore } from '~/store/accounts'
import type { CardSetting } from '~/lib/models/card/setting'
import { useHostAppStore } from '~/store/hostApp'
defineEmits<{
const emit = defineEmits<{
(
e: 'next',
version: VersionListItemFragment,
latestVersion: VersionListItemFragment
): void
(e: 'update:settings', settings: CardSetting[]): void
}>()
const props = defineProps<{
accountId: string
projectId: string
modelId: string
settings?: CardSetting[]
selectedVersionId?: string
workspaceSlug?: string
fromWizard?: boolean
}>()
const store = useHostAppStore()
const accountStore = useAccountStore()
const serverUrl = computed(() => accountStore.activeAccount.accountInfo.serverInfo.url)
const hasReceiveSettings = computed(
() => store.receiveSettings && store.receiveSettings.length > 0
)
const updateSettings = (settings: CardSetting[]) => {
emit('update:settings', settings)
}
const {
result: modelVersionResults,
loading,
+75
View File
@@ -1023,6 +1023,39 @@ export type FileUpload = {
userId: Scalars['String']['output'];
};
export type FileUploadCollection = {
__typename?: 'FileUploadCollection';
cursor?: Maybe<Scalars['String']['output']>;
items: Array<FileUpload>;
totalCount: Scalars['Int']['output'];
};
export type FileUploadMutations = {
__typename?: 'FileUploadMutations';
/**
* Generate a pre-signed url to which a file can be uploaded.
* After uploading the file, call mutation startFileImport to register the completed upload.
*/
generateUploadUrl: GenerateFileUploadUrlOutput;
/**
* Before calling this mutation, call generateUploadUrl to get the
* pre-signed url and blobId. Then upload the file to that url.
* Once the upload to the pre-signed url is completed, this mutation should be
* called to register the completed upload and create the blob metadata.
*/
startFileImport: FileUpload;
};
export type FileUploadMutationsGenerateUploadUrlArgs = {
input: GenerateFileUploadUrlInput;
};
export type FileUploadMutationsStartFileImportArgs = {
input: StartFileImportInput;
};
export type GendoAiRender = {
__typename?: 'GendoAIRender';
camera?: Maybe<Scalars['JSONObject']['output']>;
@@ -1058,6 +1091,24 @@ export type GendoAiRenderInput = {
versionId: Scalars['ID']['input'];
};
export type GenerateFileUploadUrlInput = {
fileName: Scalars['String']['input'];
projectId: Scalars['String']['input'];
};
export type GenerateFileUploadUrlOutput = {
__typename?: 'GenerateFileUploadUrlOutput';
fileId: Scalars['String']['output'];
url: Scalars['String']['output'];
};
export type GetModelUploadsInput = {
/** The cursor for pagination. */
cursor?: InputMaybe<Scalars['String']['input']>;
/** The maximum number of uploads to return. */
limit?: InputMaybe<Scalars['Int']['input']>;
};
export type InvitableCollaboratorsFilter = {
search?: InputMaybe<Scalars['String']['input']>;
};
@@ -1276,6 +1327,8 @@ export type Model = {
permissions: ModelPermissionChecks;
previewUrl?: Maybe<Scalars['String']['output']>;
updatedAt: Scalars['DateTime']['output'];
/** Get all file uploads ever done in this model */
uploads: FileUploadCollection;
version: Version;
versions: VersionCollection;
};
@@ -1292,6 +1345,11 @@ export type ModelPendingImportedVersionsArgs = {
};
export type ModelUploadsArgs = {
input?: InputMaybe<GetModelUploadsInput>;
};
export type ModelVersionArgs = {
id: Scalars['String']['input'];
};
@@ -1453,6 +1511,7 @@ export type Mutation = {
* @deprecated Part of the old API surface and will be removed in the future. Use VersionMutations.moveToModel instead.
*/
commitsMove: Scalars['Boolean']['output'];
fileUploadMutations: FileUploadMutations;
/**
* Delete a pending invite
* Note: The required scope to invoke this is not given out to app or personal access tokens
@@ -3026,6 +3085,7 @@ export type Role = {
export type RootPermissionChecks = {
__typename?: 'RootPermissionChecks';
canCreatePersonalProject: PermissionCheckResult;
canCreateWorkspace: PermissionCheckResult;
};
/** Available scopes. */
@@ -3262,6 +3322,17 @@ export enum SortDirection {
Desc = 'DESC'
}
export type StartFileImportInput = {
/**
* The etag is returned by the blob storage provider in the response body after a successful upload.
* It is used to verify the integrity of the uploaded file.
*/
etag: Scalars['String']['input'];
fileId: Scalars['String']['input'];
modelId: Scalars['String']['input'];
projectId: Scalars['String']['input'];
};
export type Stream = {
__typename?: 'Stream';
/**
@@ -4479,6 +4550,8 @@ export type Workspace = {
id: Scalars['ID']['output'];
/** Only available to workspace owners/members */
invitedTeam?: Maybe<Array<PendingWorkspaceCollaborator>>;
/** Exclusive workspaces do not allow their workspace members to create or join other workspaces as members. */
isExclusive: Scalars['Boolean']['output'];
/** Logo image as base64-encoded string */
logo?: Maybe<Scalars['String']['output']>;
name: Scalars['String']['output'];
@@ -4865,6 +4938,7 @@ export type WorkspacePermissionChecks = {
canCreateProject: PermissionCheckResult;
canEditEmbedOptions: PermissionCheckResult;
canInvite: PermissionCheckResult;
canMakeWorkspaceExclusive: PermissionCheckResult;
canMoveProjectToWorkspace: PermissionCheckResult;
canReadMemberEmail: PermissionCheckResult;
};
@@ -5115,6 +5189,7 @@ export type WorkspaceUpdateInput = {
discoverabilityEnabled?: InputMaybe<Scalars['Boolean']['input']>;
domainBasedMembershipProtectionEnabled?: InputMaybe<Scalars['Boolean']['input']>;
id: Scalars['String']['input'];
isExclusive?: InputMaybe<Scalars['Boolean']['input']>;
/** Logo image as base64-encoded string */
logo?: InputMaybe<Scalars['String']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
+7
View File
@@ -196,6 +196,7 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
}
const sendSettings = ref<CardSetting[]>()
const receiveSettings = ref<CardSetting[]>()
/**
* Send filters
@@ -620,6 +621,10 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
sendSettings.value = await app.$sendBinding.getSendSettings()
}
const getReceiveSettings = async () => {
receiveSettings.value = await app.$receiveBinding.getReceiveSettings()
}
const tryToUpgradeModelCardSettings = (
settings: CardSetting[],
typeDiscriminator: string
@@ -698,6 +703,7 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
await refreshDocumentModelStore()
await refreshSendFilters()
await getSendSettings()
await getReceiveSettings()
tryToUpgradeModelCardSettings(sendSettings.value || [], 'SenderModelCard')
// Intercom shenanningans below
@@ -731,6 +737,7 @@ export const useHostAppStore = defineStore('hostAppStore', () => {
models,
sendFilters,
sendSettings,
receiveSettings,
selectionFilter,
everythingFilter,
currentNotification,