diff --git a/api/fixtures/campCollaborations.yml b/api/fixtures/campCollaborations.yml
index 87e8088174..f345312b04 100644
--- a/api/fixtures/campCollaborations.yml
+++ b/api/fixtures/campCollaborations.yml
@@ -9,6 +9,8 @@ App\Entity\CampCollaboration:
camp: '@camp1'
status: established
role: member
+ abbreviation: "🧑🏽🚀"
+ color: "#11a1e1"
campCollaboration3guest:
user: '@user3guest'
camp: '@camp1'
diff --git a/api/fixtures/profiles.yml b/api/fixtures/profiles.yml
index d4b184a86a..024fffe900 100644
--- a/api/fixtures/profiles.yml
+++ b/api/fixtures/profiles.yml
@@ -6,6 +6,8 @@ App\Entity\Profile:
surname: Baden-Powell
nickname: Bi-Pi
language: en
+ abbreviation: '⚜️'
+ color: '#6a209b'
roles: [ 'ROLE_USER' ]
profile2member:
user: '@user2member'
diff --git a/api/migrations/dev-data/Version202404121950.php b/api/migrations/dev-data/Version202404121950.php
index 82166b1d9e..da25cf7867 100644
--- a/api/migrations/dev-data/Version202404121950.php
+++ b/api/migrations/dev-data/Version202404121950.php
@@ -16,14 +16,6 @@ public function getDescription(): string {
public function up(Schema $schema): void {
// START PHP CODE
- $this->addSql(createTruncateDatabaseCommand());
-
- $statements = getStatementsForMigrationFile();
- foreach ($statements as $statement) {
- if (trim($statement)) {
- $this->addSql($statement);
- }
- }
// END PHP CODE
}
diff --git a/api/migrations/dev-data/Version202406211251.php b/api/migrations/dev-data/Version202406211251.php
new file mode 100644
index 0000000000..a4ae84b459
--- /dev/null
+++ b/api/migrations/dev-data/Version202406211251.php
@@ -0,0 +1,31 @@
+addSql(createTruncateDatabaseCommand());
+
+ $statements = getStatementsForMigrationFile();
+ foreach ($statements as $statement) {
+ if (trim($statement)) {
+ $this->addSql($statement);
+ }
+ }
+ // END PHP CODE
+ }
+
+ public function down(Schema $schema): void {}
+}
diff --git a/api/migrations/dev-data/data.sql b/api/migrations/dev-data/data.sql
index 807e1f3b54..dc7516a945 100644
--- a/api/migrations/dev-data/data.sql
+++ b/api/migrations/dev-data/data.sql
@@ -2,22 +2,22 @@
-INSERT INTO public.profile (id, email, firstname, surname, nickname, language, roles, createtime, updatetime, googleid, pbsmidataid, cevidbid, untrustedemail, untrustedemailkeyhash, jubladbid) VALUES
- ('711ad2e96f9f', 'admin@example.com', 'Admi', 'Nistrator', 'Administrator', 'de', '["ROLE_USER", "ROLE_ADMIN"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
- ('5e387cad273d', 'test@example.com', 'Robert', 'Baden-Powell', 'Bi-Pi', 'de-CH-scout', '["ROLE_USER"]', '2022-01-23 16:19:10', '2023-08-08 09:11:11', NULL, NULL, NULL, NULL, NULL, NULL),
- ('0870635edda6', 'idefix@example.com', 'Tremaine', 'Kohler', 'Idefix', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:18:43', NULL, NULL, NULL, NULL, NULL, NULL),
- ('4cda72af2704', 'et@example.com', 'Karlie', 'Terry', 'ET', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:21:43', NULL, NULL, NULL, NULL, NULL, NULL),
- ('22dce794d4e2', 'snoopy@example.com', 'Pat', 'Fadel', 'Snoopy', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:19:40', NULL, NULL, NULL, NULL, NULL, NULL),
- ('d46337a76a2c', 'salamander@example.com', 'Fritz', 'Müller', 'Salamander', 'de', '["ROLE_USER"]', '2022-02-04 19:26:22', '2022-02-04 23:08:12', NULL, NULL, NULL, NULL, NULL, NULL),
- ('f9f1a2f9af25', 'baghira@example.com', 'Zora', 'Steuber', 'Baghira', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:18:01', NULL, NULL, NULL, NULL, NULL, NULL),
- ('7d03c967be7e', 'castor@example.com', 'Hans', 'Muster', 'Castor', 'de', '["ROLE_USER"]', '2022-02-04 19:25:07', '2022-02-04 23:07:57', NULL, NULL, NULL, NULL, NULL, NULL),
- ('d36197370d44', 'sed@example.com', 'Clifford', 'Beier', 'sed', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
- ('e5433660140b', 'sit@example.com', 'Wanda', 'Koelpin', 'sit', 'en', '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
- ('4bc441dc4b29', 'luke@skywalker.com', 'Luke', 'Skywalker', NULL, 'en', '["ROLE_USER"]', '2023-08-12 16:43:34', '2023-08-12 16:43:34', NULL, NULL, NULL, NULL, NULL, NULL),
- ('5552108bf43e', 'john@wick.com', 'John', 'Wick', NULL, 'en', '["ROLE_USER"]', '2023-08-12 16:46:43', '2023-08-12 16:46:43', NULL, NULL, NULL, NULL, NULL, NULL),
- ('abfcbcbd4566', 'clark@kent.com', 'Clark', 'Kent', NULL, 'en', '["ROLE_USER"]', '2023-08-12 16:49:27', '2023-08-12 16:49:27', NULL, NULL, NULL, NULL, NULL, NULL),
- ('3f3fa9319dd2', 'bruce@wayne.com', 'Bruce', 'Wayne', NULL, 'en', '["ROLE_USER"]', '2023-08-12 16:55:28', '2023-08-12 16:55:28', NULL, NULL, NULL, NULL, NULL, NULL),
- ('51245d0e2ad4', 'felicity@smoak.com', 'Felicity', 'Smoak', NULL, 'en', '["ROLE_USER"]', '2023-08-12 16:59:38', '2023-08-12 16:59:38', NULL, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO public.profile (id, email, firstname, surname, nickname, language, color, abbreviation, roles, createtime, updatetime, googleid, pbsmidataid, cevidbid, untrustedemail, untrustedemailkeyhash, jubladbid) VALUES
+ ('711ad2e96f9f', 'admin@example.com', 'Admi', 'Nistrator', 'Administrator', 'de', NULL, NULL, '["ROLE_USER", "ROLE_ADMIN"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('5e387cad273d', 'test@example.com', 'Robert', 'Baden-Powell', 'Bi-Pi', 'de-CH-scout', '#6a209b', '⚜️', '["ROLE_USER"]', '2022-01-23 16:19:10', '2023-08-08 09:11:11', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('0870635edda6', 'idefix@example.com', 'Tremaine', 'Kohler', 'Idefix', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:18:43', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('4cda72af2704', 'et@example.com', 'Karlie', 'Terry', 'ET', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:21:43', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('22dce794d4e2', 'snoopy@example.com', 'Pat', 'Fadel', 'Snoopy', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:19:40', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('d46337a76a2c', 'salamander@example.com', 'Fritz', 'Müller', 'Salamander', 'de', NULL, NULL, '["ROLE_USER"]', '2022-02-04 19:26:22', '2022-02-04 23:08:12', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('f9f1a2f9af25', 'baghira@example.com', 'Zora', 'Steuber', 'Baghira', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-02-04 19:18:01', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('7d03c967be7e', 'castor@example.com', 'Hans', 'Muster', 'Castor', 'de', NULL, 'C', '["ROLE_USER"]', '2022-02-04 19:25:07', '2022-02-04 23:07:57', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('d36197370d44', 'sed@example.com', 'Clifford', 'Beier', 'sed', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('e5433660140b', 'sit@example.com', 'Wanda', 'Koelpin', 'sit', 'en', NULL, NULL, '["ROLE_USER"]', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('4bc441dc4b29', 'luke@skywalker.com', 'Luke', 'Skywalker', NULL, 'en', NULL, NULL, '["ROLE_USER"]', '2023-08-12 16:43:34', '2023-08-12 16:43:34', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('5552108bf43e', 'john@wick.com', 'John', 'Wick', NULL, 'en', NULL, NULL, '["ROLE_USER"]', '2023-08-12 16:46:43', '2023-08-12 16:46:43', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('abfcbcbd4566', 'clark@kent.com', 'Clark', 'Kent', NULL, 'en', NULL, NULL, '["ROLE_USER"]', '2023-08-12 16:49:27', '2023-08-12 16:49:27', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('3f3fa9319dd2', 'bruce@wayne.com', 'Bruce', 'Wayne', NULL, 'en', NULL, NULL, '["ROLE_USER"]', '2023-08-12 16:55:28', '2023-08-12 16:55:28', NULL, NULL, NULL, NULL, NULL, NULL),
+ ('51245d0e2ad4', 'felicity@smoak.com', 'Felicity', 'Smoak', NULL, 'en', NULL, NULL, '["ROLE_USER"]', '2023-08-12 16:59:38', '2023-08-12 16:59:38', NULL, NULL, NULL, NULL, NULL, NULL);
@@ -988,36 +988,36 @@ INSERT INTO public.activity (id, title, location, campid, categoryid, rootconten
-INSERT INTO public.camp_collaboration (id, inviteemail, invitekeyhash, status, role, createtime, updatetime, userid, campid) VALUES
- ('237abf0bd057', 'e.mail2@test.com', 'myInviteKey2', 'invited', 'member', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, '6430aecc5422'),
- ('0e524d43e799', NULL, NULL, 'established', 'manager', '2022-01-23 16:19:10', '2022-01-23 16:19:10', 'e7b00084dabf', '6430aecc5422'),
- ('2c313fa367b3', NULL, NULL, 'established', 'manager', '2022-01-23 16:19:10', '2022-01-23 16:19:10', '3b41dca5c568', 'e5027d852487'),
- ('2b3cf1ce6341', 'x@z.com', 'd12ntPWBK0qmPxfMGg/QRWh98XE=', 'invited', 'member', '2023-08-08 08:03:06', '2023-08-08 08:03:06', NULL, '3c79b99ab424'),
- ('dba39edd9910', NULL, NULL, 'established', 'member', '2023-08-08 07:59:24', '2023-08-08 08:11:28', 'bee7cf5b3871', '3c79b99ab424'),
- ('c88fd78c90ea', NULL, NULL, 'established', 'manager', '2023-08-08 07:58:53', '2023-08-08 08:12:12', 'caeba9f7e728', '3c79b99ab424'),
- ('5111b2972441', 'inactive@test.com', 'Vazgl+0DsuUKrcTezKxA+KmBgOA=', 'inactive', 'member', '2023-08-08 07:59:53', '2023-08-08 09:18:22', NULL, '3c79b99ab424'),
- ('68694999fa8d', NULL, NULL, 'established', 'manager', '2023-08-08 09:22:58', '2023-08-08 09:22:58', '9145944210a7', '6973c230d6b1'),
- ('3229d273decd', NULL, '5eO+mQd6F+AQwCITx5mV8dX9/6U=', 'invited', 'manager', '2023-08-08 09:38:27', '2023-08-08 09:43:11', '130684395770', '6973c230d6b1'),
- ('7cae64a7800c', 'e.mail@test.com', '7FUv2lrEcRjMbW/Nb1mTkBaAPOs=', 'invited', 'member', '2023-08-08 09:37:38', '2023-08-08 09:43:21', NULL, '6973c230d6b1'),
- ('878426563205', NULL, NULL, 'established', 'guest', '2023-08-08 09:36:41', '2023-08-08 09:43:52', '48f00685a292', '6973c230d6b1'),
- ('d27ca1d0e6e4', NULL, NULL, 'established', 'member', '2023-08-08 09:36:01', '2023-08-08 09:44:19', 'bae69a1c9fcc', '6973c230d6b1'),
- ('c463d2a19847', NULL, NULL, 'established', 'member', '2023-08-08 09:38:01', '2023-08-08 09:44:50', 'caeba9f7e728', '6973c230d6b1'),
- ('763c0d181b63', NULL, NULL, 'established', 'manager', '2023-08-08 09:37:16', '2023-08-08 09:45:21', 'bee7cf5b3871', '6973c230d6b1'),
- ('b7d93b2fa1be', NULL, 'mLdsTtaGGptPYSZLUDgX8sAFO54=', 'established', 'member', '2023-08-12 19:10:49', '2023-08-12 19:10:49', 'a2f4f3879c85', '9c2447aefe38'),
- ('ac1cd0bcbd69', NULL, 'V30YTcBqBqs5xS7HrFM4ODRrzbw=', 'established', 'member', '2023-08-12 19:10:28', '2023-08-12 19:10:28', 'a3d9d86dc23b', '9c2447aefe38'),
- ('8be6d2f6f7dc', NULL, 'ru6jsdD9fODk8+p8wmI909rJPkQ=', 'established', 'manager', '2023-08-12 19:11:03', '2023-08-12 19:11:03', '566aea2c2759', '9c2447aefe38'),
- ('0e26982c9895', NULL, 'ao9OQRgXWBpCVaD4lGQaUFzvKwI=', 'established', 'member', '2023-08-12 19:10:14', '2023-08-12 19:10:14', 'dac7116e02ed', '9c2447aefe38'),
- ('b2f127cb410f', NULL, NULL, 'established', 'manager', '2023-08-13 06:32:29', '2023-08-13 06:32:29', 'dac7116e02ed', '0969e3c95dfc'),
- ('d806a59915f8', NULL, 'SuP47raE2s/2hGLsdBiO/icIU0E=', 'established', 'member', '2023-08-13 10:29:25', '2023-08-13 10:29:25', 'a3d9d86dc23b', '0969e3c95dfc'),
- ('7db6a9ffc210', NULL, 'yyXTSd6kGh7kNENlcGDeYtq4ftQ=', 'established', 'guest', '2023-08-13 10:29:47', '2023-08-13 10:29:47', 'a2f4f3879c85', '0969e3c95dfc'),
- ('60a470e1aff6', NULL, 'uGXywHjal9lK+rcdtRBcXh8y5qA=', 'established', 'manager', '2023-08-13 10:29:55', '2023-08-13 10:29:55', '566aea2c2759', '0969e3c95dfc'),
- ('d1c0a4522283', NULL, NULL, 'established', 'manager', '2023-09-29 23:24:38', '2023-09-29 23:24:38', 'dac7116e02ed', '70ca971c992f'),
- ('5b24ce470d9f', NULL, 'XisYzAgXUozfJA1M/y39ow8t5Vw=', 'established', 'member', '2023-09-29 23:27:54', '2023-09-29 23:27:54', 'a3d9d86dc23b', '70ca971c992f'),
- ('46d14f7c072c', NULL, '4KCuIMWvkGVAjSBtAnG5QcesOrI=', 'established', 'manager', '2023-09-29 23:41:30', '2023-09-29 23:41:30', 'a2f4f3879c85', '70ca971c992f'),
- ('b0bdb7202a9d', NULL, NULL, 'established', 'manager', '2023-08-08 07:53:12', '2023-08-08 07:53:12', '9145944210a7', '3c79b99ab424'),
- ('b00054c3c03e', NULL, 'XC/b4erYO0iZZTBEXOi3n/4AH9w=', 'established', 'guest', '2023-08-13 10:29:08', '2023-08-13 10:29:08', '9145944210a7', '0969e3c95dfc'),
- ('10d8f02ce5b4', NULL, 'n1MKxMj1RWkrcSmNfHdjUxKV3QY=', 'established', 'guest', '2023-09-29 23:25:49', '2023-09-29 23:25:49', '9145944210a7', '70ca971c992f'),
- ('b32db30637c8', NULL, 'AC/b4erYO0iZZTBEXOi3n/4AH9w=', 'invited', 'manager', '2023-08-12 17:41:55', '2023-08-12 17:41:55', '9145944210a7', '9c2447aefe38');
+INSERT INTO public.camp_collaboration (id, inviteemail, invitekeyhash, status, color, abbreviation, role, createtime, updatetime, userid, campid) VALUES
+ ('237abf0bd057', 'e.mail2@test.com', 'myInviteKey2', 'invited', NULL, NULL, 'member', '2022-01-23 16:19:10', '2022-01-23 16:19:10', NULL, '6430aecc5422'),
+ ('0e524d43e799', NULL, NULL, 'established', NULL, NULL, 'manager', '2022-01-23 16:19:10', '2022-01-23 16:19:10', 'e7b00084dabf', '6430aecc5422'),
+ ('2c313fa367b3', NULL, NULL, 'established', NULL, NULL, 'manager', '2022-01-23 16:19:10', '2022-01-23 16:19:10', '3b41dca5c568', 'e5027d852487'),
+ ('2b3cf1ce6341', 'x@z.com', 'd12ntPWBK0qmPxfMGg/QRWh98XE=', 'invited', NULL, NULL, 'member', '2023-08-08 08:03:06', '2023-08-08 08:03:06', NULL, '3c79b99ab424'),
+ ('dba39edd9910', NULL, NULL, 'established', NULL, NULL, 'member', '2023-08-08 07:59:24', '2023-08-08 08:11:28', 'bee7cf5b3871', '3c79b99ab424'),
+ ('c88fd78c90ea', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-08-08 07:58:53', '2023-08-08 08:12:12', 'caeba9f7e728', '3c79b99ab424'),
+ ('5111b2972441', 'inactive@test.com', 'Vazgl+0DsuUKrcTezKxA+KmBgOA=', 'inactive', NULL, NULL, 'member', '2023-08-08 07:59:53', '2023-08-08 09:18:22', NULL, '3c79b99ab424'),
+ ('68694999fa8d', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-08-08 09:22:58', '2023-08-08 09:22:58', '9145944210a7', '6973c230d6b1'),
+ ('3229d273decd', NULL, '5eO+mQd6F+AQwCITx5mV8dX9/6U=', 'invited', NULL, NULL, 'manager', '2023-08-08 09:38:27', '2023-08-08 09:43:11', '130684395770', '6973c230d6b1'),
+ ('7cae64a7800c', 'e.mail@test.com', '7FUv2lrEcRjMbW/Nb1mTkBaAPOs=', 'invited', NULL, NULL, 'member', '2023-08-08 09:37:38', '2023-08-08 09:43:21', NULL, '6973c230d6b1'),
+ ('878426563205', NULL, NULL, 'established', NULL, NULL, 'guest', '2023-08-08 09:36:41', '2023-08-08 09:43:52', '48f00685a292', '6973c230d6b1'),
+ ('d27ca1d0e6e4', NULL, NULL, 'established', '#ff0080', '🐈⬛', 'member', '2023-08-08 09:36:01', '2023-08-08 09:44:19', 'bae69a1c9fcc', '6973c230d6b1'),
+ ('c463d2a19847', NULL, NULL, 'established', NULL, 'Ca', 'member', '2023-08-08 09:38:01', '2023-08-08 09:44:50', 'caeba9f7e728', '6973c230d6b1'),
+ ('763c0d181b63', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-08-08 09:37:16', '2023-08-08 09:45:21', 'bee7cf5b3871', '6973c230d6b1'),
+ ('b7d93b2fa1be', NULL, 'mLdsTtaGGptPYSZLUDgX8sAFO54=', 'established', NULL, NULL, 'member', '2023-08-12 19:10:49', '2023-08-12 19:10:49', 'a2f4f3879c85', '9c2447aefe38'),
+ ('ac1cd0bcbd69', NULL, 'V30YTcBqBqs5xS7HrFM4ODRrzbw=', 'established', NULL, NULL, 'member', '2023-08-12 19:10:28', '2023-08-12 19:10:28', 'a3d9d86dc23b', '9c2447aefe38'),
+ ('8be6d2f6f7dc', NULL, 'ru6jsdD9fODk8+p8wmI909rJPkQ=', 'established', NULL, NULL, 'manager', '2023-08-12 19:11:03', '2023-08-12 19:11:03', '566aea2c2759', '9c2447aefe38'),
+ ('0e26982c9895', NULL, 'ao9OQRgXWBpCVaD4lGQaUFzvKwI=', 'established', NULL, NULL, 'member', '2023-08-12 19:10:14', '2023-08-12 19:10:14', 'dac7116e02ed', '9c2447aefe38'),
+ ('b2f127cb410f', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-08-13 06:32:29', '2023-08-13 06:32:29', 'dac7116e02ed', '0969e3c95dfc'),
+ ('d806a59915f8', NULL, 'SuP47raE2s/2hGLsdBiO/icIU0E=', 'established', NULL, NULL, 'member', '2023-08-13 10:29:25', '2023-08-13 10:29:25', 'a3d9d86dc23b', '0969e3c95dfc'),
+ ('7db6a9ffc210', NULL, 'yyXTSd6kGh7kNENlcGDeYtq4ftQ=', 'established', NULL, NULL, 'guest', '2023-08-13 10:29:47', '2023-08-13 10:29:47', 'a2f4f3879c85', '0969e3c95dfc'),
+ ('60a470e1aff6', NULL, 'uGXywHjal9lK+rcdtRBcXh8y5qA=', 'established', NULL, NULL, 'manager', '2023-08-13 10:29:55', '2023-08-13 10:29:55', '566aea2c2759', '0969e3c95dfc'),
+ ('d1c0a4522283', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-09-29 23:24:38', '2023-09-29 23:24:38', 'dac7116e02ed', '70ca971c992f'),
+ ('5b24ce470d9f', NULL, 'XisYzAgXUozfJA1M/y39ow8t5Vw=', 'established', NULL, NULL, 'member', '2023-09-29 23:27:54', '2023-09-29 23:27:54', 'a3d9d86dc23b', '70ca971c992f'),
+ ('46d14f7c072c', NULL, '4KCuIMWvkGVAjSBtAnG5QcesOrI=', 'established', NULL, NULL, 'manager', '2023-09-29 23:41:30', '2023-09-29 23:41:30', 'a2f4f3879c85', '70ca971c992f'),
+ ('b0bdb7202a9d', NULL, NULL, 'established', NULL, NULL, 'manager', '2023-08-08 07:53:12', '2023-08-08 07:53:12', '9145944210a7', '3c79b99ab424'),
+ ('b00054c3c03e', NULL, 'XC/b4erYO0iZZTBEXOi3n/4AH9w=', 'established', NULL, NULL, 'guest', '2023-08-13 10:29:08', '2023-08-13 10:29:08', '9145944210a7', '0969e3c95dfc'),
+ ('10d8f02ce5b4', NULL, 'n1MKxMj1RWkrcSmNfHdjUxKV3QY=', 'established', NULL, NULL, 'guest', '2023-09-29 23:25:49', '2023-09-29 23:25:49', '9145944210a7', '70ca971c992f'),
+ ('b32db30637c8', NULL, 'AC/b4erYO0iZZTBEXOi3n/4AH9w=', 'invited', NULL, NULL, 'manager', '2023-08-12 17:41:55', '2023-08-12 17:41:55', '9145944210a7', '9c2447aefe38');
diff --git a/api/migrations/schema/Version20240621060047.php b/api/migrations/schema/Version20240621060047.php
new file mode 100644
index 0000000000..4f04aa3587
--- /dev/null
+++ b/api/migrations/schema/Version20240621060047.php
@@ -0,0 +1,27 @@
+addSql('ALTER TABLE profile ADD color VARCHAR(8) DEFAULT NULL');
+ $this->addSql('ALTER TABLE profile ADD abbreviation TEXT DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void {
+ $this->addSql('ALTER TABLE profile DROP color');
+ $this->addSql('ALTER TABLE profile DROP abbreviation');
+ }
+}
diff --git a/api/src/Entity/Profile.php b/api/src/Entity/Profile.php
index 536f67adba..92a6bb3d5b 100644
--- a/api/src/Entity/Profile.php
+++ b/api/src/Entity/Profile.php
@@ -172,6 +172,26 @@ class Profile extends BaseEntity {
#[ORM\Column(type: 'string', length: 20, nullable: true)]
public ?string $language = null;
+ /**
+ * The default color of the avatar as a hex color string.
+ */
+ #[InputFilter\Trim]
+ #[Assert\Regex(pattern: '/^#[0-9a-zA-Z]{6}$/')]
+ #[ApiProperty(example: '#4DBB52')]
+ #[Groups(['read', 'write'])]
+ #[ORM\Column(type: 'string', length: 8, nullable: true)]
+ public ?string $color = null;
+
+ /**
+ * The default abbreviation in the avatar.
+ */
+ #[InputFilter\Trim]
+ #[Assert\Length(max: 2, countUnit: Assert\Length::COUNT_GRAPHEMES)]
+ #[ApiProperty(example: 'AB')]
+ #[Groups(['read', 'write'])]
+ #[ORM\Column(type: 'text', nullable: true)]
+ public ?string $abbreviation = null;
+
/**
* The technical roles that this person has in the eCamp application.
*/
diff --git a/api/src/Entity/User.php b/api/src/Entity/User.php
index cf3d68d9ba..40c960fb46 100644
--- a/api/src/Entity/User.php
+++ b/api/src/Entity/User.php
@@ -182,6 +182,24 @@ public function getDisplayName(): ?string {
return $this->profile->getDisplayName();
}
+ /**
+ * A displayable name of the user.
+ */
+ #[ApiProperty(example: '#ff0000')]
+ #[Groups(['read'])]
+ public function getColor(): ?string {
+ return $this->profile->color;
+ }
+
+ /**
+ * A displayable name of the user.
+ */
+ #[ApiProperty(example: 'AB')]
+ #[Groups(['read'])]
+ public function getAbbreviation(): ?string {
+ return $this->profile->abbreviation;
+ }
+
#[ApiProperty]
#[SerializedName('profile')]
#[Groups(['read'])]
diff --git a/api/tests/Api/CampCollaborations/UpdateCampCollaborationTest.php b/api/tests/Api/CampCollaborations/UpdateCampCollaborationTest.php
index c427641782..51b89f16a2 100644
--- a/api/tests/Api/CampCollaborations/UpdateCampCollaborationTest.php
+++ b/api/tests/Api/CampCollaborations/UpdateCampCollaborationTest.php
@@ -265,6 +265,53 @@ public function testPatchStatusFromInactiveToInvitedSendsInviteEmail() {
$this->assertEmailCount(1);
}
+ public function testPatchCampCollaborationValidatesInvalidColor() {
+ $campCollaboration = static::getFixture('campCollaboration3guest');
+ static::createClientWithCredentials()->request('PATCH', '/camp_collaborations/'.$campCollaboration->getId(), ['json' => [
+ 'color' => 'red',
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+
+ $this->assertResponseStatusCodeSame(422);
+ $this->assertJsonContains([
+ 'violations' => [
+ [
+ 'propertyPath' => 'color',
+ 'message' => 'This value is not valid.',
+ ],
+ ],
+ ]);
+ }
+
+ #[DataProvider('invalidAbbreviations')]
+ public function testPatchCampCollaborationValidatesInvalidAbbreviation($abbreviation) {
+ $campCollaboration = static::getFixture('campCollaboration3guest');
+ static::createClientWithCredentials()->request('PATCH', '/camp_collaborations/'.$campCollaboration->getId(), ['json' => [
+ 'abbreviation' => $abbreviation,
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+
+ $this->assertResponseStatusCodeSame(422);
+ $this->assertJsonContains([
+ 'violations' => [
+ [
+ 'propertyPath' => 'abbreviation',
+ 'message' => 'This value is too long. It should have 2 characters or less.',
+ ],
+ ],
+ ]);
+ }
+
+ #[DataProvider('validAbbreviations')]
+ public function testPatchCampCollaborationValidatesValidAbbreviation($abbreviation) {
+ $campCollaboration = static::getFixture('campCollaboration5inactive');
+ static::createClientWithCredentials()->request('PATCH', '/camp_collaborations/'.$campCollaboration->getId(), ['json' => [
+ 'abbreviation' => $abbreviation,
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+ $this->assertResponseStatusCodeSame(200);
+ $this->assertJsonContains([
+ 'abbreviation' => $abbreviation,
+ ]);
+ }
+
#[DataProvider('usersWhichCanEditCampCollaborations')]
public function testRejectsPatchStatusFromEstablishedToInactiveIfNoManagerWouldBeInCamp(string $userFixtureName) {
$campCollaboration = static::getFixture('campCollaboration1camp2manager');
@@ -355,4 +402,23 @@ public function testRejectsPatchRoleToGuestIfNoManagerWouldBeInCamp(string $user
public static function usersWhichCanEditCampCollaborations(): array {
return ['user1manager' => ['user1manager'], 'user2member' => ['user2member']];
}
+
+ public static function invalidAbbreviations(): array {
+ return [
+ ['ABC'],
+ ['D3C'],
+ ['🧑🏿🚀🙋🏼♀️😊'],
+ ];
+ }
+
+ public static function validAbbreviations(): array {
+ return [
+ ['A'],
+ ['33'],
+ ['X4'],
+ ['✅😊'],
+ ['🧑🏿🚀🧑🏼🔧'],
+ ['⚜️'],
+ ];
+ }
}
diff --git a/api/tests/Api/Profiles/ReadProfileTest.php b/api/tests/Api/Profiles/ReadProfileTest.php
index 3c9528d388..187afa004b 100644
--- a/api/tests/Api/Profiles/ReadProfileTest.php
+++ b/api/tests/Api/Profiles/ReadProfileTest.php
@@ -34,6 +34,8 @@ public function testGetSingleProfileIsAllowedForSelf() {
'nickname' => $profile->nickname,
'language' => $profile->language,
'legalName' => $profile->getLegalName(),
+ 'abbreviation' => $profile->abbreviation,
+ 'color' => $profile->color,
'_links' => [
'self' => [
'href' => '/profiles/'.$profile->getId(),
@@ -58,6 +60,8 @@ public function testGetSingleProfileIsAllowedForRelatedUser() {
'nickname' => $profile->nickname,
'language' => $profile->language,
'legalName' => $profile->getLegalName(),
+ 'abbreviation' => $profile->abbreviation,
+ 'color' => $profile->color,
'_links' => [
'self' => [
'href' => '/profiles/'.$profile->getId(),
@@ -84,6 +88,8 @@ public function testGetSingleProfileIsAllowedForSelfIfSelfHasNoCampCollaboration
'nickname' => $profile->nickname,
'language' => $profile->language,
'legalName' => $profile->getLegalName(),
+ 'abbreviation' => $profile->abbreviation,
+ 'color' => $profile->color,
'_links' => [
'self' => [
'href' => '/profiles/'.$profile->getId(),
diff --git a/api/tests/Api/Profiles/UpdateProfileTest.php b/api/tests/Api/Profiles/UpdateProfileTest.php
index 2270e3da14..6da0619cb3 100644
--- a/api/tests/Api/Profiles/UpdateProfileTest.php
+++ b/api/tests/Api/Profiles/UpdateProfileTest.php
@@ -204,6 +204,53 @@ public function testPatchProfileTrimsLanguage() {
]);
}
+ public function testPatchProfileValidatesInvalidColor() {
+ $profile = static::getFixture('profile1manager');
+ static::createClientWithCredentials()->request('PATCH', '/profiles/'.$profile->getId(), ['json' => [
+ 'color' => 'red',
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+
+ $this->assertResponseStatusCodeSame(422);
+ $this->assertJsonContains([
+ 'violations' => [
+ [
+ 'propertyPath' => 'color',
+ 'message' => 'This value is not valid.',
+ ],
+ ],
+ ]);
+ }
+
+ #[DataProvider('invalidAbbreviations')]
+ public function testPatchCampCollaborationValidatesInvalidAbbreviation($abbreviation) {
+ $profile = static::getFixture('profile1manager');
+ static::createClientWithCredentials()->request('PATCH', '/profiles/'.$profile->getId(), ['json' => [
+ 'abbreviation' => $abbreviation,
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+
+ $this->assertResponseStatusCodeSame(422);
+ $this->assertJsonContains([
+ 'violations' => [
+ [
+ 'propertyPath' => 'abbreviation',
+ 'message' => 'This value is too long. It should have 2 characters or less.',
+ ],
+ ],
+ ]);
+ }
+
+ #[DataProvider('validAbbreviations')]
+ public function testPatchCampCollaborationValidatesValidAbbreviation($abbreviation) {
+ $profile = static::getFixture('profile1manager');
+ static::createClientWithCredentials()->request('PATCH', '/profiles/'.$profile->getId(), ['json' => [
+ 'abbreviation' => $abbreviation,
+ ], 'headers' => ['Content-Type' => 'application/merge-patch+json']]);
+ $this->assertResponseStatusCodeSame(200);
+ $this->assertJsonContains([
+ 'abbreviation' => $abbreviation,
+ ]);
+ }
+
public function testPatchProfileValidatesInvalidLanguage() {
$profile = static::getFixture('profile1manager');
static::createClientWithCredentials()->request('PATCH', '/profiles/'.$profile->getId(), ['json' => [
@@ -270,4 +317,22 @@ public static function notWriteableProfileProperties(): array {
'user' => ['user'],
];
}
+
+ public static function invalidAbbreviations(): array {
+ return [
+ ['ABC'],
+ ['D3C'],
+ ['🧑🏿🚀🙋🏼♀️😊'],
+ ];
+ }
+
+ public static function validAbbreviations(): array {
+ return [
+ ['AB'],
+ ['33'],
+ ['X4'],
+ ['✅😊'],
+ ['🧑🏿🚀🧑🏼🔧'],
+ ];
+ }
}
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set camp_collaborations__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set camp_collaborations__1.json
index 44110ee299..e2ff2cbcd4 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set camp_collaborations__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set camp_collaborations__1.json
@@ -126,6 +126,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -206,6 +208,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -286,6 +290,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -366,6 +372,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -446,6 +454,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -526,6 +536,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -606,6 +618,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -686,6 +700,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -766,6 +782,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -846,6 +864,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -926,6 +946,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set profiles__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set profiles__1.json
index 38f9b870e0..5396b1b4c8 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set profiles__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set profiles__1.json
@@ -10,6 +10,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
@@ -27,6 +29,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
@@ -44,6 +48,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
@@ -61,6 +67,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
@@ -78,6 +86,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camp_collaborations__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camp_collaborations__1.json
index b3c5bec5b1..c84f1c605b 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camp_collaborations__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camp_collaborations__1.json
@@ -56,6 +56,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camps__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camps__1.json
index 6eb4f736b4..9afc1cba01 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camps__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set camps__1.json
@@ -32,6 +32,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -65,6 +67,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -98,6 +102,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -131,6 +137,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
@@ -164,6 +172,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"displayName": "escaped_value",
"id": "escaped_value"
}
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set profiles__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set profiles__1.json
index 835aeeec69..01fb732b50 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set profiles__1.json
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set profiles__1.json
@@ -7,6 +7,8 @@
"href": "escaped_value"
}
},
+ "abbreviation": "escaped_value",
+ "color": "escaped_value",
"email": "escaped_value",
"firstname": "escaped_value",
"id": "escaped_value",
diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
index a68fa412dd..226c6c1573 100644
--- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
+++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml
@@ -15488,6 +15488,21 @@ components:
The properties available to related eCamp users are here.
Related means that they were or are collaborators in the same camp.
properties:
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -15564,6 +15579,21 @@ components:
deprecated: false
description: ''
properties:
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -15643,6 +15673,21 @@ components:
The properties available to related eCamp users are here.
Related means that they were or are collaborators in the same camp.
properties:
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -15709,6 +15754,21 @@ components:
The properties available to related eCamp users are here.
Related means that they were or are collaborators in the same camp.
properties:
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
firstname:
description: "The user's (optional) first name."
example: Robert
@@ -15781,6 +15841,17 @@ components:
maxLength: 16
readOnly: true
type: string
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type: ['null', string]
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type: ['null', string]
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -15871,6 +15942,21 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -15956,6 +16042,21 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -16044,6 +16145,21 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -16133,6 +16249,21 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -16232,6 +16363,21 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -16311,6 +16457,21 @@ components:
The properties available to related eCamp users are here.
Related means that they were or are collaborators in the same camp.
properties:
+ abbreviation:
+ description: 'The default abbreviation in the avatar.'
+ example: AB
+ maxLength: 2
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'The default color of the avatar as a hex color string.'
+ example: '#4DBB52'
+ maxLength: 8
+ pattern: '^(#[0-9a-zA-Z]{6})$'
+ type:
+ - 'null'
+ - string
email:
description: 'Unique email of the user.'
example: bi-pi@example.com
@@ -20218,6 +20379,20 @@ components:
A person using eCamp.
The properties available for all other eCamp users are here.
properties:
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20245,6 +20420,20 @@ components:
deprecated: false
description: ''
properties:
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20272,6 +20461,20 @@ components:
deprecated: false
description: ''
properties:
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20301,6 +20504,20 @@ components:
A person using eCamp.
The properties available for all other eCamp users are here.
properties:
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20391,10 +20608,20 @@ components:
maxLength: 16
readOnly: true
type: string
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type: ['null', string]
activationKey:
description: 'User-Input for activation.'
type: ['null', string]
writeOnly: true
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type: ['null', string]
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20454,6 +20681,20 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20490,6 +20731,20 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20526,6 +20781,20 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20564,6 +20833,20 @@ components:
type: string
type: object
type: object
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20657,6 +20940,20 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20707,6 +21004,20 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20757,6 +21068,20 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
@@ -20809,6 +21134,20 @@ components:
'@type':
readOnly: true
type: string
+ abbreviation:
+ description: 'A displayable name of the user.'
+ example: AB
+ readOnly: true
+ type:
+ - 'null'
+ - string
+ color:
+ description: 'A displayable name of the user.'
+ example: '#ff0000'
+ readOnly: true
+ type:
+ - 'null'
+ - string
displayName:
description: 'A displayable name of the user.'
example: 'Robert Baden-Powell'
diff --git a/api/tests/Api/Users/ReadUserTest.php b/api/tests/Api/Users/ReadUserTest.php
index 23a1f308dd..9cde757a64 100644
--- a/api/tests/Api/Users/ReadUserTest.php
+++ b/api/tests/Api/Users/ReadUserTest.php
@@ -57,6 +57,8 @@ public function testGetSingleUserIsAllowedForSelf() {
$this->assertJsonEquals([
'id' => $user->getId(),
'displayName' => $user->getDisplayName(),
+ 'abbreviation' => $user->getAbbreviation(),
+ 'color' => $user->getColor(),
'_links' => [
'self' => [
'href' => $this->getIriFor('user1manager'),
@@ -76,6 +78,8 @@ public function testGetSingleUserIsAllowedForRelatedUser() {
$this->assertJsonEquals([
'id' => $user->getId(),
'displayName' => $user->getDisplayName(),
+ 'abbreviation' => $user->getAbbreviation(),
+ 'color' => $user->getColor(),
'_links' => [
'self' => [
'href' => $this->getIriFor('user2member'),
diff --git a/common/helpers/__tests__/campCollaborationInitials.spec.js b/common/helpers/__tests__/campCollaborationInitials.spec.js
index 379b88dccc..5693d6c486 100644
--- a/common/helpers/__tests__/campCollaborationInitials.spec.js
+++ b/common/helpers/__tests__/campCollaborationInitials.spec.js
@@ -17,6 +17,12 @@ describe('campCollaborationInitials', () => {
[{ inviteEmail: 'ecamp@ecamp3.ch', status: 'inactive', user: null }, 'EC'],
[{ abbreviation: 'B', inviteEmail: null, user: null }, 'B'],
[{ abbreviation: 'AA', user: () => ({ displayName: 'Bi-Pi' }) }, 'AA'],
+ [
+ { abbreviation: 'AA', user: () => ({ abbreviation: 'CC', displayName: 'Bi-Pi' }) },
+ 'AA',
+ ],
+ [{ user: () => ({ abbreviation: 'QQ' }) }, 'QQ'],
+ [{ user: () => ({ abbreviation: 'QQ', displayName: 'Bi-Pi' }) }, 'QQ'],
])('maps %o to "%s"', (input, expected) => {
expect(campCollaborationInitials(input)).toEqual(expected)
})
diff --git a/common/helpers/__tests__/colors.spec.js b/common/helpers/__tests__/colors.spec.js
index 8650b44257..0af33c5db4 100644
--- a/common/helpers/__tests__/colors.spec.js
+++ b/common/helpers/__tests__/colors.spec.js
@@ -24,6 +24,8 @@ describe('userColor', () => {
[{ name: 'test' }, '#4d4d4d'],
[{ _meta: {} }, '#4d4d4d'],
[{ _meta: { loading: true } }, '#4d4d4d'],
+ [{ color: '#abcdef' }, '#abcdef'],
+ [{ color: '#abcdef', _meta: { loading: true } }, '#4d4d4d'],
])('maps %p to %p', (input, expected) => {
expect(userColor(input)).toEqual(expected)
})
@@ -40,6 +42,19 @@ describe('campCollaborationColor', () => {
[{ _meta: { loading: true } }, '#4d4d4d'],
[{ id: 'fffffff', user: () => ({ _meta: { loading: true } }) }, '#4d4d4d'],
[{ color: '#ECA110' }, '#ECA110'],
+ [{ color: '#ECA110', _meta: { loading: true } }, '#4d4d4d'],
+ [
+ { id: 'fffffff', user: () => ({ color: '#ECA110', _meta: { loading: true } }) },
+ '#4d4d4d',
+ ],
+ [
+ {
+ id: 'fffffff',
+ _meta: { loading: true },
+ user: () => ({ color: '#ECA110', _meta: { loading: true } }),
+ },
+ '#4d4d4d',
+ ],
])('maps %o to "%s"', (input, expected) => {
expect(campCollaborationColor(input)).toEqual(expected)
})
diff --git a/common/helpers/__tests__/userInitials.spec.js b/common/helpers/__tests__/userInitials.spec.js
index 051ff74771..eff283e9f8 100644
--- a/common/helpers/__tests__/userInitials.spec.js
+++ b/common/helpers/__tests__/userInitials.spec.js
@@ -2,11 +2,15 @@ import userInitials from '../userInitials.js'
describe('userInitials', () => {
it.each([
+ [{}, ''],
+ [null, ''],
+ [undefined, ''],
[{ id: 'fffffff' }, ''],
[{ displayName: 'test' }, 'TE'],
[{ displayName: 'test', _meta: {} }, 'TE'],
[{ _meta: { loading: true } }, ''],
- ])('maps %p to %p', (input, expected) => {
+ [{ abbreviation: 'V3', displayName: 'test' }, 'V3'],
+ ])('maps %o to "%s"', (input, expected) => {
expect(userInitials(input)).toEqual(expected)
})
})
diff --git a/common/helpers/campCollaborationInitials.js b/common/helpers/campCollaborationInitials.js
index 93438b3b75..3ca2823bf5 100644
--- a/common/helpers/campCollaborationInitials.js
+++ b/common/helpers/campCollaborationInitials.js
@@ -1,11 +1,24 @@
-import campCollaborationDisplayName from './campCollaborationDisplayName.js'
+import userDisplayName from './userDisplayName.js'
import initials from './initials.js'
/**
* Returns two characters to display for a camp collaboration based on its user
*/
export default function (campCollaboration) {
- return campCollaboration?.abbreviation
- ? campCollaboration.abbreviation
- : initials(campCollaborationDisplayName(campCollaboration, null, false))
+ if (!campCollaboration) {
+ return ''
+ }
+
+ if (campCollaboration?.abbreviation) {
+ return campCollaboration.abbreviation
+ }
+
+ if (typeof campCollaboration.user === 'function') {
+ if (campCollaboration.user().abbreviation) {
+ return campCollaboration.user().abbreviation
+ }
+ return initials(userDisplayName(campCollaboration.user()))
+ }
+
+ return initials(campCollaboration.inviteEmail || '')
}
diff --git a/common/helpers/colors.js b/common/helpers/colors.js
index 2b79dc1025..4e654108c2 100644
--- a/common/helpers/colors.js
+++ b/common/helpers/colors.js
@@ -41,8 +41,11 @@ function defaultColor() {
/**
* @returns {string} color for a user based on their id
*/
-function userColor(user) {
- return idToColor(user.id, user._meta?.loading)
+function userColor(user, inactive = user._meta?.loading) {
+ if (user.color && !inactive) {
+ return user.color
+ }
+ return idToColor(user.id, inactive)
}
/**
@@ -53,21 +56,21 @@ function campCollaborationColor(campCollaboration) {
return idToColor('', true)
}
- const loading =
- campCollaboration._meta?.loading ||
- (typeof campCollaboration.user === 'function' &&
- campCollaboration.user()._meta?.loading)
+ const inactive =
+ campCollaboration._meta?.loading || campCollaboration.status === 'inactive'
- if (campCollaboration?.color) {
+ if (campCollaboration?.color && !inactive) {
return campCollaboration.color
}
- return idToColor(
- typeof campCollaboration.user === 'function'
- ? campCollaboration.user().id
- : campCollaboration.id,
- campCollaboration.status === 'inactive' || loading
- )
+ if (typeof campCollaboration.user === 'function') {
+ return userColor(
+ campCollaboration.user(),
+ inactive || campCollaboration.user()._meta?.loading
+ )
+ } else {
+ return idToColor(campCollaboration.id, inactive)
+ }
}
export { contrastColor, defaultColor, userColor, campCollaborationColor, idToColor }
diff --git a/common/helpers/userInitials.js b/common/helpers/userInitials.js
index 4c6d5672c8..cdb6d9e225 100644
--- a/common/helpers/userInitials.js
+++ b/common/helpers/userInitials.js
@@ -5,5 +5,11 @@ import initials from './initials.js'
* Returns two characters to display for a user
*/
export default function (user) {
+ if (!user) {
+ return ''
+ }
+ if (user.abbreviation) {
+ return user.abbreviation
+ }
return initials(userDisplayName(user))
}
diff --git a/common/locales/de.json b/common/locales/de.json
index fdb5c54f2c..c8f3f1d83f 100644
--- a/common/locales/de.json
+++ b/common/locales/de.json
@@ -202,6 +202,19 @@
},
"name": "Lagerabschnitt | Lagerabschnitte"
},
+ "profile": {
+ "fields": {
+ "abbreviation": "Abkürzung",
+ "color": "Farbe",
+ "email": "E-Mail-Adresse",
+ "firstname": "Vorname",
+ "language": "Sprache",
+ "nickname": "Spitzname",
+ "password": "Passwort",
+ "surname": "Nachname"
+ },
+ "name": "Profil"
+ },
"scheduleEntry": {
"fields": {
"duration": "Dauer",
diff --git a/common/locales/en.json b/common/locales/en.json
index d78a0fa02a..1093dd758c 100644
--- a/common/locales/en.json
+++ b/common/locales/en.json
@@ -209,6 +209,19 @@
},
"name": "Period | Periods"
},
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviation",
+ "color": "Color",
+ "email": "Email address",
+ "firstname": "Firstname",
+ "language": "Language",
+ "nickname": "Nickname",
+ "password": "Password",
+ "surname": "Lastname"
+ },
+ "name": "Profile"
+ },
"scheduleEntry": {
"fields": {
"duration": "Duration",
diff --git a/common/locales/fr.json b/common/locales/fr.json
index 5cf8b89303..db1a1a74a4 100644
--- a/common/locales/fr.json
+++ b/common/locales/fr.json
@@ -190,6 +190,19 @@
},
"name": "Période | Périodes"
},
+ "profile": {
+ "fields": {
+ "abbreviation": "Abréviation",
+ "color": "Couleur",
+ "email": "Adresse e-mail",
+ "firstname": "Prénom",
+ "language": "Langue",
+ "nickname": "Surnom",
+ "password": "Mot de passe",
+ "surname": "Nom de famille"
+ },
+ "name": "Profil"
+ },
"scheduleEntry": {
"fields": {
"duration": "Durée",
diff --git a/common/locales/it.json b/common/locales/it.json
index c2ff83a458..f7ea5a4054 100644
--- a/common/locales/it.json
+++ b/common/locales/it.json
@@ -180,6 +180,19 @@
},
"name": "Periodo | Periodi"
},
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviazione",
+ "color": "Colore",
+ "email": "Indirizzo email",
+ "firstname": "Nome",
+ "language": "Lingua",
+ "nickname": "Soprannome",
+ "password": "Parola d'ordine",
+ "surname": "Cognome"
+ },
+ "name": "Profilo"
+ },
"scheduleEntry": {
"fields": {
"duration": "Durata",
diff --git a/common/locales/rm.json b/common/locales/rm.json
index 9e26dfeeb6..28973a4e31 100644
--- a/common/locales/rm.json
+++ b/common/locales/rm.json
@@ -1 +1,16 @@
-{}
\ No newline at end of file
+{
+ "entity": {
+ "profile": {
+ "fields": {
+ "abbreviation": "Abbreviaziun",
+ "color": "Colur",
+ "email": "Adressa dad e-mail",
+ "firstname": "Prenum",
+ "language": "Lingua",
+ "nickname": "Surnum",
+ "password": "Pled-clav",
+ "surname": "Num da famiglia"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/components/collaborator/CollaboratorCreate.vue b/frontend/src/components/collaborator/CollaboratorCreate.vue
index f195eb0052..ba303341be 100644
--- a/frontend/src/components/collaborator/CollaboratorCreate.vue
+++ b/frontend/src/components/collaborator/CollaboratorCreate.vue
@@ -25,7 +25,7 @@
class="mb-2"
/>
-
+
diff --git a/frontend/src/components/collaborator/CollaboratorEdit.vue b/frontend/src/components/collaborator/CollaboratorEdit.vue
index d1c23dc05d..47974ab47f 100644
--- a/frontend/src/components/collaborator/CollaboratorEdit.vue
+++ b/frontend/src/components/collaborator/CollaboratorEdit.vue
@@ -66,6 +66,7 @@
:collaboration="entityData"
:status="collaborator.status"
:readonly-role="isLastManager"
+ :initial-collaboration="collaborator"
>
-
+