From 1a53390c7549af9607fbab7e5f072b939f8cdceb Mon Sep 17 00:00:00 2001 From: Antoine Jaussoin Date: Tue, 18 Jul 2023 09:41:19 +0100 Subject: [PATCH] Options to restrict title, grouping, ordering to owner (#556) --- backend/src/common/models.ts | 3 + backend/src/common/types.ts | 3 + backend/src/db/entities/SessionOptions.ts | 10 ++ .../migrations/1689628225524-MoreOptions.ts | 24 ++++ frontend/src/common/models.ts | 3 + frontend/src/common/types.ts | 3 + frontend/src/translations/locales/ar-SA.json | 6 + frontend/src/translations/locales/de-DE.json | 6 + frontend/src/translations/locales/en-GB.json | 6 + frontend/src/translations/locales/es-ES.json | 6 + frontend/src/translations/locales/fr-FR.json | 6 + frontend/src/translations/locales/hu-HU.json | 18 ++- frontend/src/translations/locales/it-IT.json | 6 + frontend/src/translations/locales/ja-JP.json | 6 + frontend/src/translations/locales/nl-NL.json | 6 + frontend/src/translations/locales/pl-PL.json | 6 + frontend/src/translations/locales/pt-BR.json | 6 + frontend/src/translations/locales/pt-PT.json | 6 + frontend/src/translations/locales/uk-UA.json | 6 + frontend/src/translations/locales/zh-CN.json | 6 + frontend/src/translations/locales/zh-TW.json | 6 + frontend/src/views/game/board/Column.tsx | 9 +- .../board/__tests__/permissions-logic.test.ts | 130 ++++++++++++++---- .../views/game/board/header/BoardHeader.tsx | 2 +- .../src/views/game/board/permissions-logic.ts | 46 +++++-- .../sections/posts/PostsSection.tsx | 57 ++++++++ 26 files changed, 343 insertions(+), 49 deletions(-) create mode 100644 backend/src/db/migrations/1689628225524-MoreOptions.ts diff --git a/backend/src/common/models.ts b/backend/src/common/models.ts index 80e89f2a7..9d9d99bb0 100644 --- a/backend/src/common/models.ts +++ b/backend/src/common/models.ts @@ -17,6 +17,9 @@ export const defaultOptions: SessionOptions = { allowTimer: true, timerDuration: 15 * 60, readonlyOnTimerEnd: true, + restrictTitleEditToOwner: false, + restrictReorderingToOwner: false, + restrictGroupingToOwner: false, }; export const defaultSession: Omit = { diff --git a/backend/src/common/types.ts b/backend/src/common/types.ts index 9c0ca79c5..e3fa00e9a 100644 --- a/backend/src/common/types.ts +++ b/backend/src/common/types.ts @@ -60,6 +60,9 @@ export interface SessionOptions { allowGrouping: boolean; allowReordering: boolean; allowCancelVote: boolean; + restrictTitleEditToOwner: boolean; + restrictReorderingToOwner: boolean; + restrictGroupingToOwner: boolean; blurCards: boolean; newPostsFirst: boolean; allowTimer: boolean; diff --git a/backend/src/db/entities/SessionOptions.ts b/backend/src/db/entities/SessionOptions.ts index 3d8d31e68..37373f01e 100644 --- a/backend/src/db/entities/SessionOptions.ts +++ b/backend/src/db/entities/SessionOptions.ts @@ -30,6 +30,12 @@ export default class SessionOptionsEntity { public allowCancelVote: boolean; @Column({ default: true }) public allowTimer: boolean; + @Column({ default: false }) + public restrictTitleEditToOwner: boolean; + @Column({ default: false }) + public restrictReorderingToOwner: boolean; + @Column({ default: false }) + public restrictGroupingToOwner: boolean; @Column({ type: 'numeric', default: 15 * 60 }) public timerDuration: number; @Column({ default: true }) @@ -63,6 +69,10 @@ export default class SessionOptionsEntity { this.allowTimer = optionsWithDefault.allowTimer; this.timerDuration = optionsWithDefault.timerDuration; this.readonlyOnTimerEnd = optionsWithDefault.readonlyOnTimerEnd; + this.restrictTitleEditToOwner = optionsWithDefault.restrictTitleEditToOwner; + this.restrictReorderingToOwner = + optionsWithDefault.restrictReorderingToOwner; + this.restrictGroupingToOwner = optionsWithDefault.restrictGroupingToOwner; } } diff --git a/backend/src/db/migrations/1689628225524-MoreOptions.ts b/backend/src/db/migrations/1689628225524-MoreOptions.ts new file mode 100644 index 000000000..8a2614eeb --- /dev/null +++ b/backend/src/db/migrations/1689628225524-MoreOptions.ts @@ -0,0 +1,24 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MoreOptions1689628225524 implements MigrationInterface { + name = 'MoreOptions1689628225524' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "templates" ADD "options_restrict_title_edit_to_owner" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "templates" ADD "options_restrict_reordering_to_owner" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "templates" ADD "options_restrict_grouping_to_owner" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "sessions" ADD "options_restrict_title_edit_to_owner" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "sessions" ADD "options_restrict_reordering_to_owner" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "sessions" ADD "options_restrict_grouping_to_owner" boolean NOT NULL DEFAULT false`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "sessions" DROP COLUMN "options_restrict_grouping_to_owner"`); + await queryRunner.query(`ALTER TABLE "sessions" DROP COLUMN "options_restrict_reordering_to_owner"`); + await queryRunner.query(`ALTER TABLE "sessions" DROP COLUMN "options_restrict_title_edit_to_owner"`); + await queryRunner.query(`ALTER TABLE "templates" DROP COLUMN "options_restrict_grouping_to_owner"`); + await queryRunner.query(`ALTER TABLE "templates" DROP COLUMN "options_restrict_reordering_to_owner"`); + await queryRunner.query(`ALTER TABLE "templates" DROP COLUMN "options_restrict_title_edit_to_owner"`); + } + +} diff --git a/frontend/src/common/models.ts b/frontend/src/common/models.ts index 80e89f2a7..9d9d99bb0 100644 --- a/frontend/src/common/models.ts +++ b/frontend/src/common/models.ts @@ -17,6 +17,9 @@ export const defaultOptions: SessionOptions = { allowTimer: true, timerDuration: 15 * 60, readonlyOnTimerEnd: true, + restrictTitleEditToOwner: false, + restrictReorderingToOwner: false, + restrictGroupingToOwner: false, }; export const defaultSession: Omit = { diff --git a/frontend/src/common/types.ts b/frontend/src/common/types.ts index 9c0ca79c5..e3fa00e9a 100644 --- a/frontend/src/common/types.ts +++ b/frontend/src/common/types.ts @@ -60,6 +60,9 @@ export interface SessionOptions { allowGrouping: boolean; allowReordering: boolean; allowCancelVote: boolean; + restrictTitleEditToOwner: boolean; + restrictReorderingToOwner: boolean; + restrictGroupingToOwner: boolean; blurCards: boolean; newPostsFirst: boolean; allowTimer: boolean; diff --git a/frontend/src/translations/locales/ar-SA.json b/frontend/src/translations/locales/ar-SA.json index 0d83a22b6..271aa3030 100644 --- a/frontend/src/translations/locales/ar-SA.json +++ b/frontend/src/translations/locales/ar-SA.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "السماح بإنشاء مجموعات لتجميع المشاركات معا", "allowReordering": "السماح بإعادة الطلب", "allowReorderingHelp": "السماح بإعادة ترتيب المشاركات بسحب وإسقاط", + "restrictTitleEditToOwner": "تقييد تحرير العنوان إلى المالك", + "restrictTitleEditToOwnerHelp": "لا يستطيع تغيير ملكيته إلا مالك الارتداد", + "restrictReorderingToOwner": "تقييد إعادة الطلب إلى المالك", + "restrictReorderingToOwnerHelp": "لا يستطيع إعادة ترتيب الوظائف إلا مالك الكاتب بأثر رجعي", + "restrictGroupingToOwner": "تقييد التجميع إلى المالك", + "restrictGroupingToOwnerHelp": "لا يستطيع إنشاء مجموعات إلا مالك الارتداد", "blurCards": "طمس البطاقات", "blurCardsHelp": "محتوى البطاقات غير واضح حتى يكشف المشرف عن المحتوى", "template": "قالب", diff --git a/frontend/src/translations/locales/de-DE.json b/frontend/src/translations/locales/de-DE.json index 7800bfd59..da163e59f 100644 --- a/frontend/src/translations/locales/de-DE.json +++ b/frontend/src/translations/locales/de-DE.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Erstelle Gruppen, um Beiträge zusammenzufassen", "allowReordering": "Neu sortieren erlauben", "allowReorderingHelp": "Erlaubt die Beiträge per Drag-and-Drop neu zu sortieren", + "restrictTitleEditToOwner": "Titelbearbeitung auf Eigentümer beschränken", + "restrictTitleEditToOwnerHelp": "Nur der Besitzer einer Retrospektive kann seinen Titel ändern", + "restrictReorderingToOwner": "Neubestellung auf Eigentümer beschränken", + "restrictReorderingToOwnerHelp": "Nur der Besitzer einer Retrospektive kann Beiträge neu bestellen", + "restrictGroupingToOwner": "Gruppierung auf Besitzer beschränken", + "restrictGroupingToOwnerHelp": "Nur der Besitzer einer Retrospektive kann Gruppen erstellen", "blurCards": "Unscharfe Karten", "blurCardsHelp": "Karteninhalte werden verschwommen dargestellt, bis der Moderator den Inhalt aufdeckt", "template": "Vorlage", diff --git a/frontend/src/translations/locales/en-GB.json b/frontend/src/translations/locales/en-GB.json index 8f926013f..fa556d924 100644 --- a/frontend/src/translations/locales/en-GB.json +++ b/frontend/src/translations/locales/en-GB.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Allow the creation of groups to group posts together", "allowReordering": "Allow Re-ordering", "allowReorderingHelp": "Allow re-ordering posts by drag-and-drop", + "restrictTitleEditToOwner": "Restrict title editing to owner", + "restrictTitleEditToOwnerHelp": "Only the owner of a retrospective is able to change its title", + "restrictReorderingToOwner": "Restrict re-ordering to owner", + "restrictReorderingToOwnerHelp": "Only the owner of a retrospective is able to re-order posts", + "restrictGroupingToOwner": "Restrict grouping to owner", + "restrictGroupingToOwnerHelp": "Only the owner of a retrospective is able to create groups", "blurCards": "Blur Cards", "blurCardsHelp": "Cards content is blurred until the moderator reveals the content", "template": "Template", diff --git a/frontend/src/translations/locales/es-ES.json b/frontend/src/translations/locales/es-ES.json index f02a6b9d3..db0be3949 100644 --- a/frontend/src/translations/locales/es-ES.json +++ b/frontend/src/translations/locales/es-ES.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Permitir la creación de grupos agrupar mensajes juntos", "allowReordering": "Permitir reordenar", "allowReorderingHelp": "Permitir reordenar mensajes por arrastrar y soltar", + "restrictTitleEditToOwner": "Restringir la edición del título al propietario", + "restrictTitleEditToOwnerHelp": "Sólo el propietario de una retrospectiva puede cambiar su título", + "restrictReorderingToOwner": "Restringir reordenar al propietario", + "restrictReorderingToOwnerHelp": "Sólo el propietario de un retrospective puede reordenar los posts", + "restrictGroupingToOwner": "Restringir agrupación al propietario", + "restrictGroupingToOwnerHelp": "Sólo el dueño de un retrospective puede crear grupos", "blurCards": "Desenfocar tarjetas", "blurCardsHelp": "El contenido de las tarjetas está desenfocado hasta que el moderador revele el contenido", "template": "Plantilla", diff --git a/frontend/src/translations/locales/fr-FR.json b/frontend/src/translations/locales/fr-FR.json index 48717fe75..c7d5d50d5 100644 --- a/frontend/src/translations/locales/fr-FR.json +++ b/frontend/src/translations/locales/fr-FR.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Permettre aux utilisateurs de grouper les posts par groupes", "allowReordering": "Re-organiser", "allowReorderingHelp": "Permettre aux utilisateurs de réorganiser l'ordre des posts", + "restrictTitleEditToOwner": "Restreindre l'édition du titre à l'admin", + "restrictTitleEditToOwnerHelp": "Seul l'admin d'une rétrospective est en mesure de changer son titre", + "restrictReorderingToOwner": "Limiter la réorganisation (drag-and-drop) des posts à l'admin", + "restrictReorderingToOwnerHelp": "Seul l'admin d'une rétrospective est en mesure de réorganiser les posts", + "restrictGroupingToOwner": "Restreindre la création de groupes à l'admin", + "restrictGroupingToOwnerHelp": "Seul l'admin d'une rétrospective peut créer et réordonner des groupes", "blurCards": "Flouter", "blurCardsHelp": "Les posts sont floutés, jusqu'à ce qu'un modérateur révèle les posts", "template": "Modèles", diff --git a/frontend/src/translations/locales/hu-HU.json b/frontend/src/translations/locales/hu-HU.json index c7a957590..be5df9677 100644 --- a/frontend/src/translations/locales/hu-HU.json +++ b/frontend/src/translations/locales/hu-HU.json @@ -26,7 +26,7 @@ "welcome": "", "anonWarning": "", "howDoesThatWork": "Hogyan működik?", - "login": "", + "login": "Belépés", "searchNoMatch": "", "proNotSetupWarning": "", "proNotSetupWarningAction": "" @@ -110,6 +110,12 @@ "allowGroupingHelp": "Csoportok létrehozásának engedélyezése a bejegyzések csoportosításához", "allowReordering": "Újrarendelés engedélyezése", "allowReorderingHelp": "A bejegyzések átrendezésének engedélyezése fogd és vidd módszerrel", + "restrictTitleEditToOwner": "", + "restrictTitleEditToOwnerHelp": "", + "restrictReorderingToOwner": "", + "restrictReorderingToOwnerHelp": "", + "restrictGroupingToOwner": "", + "restrictGroupingToOwnerHelp": "", "blurCards": "Kártyák elmosódása", "blurCardsHelp": "A kártyák tartalma elmosódik, amíg a moderátor fel nem fedi a tartalmat", "template": "Sablon", @@ -184,7 +190,7 @@ "Clients": { "header": "Jelenleg itt van:", "joined": "{{users}} csatlakozott.", - "left": "{{users}} maradt." + "left": "{{users}} távozott." }, "Join": { "welcome": "Üdv, ez itt a Retrospected", @@ -222,7 +228,7 @@ "passwordField": "Jelszó", "nameField": "Az Ön neve (megjelenítési célból)", "noAuthWarning": "", - "or": "", + "or": "vagy", "passwordScoreWords": [ "gyenge", "gyenge", @@ -271,7 +277,7 @@ "copySuccessful": "Sikeresen másolta az összefoglalót a vágólapra" }, "SessionName": { - "defaultSessionName": "Retrospektívám" + "defaultSessionName": "Retro" }, "Invite": { "inviteButton": "Meghívás", @@ -492,13 +498,13 @@ "stopTimerTitle": "", "stopTimerDescription": "", "stopTimerButton": "", - "stopTimerCancelButton": "" + "stopTimerCancelButton": "Megszünteti" }, "Ai": { "title": "", "info": "", "disabledAnonymous": "", - "close": "", + "close": "Bezárás", "paidLimitWarning": "", "freeLimitWarning": "", "genericError": "", diff --git a/frontend/src/translations/locales/it-IT.json b/frontend/src/translations/locales/it-IT.json index a2240e833..72a8504d2 100644 --- a/frontend/src/translations/locales/it-IT.json +++ b/frontend/src/translations/locales/it-IT.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Permetti la creazione di gruppi per raggruppare post", "allowReordering": "Consenti il riordinamento", "allowReorderingHelp": "Permetti il riordinamento dei post con il trascinamento", + "restrictTitleEditToOwner": "Limita la modifica del titolo al proprietario", + "restrictTitleEditToOwnerHelp": "Solo il proprietario di una retrospettiva è in grado di cambiare il suo titolo", + "restrictReorderingToOwner": "Limita riordinamento al proprietario", + "restrictReorderingToOwnerHelp": "Solo il proprietario di una retrospettiva è in grado di riordinare i post", + "restrictGroupingToOwner": "Limita raggruppamento al proprietario", + "restrictGroupingToOwnerHelp": "Solo il proprietario di una retrospettiva è in grado di creare gruppi", "blurCards": "Sfoca Carte", "blurCardsHelp": "Il contenuto delle carte è sfocato finché il moderatore non rivela il contenuto", "template": "Modello", diff --git a/frontend/src/translations/locales/ja-JP.json b/frontend/src/translations/locales/ja-JP.json index d7e36763a..35da1eafc 100644 --- a/frontend/src/translations/locales/ja-JP.json +++ b/frontend/src/translations/locales/ja-JP.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "投稿をグループ化するグループの作成を許可する", "allowReordering": "並べ替えを許可", "allowReorderingHelp": "ドラッグ&ドロップで投稿の並べ替えを許可する", + "restrictTitleEditToOwner": "タイトル編集を所有者に制限", + "restrictTitleEditToOwnerHelp": "回顧展の所有者のみがタイトルを変更できます", + "restrictReorderingToOwner": "再順序を所有者に制限", + "restrictReorderingToOwnerHelp": "レトロスペクティブの所有者のみ投稿を再注文できます", + "restrictGroupingToOwner": "グループ化を所有者に制限", + "restrictGroupingToOwnerHelp": "レトロスペクティブの所有者のみがグループを作成できます", "blurCards": "ぼかしカード", "blurCardsHelp": "モデレーターがコンテンツを表示するまでカードの内容がぼかしています", "template": "テンプレート", diff --git a/frontend/src/translations/locales/nl-NL.json b/frontend/src/translations/locales/nl-NL.json index a1358baa4..d34a4df2e 100644 --- a/frontend/src/translations/locales/nl-NL.json +++ b/frontend/src/translations/locales/nl-NL.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Aanmaken van groepen van retropunten toestaan.", "allowReordering": "Herordenen toestaan", "allowReorderingHelp": "Toestaan om retropunten mbv drag-en-drop te herordenen", + "restrictTitleEditToOwner": "Beperk titelbewerking tot eigenaar", + "restrictTitleEditToOwnerHelp": "Alleen de eigenaar van een retrospectief kan zijn titel wijzigen", + "restrictReorderingToOwner": "Beperk herschikken tot eigenaar", + "restrictReorderingToOwnerHelp": "Alleen de eigenaar van een retrospectief kan posts opnieuw bestellen", + "restrictGroupingToOwner": "Beperk groepering tot eigenaar", + "restrictGroupingToOwnerHelp": "Alleen de eigenaar van een retrospectief kan groepen maken", "blurCards": "Vervaag Kaarten", "blurCardsHelp": "Inhoud van kaarten wordt vervaagd totdat de moderator de inhoud onthult", "template": "Sjabloon", diff --git a/frontend/src/translations/locales/pl-PL.json b/frontend/src/translations/locales/pl-PL.json index 8c9b6ac54..044f41fe6 100644 --- a/frontend/src/translations/locales/pl-PL.json +++ b/frontend/src/translations/locales/pl-PL.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Pozwól tworzyć grupy do grupowania postów", "allowReordering": "Zezwalaj na ponowne zamawianie", "allowReorderingHelp": "Zezwalaj na zmianę kolejności postów przez przeciąganie i upuszczanie", + "restrictTitleEditToOwner": "Ogranicz edycję tytułu do właściciela", + "restrictTitleEditToOwnerHelp": "Tylko właściciel retrospektywnie może zmienić swój tytuł", + "restrictReorderingToOwner": "Ogranicz kolejność do właściciela", + "restrictReorderingToOwnerHelp": "Tylko właściciel retrospektywnie może zmienić kolejność postów", + "restrictGroupingToOwner": "Ogranicz grupowanie do właściciela", + "restrictGroupingToOwnerHelp": "Tylko właściciel retrospektywnie jest w stanie tworzyć grupy", "blurCards": "Rozmycie kart", "blurCardsHelp": "Zawartość kart jest rozmyta aż moderator ujawni zawartość", "template": "Szablon", diff --git a/frontend/src/translations/locales/pt-BR.json b/frontend/src/translations/locales/pt-BR.json index 5a853a5dd..c0d61cb6f 100644 --- a/frontend/src/translations/locales/pt-BR.json +++ b/frontend/src/translations/locales/pt-BR.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Permitir a criação de grupos para agrupar postagens", "allowReordering": "Permitir reordenação", "allowReorderingHelp": "Permitir reordenação de postagens arrastando-se-e-soltar", + "restrictTitleEditToOwner": "Restringir edição do título ao proprietário", + "restrictTitleEditToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de alterar seu título", + "restrictReorderingToOwner": "Restringir reordenação ao proprietário", + "restrictReorderingToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de reordenar postagens", + "restrictGroupingToOwner": "Restringir agrupamento ao proprietário", + "restrictGroupingToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de criar grupos", "blurCards": "Cartões de Desfoque", "blurCardsHelp": "O conteúdo dos cartões fica desfocado até que o moderador revele o conteúdo", "template": "Modelo", diff --git a/frontend/src/translations/locales/pt-PT.json b/frontend/src/translations/locales/pt-PT.json index d0a831c44..45707acf9 100644 --- a/frontend/src/translations/locales/pt-PT.json +++ b/frontend/src/translations/locales/pt-PT.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Permitir a criação de grupos para agrupar postagens", "allowReordering": "Permitir reordenação", "allowReorderingHelp": "Permitir reordenação de postagens arrastando-se-e-soltar", + "restrictTitleEditToOwner": "Restringir edição do título ao proprietário", + "restrictTitleEditToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de alterar seu título", + "restrictReorderingToOwner": "Restringir reordenação ao proprietário", + "restrictReorderingToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de reordenar postagens", + "restrictGroupingToOwner": "Restringir agrupamento ao proprietário", + "restrictGroupingToOwnerHelp": "Somente o proprietário de um retrospectivo é capaz de criar grupos", "blurCards": "Cartões de Desfoque", "blurCardsHelp": "O conteúdo dos cartões fica desfocado até que o moderador revele o conteúdo", "template": "Modelo", diff --git a/frontend/src/translations/locales/uk-UA.json b/frontend/src/translations/locales/uk-UA.json index 648d9a149..72400c6d9 100644 --- a/frontend/src/translations/locales/uk-UA.json +++ b/frontend/src/translations/locales/uk-UA.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "Дозволити створення груп для групових повідомлень", "allowReordering": "Дозволити повторне замовлення", "allowReorderingHelp": "Дозволити перегрупування матеріалів перетягуванням", + "restrictTitleEditToOwner": "Обмежувати редагування заголовків власнику", + "restrictTitleEditToOwnerHelp": "Лише власник ретроспективу може змінити його назву", + "restrictReorderingToOwner": "Обмежити повторне замовлення власника", + "restrictReorderingToOwnerHelp": "Тільки власник ретроспективи може змінити порядок постів", + "restrictGroupingToOwner": "Обмежити групування власника", + "restrictGroupingToOwnerHelp": "Тільки власник ретроспективу здатний створювати групи", "blurCards": "Розмиті картки", "blurCardsHelp": "Зміст карт буде розмитим, поки модератор не отримає вміст", "template": "Шаблон", diff --git a/frontend/src/translations/locales/zh-CN.json b/frontend/src/translations/locales/zh-CN.json index cd19f8adc..6000ee254 100644 --- a/frontend/src/translations/locales/zh-CN.json +++ b/frontend/src/translations/locales/zh-CN.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "允许创建群组将帖子一起分组", "allowReordering": "允许重新排序", "allowReorderingHelp": "允许通过拖放重新排序帖子", + "restrictTitleEditToOwner": "限制标题编辑到所有者", + "restrictTitleEditToOwnerHelp": "只有追溯性的所有者能够更改其标题", + "restrictReorderingToOwner": "限制重新排序到所有者", + "restrictReorderingToOwnerHelp": "只有追溯性的所有者可以重新排序帖子", + "restrictGroupingToOwner": "限制分组到所有者", + "restrictGroupingToOwnerHelp": "只有追溯性的所有者能够创建组", "blurCards": "模糊卡", "blurCardsHelp": "在版主显示内容之前,卡片内容是模糊的", "template": "模板", diff --git a/frontend/src/translations/locales/zh-TW.json b/frontend/src/translations/locales/zh-TW.json index 2d1b13358..45267d549 100644 --- a/frontend/src/translations/locales/zh-TW.json +++ b/frontend/src/translations/locales/zh-TW.json @@ -110,6 +110,12 @@ "allowGroupingHelp": "允許創建組以將帖子分組在一起", "allowReordering": "允許重新訂購", "allowReorderingHelp": "允許通過拖放重新排序帖子", + "restrictTitleEditToOwner": "", + "restrictTitleEditToOwnerHelp": "", + "restrictReorderingToOwner": "", + "restrictReorderingToOwnerHelp": "", + "restrictGroupingToOwner": "", + "restrictGroupingToOwnerHelp": "", "blurCards": "模糊卡片", "blurCardsHelp": "卡片內容模糊,直到版主顯示內容", "template": "模板", diff --git a/frontend/src/views/game/board/Column.tsx b/frontend/src/views/game/board/Column.tsx index 8d90a1055..e141db7d1 100644 --- a/frontend/src/views/game/board/Column.tsx +++ b/frontend/src/views/game/board/Column.tsx @@ -171,7 +171,11 @@ const Column: React.FC = ({ ))} - + {( dropProvided: DroppableProvided, dropSnapshot: DroppableStateSnapshot @@ -236,7 +240,8 @@ 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; `; diff --git a/frontend/src/views/game/board/__tests__/permissions-logic.test.ts b/frontend/src/views/game/board/__tests__/permissions-logic.test.ts index 9b5e8b6f5..13c27eee8 100644 --- a/frontend/src/views/game/board/__tests__/permissions-logic.test.ts +++ b/frontend/src/views/game/board/__tests__/permissions-logic.test.ts @@ -178,6 +178,40 @@ describe('Session Permission Logic', () => { expect(result.canCreateGroup).toBe(false); expect(result.hasReachedMaxPosts).toBe(false); }); + + it('When restricting grouping to owner', () => { + const s = session({ + ...defaultOptions, + allowGrouping: true, + restrictGroupingToOwner: true, + }); + const result = sessionPermissionLogic(s, currentUser, true, false); + expect(result.canCreateGroup).toBe(true); + const forAnotherUser = sessionPermissionLogic(s, anotherUser, true, false); + expect(forAnotherUser.canCreateGroup).toBe(false); + }); + + it('When restricting editing the title to owner', () => { + const s = session({ + ...defaultOptions, + restrictTitleEditToOwner: true, + }); + const result = sessionPermissionLogic(s, currentUser, true, false); + expect(result.canEditTitle).toBe(true); + const forAnotherUser = sessionPermissionLogic(s, anotherUser, true, false); + expect(forAnotherUser.canEditTitle).toBe(false); + }); + + it('When restricting re-ordering to owner', () => { + const s = session({ + ...defaultOptions, + restrictReorderingToOwner: true, + }); + const result = sessionPermissionLogic(s, currentUser, true, false); + expect(result.canReorderPosts).toBe(true); + const forAnotherUser = sessionPermissionLogic(s, anotherUser, true, false); + expect(forAnotherUser.canReorderPosts).toBe(false); + }); }); describe('Posts Permission Logic', () => { @@ -476,32 +510,6 @@ describe('Posts Permission Logic', () => { expect(result.canReorder).toBe(false); }); - it('When allowing grouping', () => { - const p = post(anotherUser, [currentUser, currentUser, currentUser]); - const s = session( - { - ...defaultOptions, - allowGrouping: true, - }, - p - ); - const result = postPermissionLogic(p, s, capabilities, currentUser, false); - expect(result.canCreateGroup).toBe(true); - }); - - it('When disallowing grouping', () => { - const p = post(anotherUser, [currentUser, currentUser, currentUser]); - const s = session( - { - ...defaultOptions, - allowGrouping: false, - }, - p - ); - const result = postPermissionLogic(p, s, capabilities, currentUser, false); - expect(result.canCreateGroup).toBe(false); - }); - it('When cards are not blurred, for another user card', () => { const p = post(anotherUser, [currentUser]); const s = session( @@ -580,4 +588,74 @@ describe('Posts Permission Logic', () => { const result = postPermissionLogic(p, s, capabilities, currentUser, false); expect(result.canCancelVote).toBe(false); }); + + it('By default it should not show authors', () => { + const p = post(anotherUser, [currentUser]); + const s = session( + { + ...defaultOptions, + }, + p + ); + const result = postPermissionLogic(p, s, capabilities, currentUser, false); + expect(result.canShowAuthor).toBe(false); + }); + + it('If show author is enabled', () => { + const p = post(anotherUser, [currentUser]); + const s = session( + { + ...defaultOptions, + allowAuthorVisible: true, + }, + p + ); + const result = postPermissionLogic(p, s, capabilities, currentUser, false); + expect(result.canShowAuthor).toBe(true); + }); + + it('If show author is restricted across the board', () => { + const p = post(anotherUser, [currentUser]); + const s = session( + { + ...defaultOptions, + allowAuthorVisible: true, + }, + p + ); + const c: BackendCapabilities = { + ...capabilities, + disableShowAuthor: true, + }; + const result = postPermissionLogic(p, s, c, currentUser, false); + expect(result.canShowAuthor).toBe(false); + }); + + it('Can re-order if restricted to owner and not owner', () => { + const p = post(anotherUser, [currentUser]); + const s = session( + { + ...defaultOptions, + allowReordering: true, + restrictReorderingToOwner: true, + }, + p + ); + const forOwner = postPermissionLogic( + p, + s, + capabilities, + currentUser, + false + ); + expect(forOwner.canReorder).toBe(true); + const forAnotherUser = postPermissionLogic( + p, + s, + capabilities, + anotherUser, + false + ); + expect(forAnotherUser.canReorder).toBe(false); + }); }); diff --git a/frontend/src/views/game/board/header/BoardHeader.tsx b/frontend/src/views/game/board/header/BoardHeader.tsx index 2d670de8a..18ea558fb 100644 --- a/frontend/src/views/game/board/header/BoardHeader.tsx +++ b/frontend/src/views/game/board/header/BoardHeader.tsx @@ -150,7 +150,7 @@ function BoardHeader({ value={decrypt(session.name)} centered onChange={handleRenameSession} - readOnly={!isLoggedIn || !canDecrypt} + readOnly={!isLoggedIn || !canDecrypt || !permissions.canEditTitle} /> diff --git a/frontend/src/views/game/board/permissions-logic.ts b/frontend/src/views/game/board/permissions-logic.ts index d659f314d..25b5db6dd 100644 --- a/frontend/src/views/game/board/permissions-logic.ts +++ b/frontend/src/views/game/board/permissions-logic.ts @@ -4,6 +4,8 @@ import some from 'lodash/some'; export interface SessionUserPermissions { canCreatePost: boolean; canCreateGroup: boolean; + canEditTitle: boolean; + canReorderPosts: boolean; hasReachedMaxPosts: boolean; } @@ -13,23 +15,38 @@ export function sessionPermissionLogic( canDecrypt: boolean, readonly: boolean ): SessionUserPermissions { - const numberOfPosts = - session && user - ? session.posts.filter((p) => p.user.id === user.id).length - : 0; + if (!session || !user) { + return { + canCreatePost: false, + canCreateGroup: false, + canEditTitle: false, + canReorderPosts: false, + hasReachedMaxPosts: false, + }; + } + const isOwner = user.id === session.createdBy.id; + const numberOfPosts = session.posts.filter( + (p) => p.user.id === user.id + ).length; const hasReachedMaxPosts = - !!session && session.options.maxPosts !== null && session.options.maxPosts <= numberOfPosts; - const canCreatePost = - !!user && canDecrypt && !readonly && !hasReachedMaxPosts; + const canCreatePost = canDecrypt && !readonly && !hasReachedMaxPosts; const canCreateGroup = - canCreatePost && !!session && session.options.allowGrouping; + canCreatePost && + session.options.allowGrouping && + (isOwner || !session.options.restrictGroupingToOwner); + const canEditTitle = + !readonly && (isOwner || !session.options.restrictTitleEditToOwner); + const canReorderPosts = + !readonly && (isOwner || !session.options.restrictReorderingToOwner); return { canCreatePost, canCreateGroup, + canEditTitle, + canReorderPosts, hasReachedMaxPosts, }; } @@ -45,7 +62,6 @@ export interface PostUserPermissions { canShowAuthor: boolean; canUseGiphy: boolean; canReorder: boolean; - canCreateGroup: boolean; canCancelVote: boolean; isBlurred: boolean; } @@ -69,7 +85,6 @@ export function postPermissionLogic( canDisplayDownVote: false, canDisplayUpVote: false, canReorder: false, - canCreateGroup: false, canCancelVote: false, isBlurred: false, }; @@ -82,9 +97,9 @@ export function postPermissionLogic( allowMultipleVotes, allowAuthorVisible, allowGiphy, - allowGrouping, allowReordering, allowCancelVote, + restrictReorderingToOwner, blurCards, } = session.options; @@ -92,6 +107,7 @@ export function postPermissionLogic( const canCreateAction = !readonly && isLoggedIn && allowActions; const userId = user ? user.id : -1; const isAuthor = user ? user.id === post.user.id : false; + const isOwner = user ? user.id === session.createdBy.id : false; const canPotentiallyVote = !readonly && isLoggedIn && allowSelfVoting ? true : !isAuthor; const hasVoted = some(post.votes, (u) => u.userId === userId); @@ -116,8 +132,11 @@ export function postPermissionLogic( const canDelete = !readonly && isLoggedIn && isAuthor; const canShowAuthor = allowAuthorVisible && !capabilities.disableShowAuthor; const canUseGiphy = isLoggedIn && allowGiphy; - const canReorder = !readonly && isLoggedIn && allowReordering; - const canCreateGroup = !readonly && isLoggedIn && allowGrouping; + const canReorder = + !readonly && + isLoggedIn && + allowReordering && + (isOwner || !restrictReorderingToOwner); const canCancelVote = !readonly && hasVoted && allowCancelVote; const isBlurred = blurCards && !isAuthor; @@ -131,7 +150,6 @@ export function postPermissionLogic( canDelete, canShowAuthor, canUseGiphy, - canCreateGroup, canReorder, canCancelVote, isBlurred, diff --git a/frontend/src/views/session-editor/sections/posts/PostsSection.tsx b/frontend/src/views/session-editor/sections/posts/PostsSection.tsx index f214a1158..4745d4d24 100644 --- a/frontend/src/views/session-editor/sections/posts/PostsSection.tsx +++ b/frontend/src/views/session-editor/sections/posts/PostsSection.tsx @@ -96,6 +96,36 @@ function PostsSection({ options, onChange }: PostsSectionProps) { [onChange, options] ); + const setRestrictReorderingToOwner = useCallback( + (value: boolean) => { + onChange({ + ...options, + restrictReorderingToOwner: value, + }); + }, + [onChange, options] + ); + + const setRestrictGroupingToOwner = useCallback( + (value: boolean) => { + onChange({ + ...options, + restrictGroupingToOwner: value, + }); + }, + [onChange, options] + ); + + const setRestrictTitleEditToOwner = useCallback( + (value: boolean) => { + onChange({ + ...options, + restrictTitleEditToOwner: value, + }); + }, + [onChange, options] + ); + return ( + + + + + + + + +