diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 363a41538a8..d7c4fd081fb 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "8.13.1" + ".": "8.14.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c563e39a309..672e1136778 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows conventions [outlined here](http://keepachangelog.com/). +## [8.14.0](https://github.com/ParabolInc/parabol/compare/v8.13.1...v8.14.0) (2024-12-18) + + +### Added + +* get saml config for domain ([#10618](https://github.com/ParabolInc/parabol/issues/10618)) ([2da5af3](https://github.com/ParabolInc/parabol/commit/2da5af3d845cd1bb6b445ca20d3807cd229d150b)) +* update suggest group titles ([#10568](https://github.com/ParabolInc/parabol/issues/10568)) ([81043ad](https://github.com/ParabolInc/parabol/commit/81043ad1a1265ca567778f95a5507cb5ae35734b)) + ## [8.13.1](https://github.com/ParabolInc/parabol/compare/v8.13.0...v8.13.1) (2024-12-18) diff --git a/package.json b/package.json index 9f5c13e93ab..22112bab43c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "8.13.1", + "version": "8.14.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" diff --git a/packages/chronos/package.json b/packages/chronos/package.json index 764f16ff91a..077474755ce 100644 --- a/packages/chronos/package.json +++ b/packages/chronos/package.json @@ -1,6 +1,6 @@ { "name": "chronos", - "version": "8.13.1", + "version": "8.14.0", "description": "A cron job scheduler", "author": "Matt Krick ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/chronos#readme", @@ -25,6 +25,6 @@ }, "dependencies": { "cron": "^2.3.1", - "parabol-server": "8.13.1" + "parabol-server": "8.14.0" } } diff --git a/packages/client/components/ReflectionGroup/ReflectionGroupTitleEditor.tsx b/packages/client/components/ReflectionGroup/ReflectionGroupTitleEditor.tsx index c2927fb7536..9ff333051ca 100644 --- a/packages/client/components/ReflectionGroup/ReflectionGroupTitleEditor.tsx +++ b/packages/client/components/ReflectionGroup/ReflectionGroupTitleEditor.tsx @@ -128,9 +128,11 @@ const ReflectionGroupTitleEditor = (props: Props) => { const {id: reflectionGroupId, title} = reflectionGroup const dirtyRef = useRef(false) const initialTitleRef = useRef(title) - const isLoading = title === '' + + const isLoading = title === '' && !dirtyRef.current const onChange = (e: React.ChangeEvent) => { + dirtyRef.current = true const title = e.target.value commitLocalUpdate(atmosphere, (store) => { const reflectionGroup = store.get(reflectionGroupId) diff --git a/packages/client/mutations/AutogroupMutation.ts b/packages/client/mutations/AutogroupMutation.ts index 8f05c4d042c..3a66969a2e1 100644 --- a/packages/client/mutations/AutogroupMutation.ts +++ b/packages/client/mutations/AutogroupMutation.ts @@ -13,6 +13,7 @@ graphql` reflectionGroups { id title + smartTitle reflections { id plaintextContent diff --git a/packages/client/package.json b/packages/client/package.json index ff992d1ca86..11da44633d0 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "8.13.1", + "version": "8.14.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" diff --git a/packages/embedder/package.json b/packages/embedder/package.json index 1c5a71a098d..558e109e4bd 100644 --- a/packages/embedder/package.json +++ b/packages/embedder/package.json @@ -1,6 +1,6 @@ { "name": "parabol-embedder", - "version": "8.13.1", + "version": "8.14.0", "description": "A service that computes embedding vectors from Parabol objects", "author": "Jordan Husney ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/embedder#readme", diff --git a/packages/gql-executor/package.json b/packages/gql-executor/package.json index 968a0a8759f..6fae6ba656a 100644 --- a/packages/gql-executor/package.json +++ b/packages/gql-executor/package.json @@ -1,6 +1,6 @@ { "name": "gql-executor", - "version": "8.13.1", + "version": "8.14.0", "description": "A Stateless GraphQL Executor", "author": "Matt Krick ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/gqlExecutor#readme", @@ -25,8 +25,8 @@ }, "dependencies": { "dd-trace": "^5.0.0", - "parabol-client": "8.13.1", - "parabol-server": "8.13.1", + "parabol-client": "8.14.0", + "parabol-server": "8.14.0", "undici": "^5.26.2" } } diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index ea34f835137..3ae928e43a9 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -2,7 +2,7 @@ "name": "integration-tests", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "8.13.1", + "version": "8.14.0", "description": "", "main": "index.js", "scripts": { diff --git a/packages/server/graphql/mutations/helpers/updateReflectionLocation/addReflectionToGroup.ts b/packages/server/graphql/mutations/helpers/updateReflectionLocation/addReflectionToGroup.ts index 29f5df88c5c..222679d1677 100644 --- a/packages/server/graphql/mutations/helpers/updateReflectionLocation/addReflectionToGroup.ts +++ b/packages/server/graphql/mutations/helpers/updateReflectionLocation/addReflectionToGroup.ts @@ -2,6 +2,7 @@ import dndNoise from 'parabol-client/utils/dndNoise' import getKysely from '../../../../postgres/getKysely' import updateGroupTitle from '../updateGroupTitle' import {GQLContext} from './../../../graphql' +import updateSmartGroupTitle from './updateSmartGroupTitle' const addReflectionToGroup = async ( reflectionId: string, @@ -67,6 +68,11 @@ const addReflectionToGroup = async ( .set({title: oldReflectionGroup.title, smartTitle: smartTitle ?? ''}) .where('id', '=', reflectionGroupId) .execute() + } else if (smartTitle) { + // smartTitle exists when autogrouping or resetting groups + await updateSmartGroupTitle(reflectionGroupId, smartTitle) + reflectionGroup.smartTitle = smartTitle + reflectionGroup.title = smartTitle } else { const meeting = await dataLoader.get('newMeetings').loadNonNull(meetingId) await updateGroupTitle({ diff --git a/packages/server/graphql/private/queries/getSAMLForDomain.ts b/packages/server/graphql/private/queries/getSAMLForDomain.ts new file mode 100644 index 00000000000..6364ef9bad8 --- /dev/null +++ b/packages/server/graphql/private/queries/getSAMLForDomain.ts @@ -0,0 +1,23 @@ +import getKysely from '../../../postgres/getKysely' +import standardError from '../../../utils/standardError' +import {QueryResolvers} from '../resolverTypes' + +const getSAMLForDomain: QueryResolvers['getSAMLForDomain'] = async (_parent, {domain}) => { + const pg = getKysely() + + const samlResult = await pg + .selectFrom('SAML') + .innerJoin('SAMLDomain', 'SAML.id', 'SAMLDomain.samlId') + .selectAll('SAML') + .where('SAMLDomain.domain', '=', domain.toLowerCase()) + .executeTakeFirst() + + if (!samlResult) { + return standardError(new Error('No SAML configuration found for domain')) + } + return { + saml: samlResult + } +} + +export default getSAMLForDomain diff --git a/packages/server/graphql/private/typeDefs/GetSAMLForDomainPayload.graphql b/packages/server/graphql/private/typeDefs/GetSAMLForDomainPayload.graphql new file mode 100644 index 00000000000..db857c3b38f --- /dev/null +++ b/packages/server/graphql/private/typeDefs/GetSAMLForDomainPayload.graphql @@ -0,0 +1,4 @@ +""" +Return value for getSAMLForDomain, which could be an error +""" +union GetSAMLForDomainPayload = ErrorPayload | GetSAMLForDomainSuccess diff --git a/packages/server/graphql/private/typeDefs/GetSAMLForDomainSuccess.graphql b/packages/server/graphql/private/typeDefs/GetSAMLForDomainSuccess.graphql new file mode 100644 index 00000000000..fb2d42a71a4 --- /dev/null +++ b/packages/server/graphql/private/typeDefs/GetSAMLForDomainSuccess.graphql @@ -0,0 +1,6 @@ +type GetSAMLForDomainSuccess { + """ + The SAML configuration + """ + saml: SAML! +} diff --git a/packages/server/graphql/private/typeDefs/Query.graphql b/packages/server/graphql/private/typeDefs/Query.graphql index fda75c5b187..0e1b7de3c5d 100644 --- a/packages/server/graphql/private/typeDefs/Query.graphql +++ b/packages/server/graphql/private/typeDefs/Query.graphql @@ -138,4 +138,11 @@ type Query { """ includeInactive: Boolean! = false ): [Organization!] + + getSAMLForDomain( + """ + the domain to get the SAML record for + """ + domain: String! + ): GetSAMLForDomainPayload } diff --git a/packages/server/package.json b/packages/server/package.json index 33b87dc5b81..029e919664c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "8.13.1", + "version": "8.14.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" @@ -128,7 +128,7 @@ "oauth-1.0a": "^2.2.6", "openai": "^4.53.0", "oy-vey": "^0.12.1", - "parabol-client": "8.13.1", + "parabol-client": "8.14.0", "pg": "^8.5.1", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/packages/server/utils/OpenAIServerManager.ts b/packages/server/utils/OpenAIServerManager.ts index 8b880bae1dd..29a7b315cad 100644 --- a/packages/server/utils/OpenAIServerManager.ts +++ b/packages/server/utils/OpenAIServerManager.ts @@ -420,11 +420,11 @@ class OpenAIServerManager { async generateGroupTitle(reflections: {plaintextContent: string}[]) { if (!this.openAIApi) return null - const prompt = `Given these related retrospective comments, generate a short (2-4 words) theme or title that captures their essence. The title should be clear and actionable: + const prompt = `Generate a short (2-4 words) theme or title that captures the essence of these related retrospective comments. The title should be clear and actionable. ${reflections.map((r) => r.plaintextContent).join('\n')} -Return only the title, nothing else. Do not include quote marks around the title.` +Important: Respond with ONLY the title itself. Do not include any prefixes like "Title:" or any quote marks. Do not provide any additional explanation.` try { const response = await this.openAIApi.chat.completions.create({ @@ -442,7 +442,9 @@ Return only the title, nothing else. Do not include quote marks around the title presence_penalty: 0 }) const title = - (response.choices[0]?.message?.content?.trim() as string)?.replaceAll(/['"]/g, '') ?? null + (response.choices[0]?.message?.content?.trim() as string) + ?.replace(/^[Tt]itle:*\s*/gi, '') // Remove "Title:" prefix + ?.replaceAll(/['"]/g, '') ?? null return title } catch (e) {