diff --git a/client/src/components/Tool/ToolCredentials.vue b/client/src/components/Tool/ToolCredentials.vue index cb0c68679f75..b19cb56ed689 100644 --- a/client/src/components/Tool/ToolCredentials.vue +++ b/client/src/components/Tool/ToolCredentials.vue @@ -2,7 +2,14 @@ import { BAlert, BButton, BModal } from "bootstrap-vue"; import { computed, ref } from "vue"; -import type { ToolCredentialsDefinition, UserCredentials } from "@/api/users"; +import { isRegisteredUser } from "@/api"; +import { + type CreateSourceCredentialsPayload, + type ServiceCredentialsDefinition, + type SourceCredentialsDefinition, + transformToSourceCredentials, + type UserCredentials, +} from "@/api/users"; import { useUserCredentialsStore } from "@/stores/userCredentials"; import { useUserStore } from "@/stores/userStore"; @@ -12,38 +19,55 @@ import ManageToolCredentials from "@/components/User/Credentials/ManageToolCrede interface Props { toolId: string; toolVersion: string; - toolCredentialsDefinition: ToolCredentialsDefinition[]; + toolCredentialsDefinition: ServiceCredentialsDefinition[]; } const props = defineProps(); const userStore = useUserStore(); -const userCredentialsStore = useUserCredentialsStore(); +const userCredentialsStore = useUserCredentialsStore( + isRegisteredUser(userStore.currentUser) ? userStore.currentUser.id : "anonymous" +); const isBusy = ref(true); const busyMessage = ref(""); const userCredentials = ref(undefined); +const credentialsDefinition = computed(() => { + return transformToSourceCredentials(props.toolId, props.toolCredentialsDefinition); +}); + const hasUserProvidedRequiredCredentials = computed(() => { - if (!userCredentials.value) { + if (!userCredentials.value || userCredentials.value.length === 0) { return false; } - return userCredentials.value.every((credentials) => credentials.optional || areSetByUser(credentials)); + + return userCredentials.value.every((credentials) => areOptional(credentials) || areSetByUser(credentials)); }); const hasUserProvidedAllCredentials = computed(() => { - if (!userCredentials.value) { + if (!userCredentials.value || userCredentials.value.length === 0) { return false; } return userCredentials.value.every(areSetByUser); }); const hasSomeOptionalCredentials = computed(() => { - return props.toolCredentialsDefinition.some((credentials) => credentials.optional); + for (const credentials of credentialsDefinition.value.services.values()) { + if (credentials.optional) { + return true; + } + } + return false; }); const hasSomeRequiredCredentials = computed(() => { - return props.toolCredentialsDefinition.some((credentials) => !credentials.optional); + for (const credentials of credentialsDefinition.value.services.values()) { + if (!credentials.optional) { + return true; + } + } + return false; }); const provideCredentialsButtonTitle = computed(() => { @@ -75,10 +99,7 @@ async function checkUserCredentials(providedCredentials?: UserCredentials[]) { if (!providedCredentials) { providedCredentials = userCredentialsStore.getAllUserCredentialsForTool(props.toolId) ?? - (await userCredentialsStore.fetchAllUserCredentialsForTool( - props.toolId, - props.toolCredentialsDefinition - )); + (await userCredentialsStore.fetchAllUserCredentialsForTool(props.toolId)); } userCredentials.value = providedCredentials; @@ -91,25 +112,29 @@ async function checkUserCredentials(providedCredentials?: UserCredentials[]) { } function areSetByUser(credentials: UserCredentials): boolean { - return ( - credentials.variables.every((variable) => variable.value) && - credentials.secrets.every((secret) => secret.alreadySet) - ); + return Object.values(credentials.groups).every((set) => { + return set.variables.every((variable) => variable.value) && set.secrets.every((secret) => secret.already_set); + }); +} + +function areOptional(credentials: UserCredentials): boolean { + const matchingDefinition = credentialsDefinition.value.services.get(credentials.reference); + if (!matchingDefinition) { + return false; + } + return matchingDefinition.optional; } function provideCredentials() { showModal.value = true; } -async function onSavedCredentials(providedCredentials: UserCredentials[]) { +async function onSavedCredentials(providedCredentials: CreateSourceCredentialsPayload) { showModal.value = false; busyMessage.value = "Saving your credentials..."; try { isBusy.value = true; - userCredentials.value = await userCredentialsStore.saveUserCredentialsForTool( - props.toolId, - providedCredentials - ); + userCredentials.value = await userCredentialsStore.saveUserCredentialsForTool(providedCredentials); } catch (error) { // TODO: Implement error handling. console.error("Error saving user credentials", error); @@ -170,7 +195,8 @@ checkUserCredentials(); diff --git a/client/src/components/User/Credentials/CredentialsInput.vue b/client/src/components/User/Credentials/CredentialsInput.vue deleted file mode 100644 index 178c16b88382..000000000000 --- a/client/src/components/User/Credentials/CredentialsInput.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/client/src/components/User/Credentials/ManageToolCredentials.vue b/client/src/components/User/Credentials/ManageToolCredentials.vue index d4902cc5b12d..09e5e6c883ed 100644 --- a/client/src/components/User/Credentials/ManageToolCredentials.vue +++ b/client/src/components/User/Credentials/ManageToolCredentials.vue @@ -1,31 +1,116 @@ @@ -33,12 +118,16 @@ function initializeCredentials(): UserCredentials[] {

Here you can manage your credentials for the tool {{ toolId }} version - {{ toolVersion }} . + {{ toolVersion }}.

- + :credential-definition="getServiceCredentialsDefinition(credential.reference)" + :credential-payload="credential" + @new-credentials-set="onNewCredentialsSet" + @update-current-set="onCurrentSetChange" />
diff --git a/client/src/components/User/Credentials/ServiceCredentials.vue b/client/src/components/User/Credentials/ServiceCredentials.vue new file mode 100644 index 000000000000..e9d558a8d05e --- /dev/null +++ b/client/src/components/User/Credentials/ServiceCredentials.vue @@ -0,0 +1,156 @@ + + + + +