Skip to content

Commit

Permalink
Release v5.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinejaussoin authored Mar 30, 2023
1 parent 95a612f commit 784efc2
Show file tree
Hide file tree
Showing 23 changed files with 139 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/alpha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: 'Alpha Build'

on:
push:
branches: [v51/gpt]
branches: [v51/release]

jobs:
frontend:
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Canary Build](https://github.com/antoinejaussoin/retro-board/actions/workflows/canary.yml/badge.svg)](https://github.com/antoinejaussoin/retro-board/actions/workflows/canary.yml)
[![Alpha Build](https://github.com/antoinejaussoin/retro-board/actions/workflows/alpha.yml/badge.svg)](https://github.com/antoinejaussoin/retro-board/actions/workflows/alpha.yml)

[Retrospected](http://www.retrospected.com) is a free Real-time Agile Retrospective Board for engineering teams.
[Retrospected](http://www.retrospected.com) is a free AI-powered Real-time Agile Retrospective Board for engineering teams.

 

Expand All @@ -21,6 +21,8 @@
<img src="./content/logos/socketio.png" height="65">
&nbsp;
<img src="./content/logos/vite.png" height="65">
&nbsp;
<img src="./content/logos/chatgpt.png" height="65">
</p>

![Retrospected.com](/content/screenshot-v5.png?raw=true 'Retrospected.com')
Expand Down Expand Up @@ -63,6 +65,7 @@ It features the following technologies:
- [Stripe](https://stripe.com/), for our payment solution
- [Docusaurus](http://docusaurus.io/), for our documentation
- [NextJS](https://nextjs.org/), for our landing page
- [ChatGPT](https://openai.com/blog/chatgpt), powering our AI agile coach

Previous versions featured the following libraries:

Expand Down Expand Up @@ -94,6 +97,15 @@ This will run a demo version, which you can turn into a fully licenced version b

## Versions History

### Version 5.1.0

- [⭐️ Pro Feature] 🤖 AI Coach, powered by Chat GPT. Limited access to non-paid users.
- Improve the login workflow
- Improve the template selection
- Improve the home page, with search on past retrospectives and nicer button
- Allow a user to convert their Anonymous account to a regular account and migrate their data
- Bug fix: fix bug where multiple demos were created

### Version 5.0.3

- 🇩🇪 Adding the German version of our marketing website
Expand Down
4 changes: 2 additions & 2 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@retrospected/backend",
"version": "5.0.3",
"version": "5.1.0",
"license": "GNU GPLv3",
"private": true,
"type": "module",
Expand Down
56 changes: 38 additions & 18 deletions backend/src/ai/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,45 @@ import { last } from 'lodash-es';

const systemMessage: CoachMessage = {
role: 'system',
content: `You are an online agile coach, helping users to improve their online retrospectives, using Retrospected.
content: `
You are an online agile coach, helping users to improve their online retrospectives, using Retrospected.
Users are part of a remote team and are not physically in the same room.
Retrospected is an online tool to run retrospectives.
Retrospected is a light and simple but highly customizable tool.
Retrospected can be used on computers, phones, and tablets.
Retrospected can also be self-hosted, which is especially useful for organizations that require extra security and want to host and own their data.
Retrospected is usable in 15 languages, including English, German, French, and Spanish.
Retrospected is an open-source software available on GitHub.
Retrospected provides various templates such as "Start, Stop, Continue" and "4Ls”.
Retrospected is especially suited for enterprises because of its self-hosted option, multilingual interface, simple and customizable software, and encrypted sessions.
Users can vote, use a timer, and get a summary that can be exported to Jira using Markdown.
The export functionality is located in the Summary tab, using the export button on the bottom right corner.
Users can also use the "Copy to clipboard" button to copy the summary to the clipboard.
Users can make posts anonymous or not, change voting rules, customize the columns, encrypt sessions and make them private.
When possible, use bullet points.
Users can add animated images using Giphy to make their retrospective more fun.
If the user's question is too vague, do ask clarifying questions to give a better reply.
Always introduce yourself as an agile coach that can help users improve their online retrospectives and make the most out of Retrospected, by answering questions about agile methodology or the usage of Retrospected.
Always end each one of your answers by suggesting to expand on some part of your answer if needed, or answer a new question.
Retrospected is:
- an online tool to run retrospectives
- an open-source software available on GitHub (https://github.com/antoinejaussoin/retro-board)
- created by Antoine Jaussoin
- a light and simple but highly customizable tool
- usable on computers, phones, and tablets
- available in 15 languages, including English, German, French, and Spanish
Retrospected can:
- be self-hosted, which is especially useful for organizations that require extra security and want to host and own their data
- provide various templates such as "Start, Stop, Continue" and "4Ls"
- encrypt sessions and make them private (both Pro features)
Users of Retrospected can:
- Customize the columns (number, color, icon, name)
- Vote (and customize voting rules)
- Create groups of posts, to categorize posts into different topics, and will automatically count votes at the group level in the summary tab. Groups can only be named.
- Use a customizable timer. The timer can prevent users from entering more posts when it ends.
- Get a summary of the retro that can be exported to Jira using Markdown. This functionality is located in the Summary tab, using the export button on the bottom right corner.
- Use the "Copy to clipboard" button to copy the summary
- Make posts anonymously or not
- Add animated images using Giphy to make their retrospective more fun
Retrospected pricing:
- Free version has all features except private sessions and encrypted sessions and is limited to 40 posts per user
- Pro Team: same as free, but can be used by up to 20 users and have private sessions and encrypted sessions, cost 12.90 USD/month
- Pro Unlimited: same as Pro, but doesn't have a user limit, cost 49.95 USD/month
- Self-hosted version: same as Pro Unlimited, unlimited updates, one-time fee, 649.00 USD
- 30-day trial version of the Pro version
When you are responding to questions:
- Use bullet points
- If the user's question is too vague, do ask clarifying questions to give a better reply
- Always introduce yourself as an agile coach that can help users improve their online retrospectives and make the most out of Retrospected, by answering questions about agile methodology or the usage of Retrospected.
- Always end each one of your answers by suggesting to expand on some part of your answer if needed, or answer a new question.
`,
};

Expand Down
19 changes: 19 additions & 0 deletions backend/src/db/actions/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export async function deleteAccount(
user,
anonymousAccount
);
await delAiChat(manager, options.deletePosts, user, anonymousAccount);
await delVisits(manager, options.deleteSessions, user, anonymousAccount);
await delVotes(manager, options.deleteVotes, user, anonymousAccount);
await delPosts(manager, options.deletePosts, user, anonymousAccount);
Expand Down Expand Up @@ -62,6 +63,24 @@ async function delMessages(
}
}

async function delAiChat(
manager: EntityManager,
hardDelete: boolean,
user: UserView,
anon: UserIdentityEntity
) {
if (hardDelete) {
await manager.query('delete from ai_chat where created_by_id = $1', [
user.id,
]);
} else {
await manager.query(
'update ai_chat set created_by_id = $1 where created_by_id = $2',
[anon.user.id, user.id]
);
}
}

async function delVisits(
manager: EntityManager,
hardDelete: boolean,
Expand Down
7 changes: 7 additions & 0 deletions backend/src/db/actions/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { deleteAccount } from './delete.js';
import { getUserViewFromRequest } from '../../utils.js';
import { Request } from 'express';
import AiChatRepository from '../repositories/AiChatRepository.js';

export async function mergeAnonymous(req: Request, newUserIdentityId: string) {
const anonymousUser = await getUserViewFromRequest(req);
Expand Down Expand Up @@ -70,6 +71,7 @@ async function migrateOne(main: UserView, target: UserView) {
const postRepo = manager.withRepository(PostRepository);
const groupRepo = manager.withRepository(PostGroupRepository);
const sessionRepo = manager.withRepository(SessionRepository);
const aiChatRepo = manager.withRepository(AiChatRepository);

await manager.query('update messages set user_id = $1 where user_id = $2', [
main.id,
Expand All @@ -86,6 +88,11 @@ async function migrateOne(main: UserView, target: UserView) {
[main.id, target.id]
);

await aiChatRepo.update(
{ createdBy: { id: target.id } },
{ createdBy: { id: main.id } }
);

await voteRepo.update(
{ user: { id: target.id } },
{ user: { id: main.id } }
Expand Down
8 changes: 7 additions & 1 deletion backend/src/db/entities/AiChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ export default class AiChatEntity {
cascade: true,
nullable: false,
eager: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
})
public messages: AiChatMessageEntity[] | undefined;
@ManyToOne(() => UserEntity, { eager: true, cascade: true, nullable: false })
@ManyToOne(() => UserEntity, {
eager: true,
cascade: true,
nullable: false,
})
@Index()
public createdBy: UserEntity;
@CreateDateColumn({ type: 'timestamp with time zone' })
Expand Down
6 changes: 5 additions & 1 deletion backend/src/db/entities/AiChatMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import AiChatEntity from './AiChat.js';
export default class AiChatMessageEntity {
@PrimaryColumn({ primary: true, generated: false, unique: true })
public id: string;
@ManyToOne(() => AiChatEntity, { nullable: false })
@ManyToOne(() => AiChatEntity, {
nullable: false,
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
})
@Index()
public chat: Relation<AiChatEntity>;
@Column({ type: 'character varying' })
Expand Down
16 changes: 16 additions & 0 deletions backend/src/db/migrations/1680210996379-AiChatCascade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class AiChatCascade1680210996379 implements MigrationInterface {
name = 'AiChatCascade1680210996379'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ai_chat_messages" DROP CONSTRAINT "FK_312864ee92fd941771769c43e19"`);
await queryRunner.query(`ALTER TABLE "ai_chat_messages" ADD CONSTRAINT "FK_312864ee92fd941771769c43e19" FOREIGN KEY ("chat_id") REFERENCES "ai_chat"("id") ON DELETE CASCADE ON UPDATE CASCADE`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ai_chat_messages" DROP CONSTRAINT "FK_312864ee92fd941771769c43e19"`);
await queryRunner.query(`ALTER TABLE "ai_chat_messages" ADD CONSTRAINT "FK_312864ee92fd941771769c43e19" FOREIGN KEY ("chat_id") REFERENCES "ai_chat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
}

}
Binary file added content/logos/chatgpt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@retrospected/docs",
"version": "5.0.3",
"version": "5.1.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@retrospected/frontend",
"version": "5.0.3",
"version": "5.1.0",
"license": "GNU GPLv3",
"private": true,
"dependencies": {
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/components/ProButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ function ProButton({ children, quota }: ProButtonProps) {
</DialogContent>
<DialogContent>
<Features>
<Feature
icon={<Psychology />}
color={colors.blue[700]}
title={t('SubscribeModal.features.ai.title')!}
description={t('SubscribeModal.features.ai.description')!}
/>
<Feature
icon={<Lock />}
color={colors.red[700]}
Expand All @@ -145,6 +139,12 @@ function ProButton({ children, quota }: ProButtonProps) {
t('SubscribeModal.features.unlimitedPosts.description')!
}
/>
<Feature
icon={<Psychology />}
color={colors.blue[700]}
title={t('SubscribeModal.features.ai.title')!}
description={t('SubscribeModal.features.ai.description')!}
/>
</Features>
</DialogContent>
<DialogActions>
Expand Down
1 change: 0 additions & 1 deletion frontend/src/views/game/board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ function GameMode({
const Columns = styled.div<{ numberOfColumns: number }>`
display: flex;
margin-top: 30px;
margin-right: -20px;
@media screen and (max-width: ${(props) => props.numberOfColumns * 340 + 100}px) {
margin-top: 10px;
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/views/game/board/Column.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,7 @@ const PostsWrapper = styled.div<{
draggingOver: boolean;
draggingColor: string;
}>`
background-color: ${(props) =>
props.draggingOver ? props.draggingColor : 'unset'};
background-color: ${(props) => props.draggingOver ? props.draggingColor : 'unset'};
flex: 1;
min-height: 100px;
`;
Expand All @@ -248,6 +247,8 @@ const Add = styled.div`
display: flex;
align-items: center;
margin-bottom: 20px;
position: relative;
left: 10px;
> :first-of-type {
flex: 1;
Expand Down
1 change: 0 additions & 1 deletion frontend/src/views/game/board/post/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ const PostCard = styled(Card)`
margin: 10px 5px;
margin-bottom: 20px;
position: relative;
left: -10px;
:hover {
& .drag-handle {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/layout/ai/AiButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AiCoach } from './AiCoach';
export function AiButton() {
const [opened, open, close] = useModal();
const { t } = useTranslation();
const small = useMediaQuery('(max-width:600px)');
const small = useMediaQuery('(max-width:800px)');
const { ai } = useBackendCapabilities();
if (!ai) {
return null;
Expand Down
17 changes: 14 additions & 3 deletions frontend/src/views/layout/ai/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ChatInput from './ChatInput';
import { keyframes } from '@emotion/react';
import { CoachMessage } from 'common';
import { Examples } from './Examples';
import { Alert, Button } from '@mui/material';
import { Alert, Button, colors } from '@mui/material';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

Expand All @@ -30,7 +30,7 @@ export function Chat({
return (
<Container>
<Main>
<ScrollContainer>
<ScrollContainer followButtonClassName="follow">
{messages.map((m, index) => (
<ChatMessage
message={m.content}
Expand Down Expand Up @@ -60,7 +60,7 @@ export function Chat({
</ScrollContainer>
</Main>
<UserInput>
<ChatInput disabled={disabled} onMessage={onMessage} />
<ChatInput disabled={disabled || thinking} onMessage={onMessage} />
</UserInput>
</Container>
);
Expand Down Expand Up @@ -91,10 +91,21 @@ const UserInput = styled.div`
const ScrollContainer = styled(ScrollToBottom)`
height: calc(100vh - 380px);
flex: 1 1 auto;
.follow {
background-color: ${colors.grey[200]};
color: ${colors.grey[900]};
}
.follow::after {
content: '↓';
font-size: 0.8rem;
position: relative;
left: 0px;
}
`;

const Ellipsis = styled.div`
min-width: 50px;
line-height: 3rem;
font-size: 2.5rem;
height: 10px;
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const Item = styled.div<{ selected: boolean }>`
border-radius: 5px;
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
background-color: ${(p) => (p.selected ? colors.deepPurple[700] : null)};
color: ${(p) => (p.selected ? colors.grey[50] : colors.grey[500])};
color: ${(p) => (p.selected ? colors.grey[50] : colors.grey[900])};
min-width: 185px;
:hover {
Expand Down
2 changes: 1 addition & 1 deletion integration/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@retrospected/integration",
"version": "5.0.3",
"version": "5.1.0",
"description": "Integrations tests",
"main": "index.js",
"directories": {
Expand Down
Loading

0 comments on commit 784efc2

Please sign in to comment.