summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerrick Anderson <derrick@andersonwebstudio.com>2018-02-14 00:53:04 -0500
committerDerrick Anderson <derrick@andersonwebstudio.com>2018-02-14 00:53:04 -0500
commit88d693a950fad663016a84407c90b8de280c0252 (patch)
tree571d01753c39f320b3634eae5723b76904d6bd48
parent3fef21e350737c235e6dfc2d9f35311d65290c3e (diff)
parent82209b9452f3241c879591bd29a163538cb70b5e (diff)
downloadchat-88d693a950fad663016a84407c90b8de280c0252.tar.gz
chat-88d693a950fad663016a84407c90b8de280c0252.tar.bz2
chat-88d693a950fad663016a84407c90b8de280c0252.zip
Merge branch 'release-4.7' into icu753
-rw-r--r--app/channel_test.go20
-rw-r--r--app/notification.go81
-rw-r--r--app/notification_test.go45
-rw-r--r--app/team.go12
-rw-r--r--app/team_test.go89
-rw-r--r--i18n/de.json22
-rw-r--r--i18n/en.json8
-rw-r--r--i18n/es.json20
-rw-r--r--i18n/fr.json68
-rw-r--r--i18n/it.json20
-rw-r--r--i18n/ja.json20
-rw-r--r--i18n/ko.json22
-rw-r--r--i18n/nl.json114
-rw-r--r--i18n/pl.json20
-rw-r--r--i18n/pt-BR.json20
-rw-r--r--i18n/ru.json36
-rw-r--r--i18n/tr.json20
-rw-r--r--i18n/zh-CN.json20
-rw-r--r--i18n/zh-TW.json30
-rw-r--r--model/channel_member_history_result.go15
-rw-r--r--store/sqlstore/channel_member_history_store.go8
-rw-r--r--store/sqlstore/upgrade.go2
-rw-r--r--store/storetest/channel_member_history_store.go28
23 files changed, 420 insertions, 320 deletions
diff --git a/app/channel_test.go b/app/channel_test.go
index a414fbb35..d83590a27 100644
--- a/app/channel_test.go
+++ b/app/channel_test.go
@@ -116,14 +116,14 @@ func TestJoinDefaultChannelsTownSquare(t *testing.T) {
// figure out the initial number of users in town square
townSquareChannelId := store.Must(th.App.Srv.Store.Channel().GetByName(th.BasicTeam.Id, "town-square", true)).(*model.Channel).Id
- initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistory))
+ initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult))
// create a new user that joins the default channels
user := th.CreateUser()
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "")
// there should be a ChannelMemberHistory record for the user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, initialNumTownSquareUsers+1)
found := false
@@ -142,14 +142,14 @@ func TestJoinDefaultChannelsOffTopic(t *testing.T) {
// figure out the initial number of users in off-topic
offTopicChannelId := store.Must(th.App.Srv.Store.Channel().GetByName(th.BasicTeam.Id, "off-topic", true)).(*model.Channel).Id
- initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistory))
+ initialNumTownSquareUsers := len(store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult))
// create a new user that joins the default channels
user := th.CreateUser()
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "")
// there should be a ChannelMemberHistory record for the user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, initialNumTownSquareUsers+1)
found := false
@@ -170,7 +170,7 @@ func TestCreateChannelPublic(t *testing.T) {
publicChannel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN)
// there should be a ChannelMemberHistory record for the user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 1)
assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
assert.Equal(t, publicChannel.Id, histories[0].ChannelId)
@@ -184,7 +184,7 @@ func TestCreateChannelPrivate(t *testing.T) {
privateChannel := th.createChannel(th.BasicTeam, model.CHANNEL_PRIVATE)
// there should be a ChannelMemberHistory record for the user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, privateChannel.Id)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, privateChannel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 1)
assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
assert.Equal(t, privateChannel.Id, histories[0].ChannelId)
@@ -221,7 +221,7 @@ func TestCreateGroupChannel(t *testing.T) {
t.Fatal("Failed to create group channel. Error: " + err.Message)
} else {
// there should be a ChannelMemberHistory record for each user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 3)
channelMemberHistoryUserIds := make([]string, 0)
@@ -253,7 +253,7 @@ func TestAddUserToChannel(t *testing.T) {
}
// there should be a ChannelMemberHistory record for the user
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 2)
channelMemberHistoryUserIds := make([]string, 0)
for _, history := range histories {
@@ -269,7 +269,7 @@ func TestRemoveUserFromChannel(t *testing.T) {
// a user creates a channel
publicChannel := th.createChannel(th.BasicTeam, model.CHANNEL_OPEN)
- histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory)
+ histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 1)
assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
assert.Equal(t, publicChannel.Id, histories[0].ChannelId)
@@ -279,7 +279,7 @@ func TestRemoveUserFromChannel(t *testing.T) {
if err := th.App.LeaveChannel(publicChannel.Id, th.BasicUser.Id); err != nil {
t.Fatal("Failed to remove user from channel. Error: " + err.Message)
}
- histories = store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistory)
+ histories = store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, publicChannel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, histories, 1)
assert.Equal(t, th.BasicUser.Id, histories[0].UserId)
assert.Equal(t, publicChannel.Id, histories[0].ChannelId)
diff --git a/app/notification.go b/app/notification.go
index 8d8e72cf9..24e84500b 100644
--- a/app/notification.go
+++ b/app/notification.go
@@ -831,44 +831,52 @@ func GetExplicitMentions(message string, keywords map[string][]string) *Explicit
ret.MentionedUserIds[id] = true
}
}
+ checkForMention := func(word string) bool {
+ isMention := false
+ if word == "@here" {
+ ret.HereMentioned = true
+ }
+
+ if word == "@channel" {
+ ret.ChannelMentioned = true
+ }
+
+ if word == "@all" {
+ ret.AllMentioned = true
+ }
+
+ // Non-case-sensitive check for regular keys
+ if ids, match := keywords[strings.ToLower(word)]; match {
+ addMentionedUsers(ids)
+ isMention = true
+ }
+
+ // Case-sensitive check for first name
+ if ids, match := keywords[word]; match {
+ addMentionedUsers(ids)
+ isMention = true
+ }
+
+ return isMention
+ }
processText := func(text string) {
for _, word := range strings.FieldsFunc(text, func(c rune) bool {
// Split on any whitespace or punctuation that can't be part of an at mention or emoji pattern
return !(c == ':' || c == '.' || c == '-' || c == '_' || c == '@' || unicode.IsLetter(c) || unicode.IsNumber(c))
}) {
- isMention := false
-
// skip word with format ':word:' with an assumption that it is an emoji format only
if word[0] == ':' && word[len(word)-1] == ':' {
continue
}
- if word == "@here" {
- ret.HereMentioned = true
- }
-
- if word == "@channel" {
- ret.ChannelMentioned = true
- }
-
- if word == "@all" {
- ret.AllMentioned = true
- }
-
- // Non-case-sensitive check for regular keys
- if ids, match := keywords[strings.ToLower(word)]; match {
- addMentionedUsers(ids)
- isMention = true
- }
-
- // Case-sensitive check for first name
- if ids, match := keywords[word]; match {
- addMentionedUsers(ids)
- isMention = true
+ if checkForMention(word) {
+ continue
}
- if isMention {
+ // remove trailing '.', as that is the end of a sentence
+ word = strings.TrimSuffix(word, ".")
+ if checkForMention(word) {
continue
}
@@ -879,27 +887,10 @@ func GetExplicitMentions(message string, keywords map[string][]string) *Explicit
})
for _, splitWord := range splitWords {
- if splitWord == "@here" {
- ret.HereMentioned = true
+ if checkForMention(splitWord) {
+ continue
}
-
- if splitWord == "@all" {
- ret.AllMentioned = true
- }
-
- if splitWord == "@channel" {
- ret.ChannelMentioned = true
- }
-
- // Non-case-sensitive check for regular keys
- if ids, match := keywords[strings.ToLower(splitWord)]; match {
- addMentionedUsers(ids)
- }
-
- // Case-sensitive check for first name
- if ids, match := keywords[splitWord]; match {
- addMentionedUsers(ids)
- } else if _, ok := systemMentions[splitWord]; !ok && strings.HasPrefix(splitWord, "@") {
+ if _, ok := systemMentions[splitWord]; !ok && strings.HasPrefix(splitWord, "@") {
username := splitWord[1:]
ret.OtherPotentialMentions = append(ret.OtherPotentialMentions, username)
}
diff --git a/app/notification_test.go b/app/notification_test.go
index cc501fbd0..43703c019 100644
--- a/app/notification_test.go
+++ b/app/notification_test.go
@@ -109,6 +109,33 @@ func TestGetExplicitMentions(t *testing.T) {
},
},
},
+ "OnePersonWithPeriodAtEndOfUsername": {
+ Message: "this is a message for @user.name.",
+ Keywords: map[string][]string{"@user.name.": {id1}},
+ Expected: &ExplicitMentions{
+ MentionedUserIds: map[string]bool{
+ id1: true,
+ },
+ },
+ },
+ "OnePersonWithPeriodAtEndOfUsernameButNotSimilarName": {
+ Message: "this is a message for @user.name.",
+ Keywords: map[string][]string{"@user.name.": {id1}, "@user.name": {id2}},
+ Expected: &ExplicitMentions{
+ MentionedUserIds: map[string]bool{
+ id1: true,
+ },
+ },
+ },
+ "OnePersonAtEndOfSentence": {
+ Message: "this is a message for @user.",
+ Keywords: map[string][]string{"@user": {id1}},
+ Expected: &ExplicitMentions{
+ MentionedUserIds: map[string]bool{
+ id1: true,
+ },
+ },
+ },
"OnePersonWithoutAtMention": {
Message: "this is a message for @user",
Keywords: map[string][]string{"this": {id1}},
@@ -179,6 +206,24 @@ func TestGetExplicitMentions(t *testing.T) {
},
},
},
+ "AtUserWithPeriodAtEndOfSentence": {
+ Message: "this is a message for @user.period.",
+ Keywords: map[string][]string{"@user.period": {id1}},
+ Expected: &ExplicitMentions{
+ MentionedUserIds: map[string]bool{
+ id1: true,
+ },
+ },
+ },
+ "UserWithPeriodAtEndOfSentence": {
+ Message: "this is a message for user.period.",
+ Keywords: map[string][]string{"user.period": {id1}},
+ Expected: &ExplicitMentions{
+ MentionedUserIds: map[string]bool{
+ id1: true,
+ },
+ },
+ },
"PotentialOutOfChannelUser": {
Message: "this is an message for @potential and @user",
Keywords: map[string][]string{"@user": {id1}},
diff --git a/app/team.go b/app/team.go
index 8e8c29e2a..a15c64c3f 100644
--- a/app/team.go
+++ b/app/team.go
@@ -302,10 +302,16 @@ func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMem
return rtm, true, nil
}
- if tmr := <-a.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
- return nil, false, tmr.Err
+ if membersCount := <-a.Srv.Store.Team().GetActiveMemberCount(tm.TeamId); membersCount.Err != nil {
+ return nil, false, membersCount.Err
+ } else if membersCount.Data.(int64) >= int64(*a.Config().TeamSettings.MaxUsersPerTeam) {
+ return nil, false, model.NewAppError("joinUserToTeam", "app.team.join_user_to_team.max_accounts.app_error", nil, "teamId="+tm.TeamId, http.StatusBadRequest)
} else {
- return tmr.Data.(*model.TeamMember), false, nil
+ if tmr := <-a.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
+ return nil, false, tmr.Err
+ } else {
+ return tmr.Data.(*model.TeamMember), false, nil
+ }
}
} else {
// Membership appears to be missing. Lets try to add.
diff --git a/app/team_test.go b/app/team_test.go
index 7cb20b6f6..a2bf44a57 100644
--- a/app/team_test.go
+++ b/app/team_test.go
@@ -460,3 +460,92 @@ func TestAddUserToTeamByHashMismatchedInviteId(t *testing.T) {
assert.Nil(t, team)
assert.Equal(t, "api.user.create_user.signup_link_mismatched_invite_id.app_error", err.Id)
}
+
+func TestJoinUserToTeam(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ id := model.NewId()
+ team := &model.Team{
+ DisplayName: "dn_" + id,
+ Name: "name" + id,
+ Email: "success+" + id + "@simulator.amazonses.com",
+ Type: model.TEAM_OPEN,
+ }
+
+ if _, err := th.App.CreateTeam(team); err != nil {
+ t.Log(err)
+ t.Fatal("Should create a new team")
+ }
+
+ maxUsersPerTeam := th.App.Config().TeamSettings.MaxUsersPerTeam
+ defer func() {
+ th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.MaxUsersPerTeam = maxUsersPerTeam })
+ th.App.SetDefaultRolesBasedOnConfig()
+ th.App.PermanentDeleteTeam(team)
+ }()
+ one := 1
+ th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.MaxUsersPerTeam = &one })
+
+ t.Run("new join", func(t *testing.T) {
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ if _, alreadyAdded, err := th.App.joinUserToTeam(team, ruser); alreadyAdded || err != nil {
+ t.Fatal("Should return already added equal to false and no error")
+ }
+ })
+
+ t.Run("join when you are a member", func(t *testing.T) {
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ th.App.joinUserToTeam(team, ruser)
+ if _, alreadyAdded, err := th.App.joinUserToTeam(team, ruser); !alreadyAdded || err != nil {
+ t.Fatal("Should return already added and no error")
+ }
+ })
+
+ t.Run("re-join after leaving", func(t *testing.T) {
+ user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser, _ := th.App.CreateUser(&user)
+ defer th.App.PermanentDeleteUser(&user)
+
+ th.App.joinUserToTeam(team, ruser)
+ th.App.LeaveTeam(team, ruser, ruser.Id)
+ if _, alreadyAdded, err := th.App.joinUserToTeam(team, ruser); alreadyAdded || err != nil {
+ t.Fatal("Should return already added equal to false and no error")
+ }
+ })
+
+ t.Run("new join with limit problem", func(t *testing.T) {
+ user1 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser1, _ := th.App.CreateUser(&user1)
+ user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser2, _ := th.App.CreateUser(&user2)
+ defer th.App.PermanentDeleteUser(&user1)
+ defer th.App.PermanentDeleteUser(&user2)
+ th.App.joinUserToTeam(team, ruser1)
+ if _, _, err := th.App.joinUserToTeam(team, ruser2); err == nil {
+ t.Fatal("Should fail")
+ }
+ })
+
+ t.Run("re-join alfter leaving with limit problem", func(t *testing.T) {
+ user1 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser1, _ := th.App.CreateUser(&user1)
+ user2 := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
+ ruser2, _ := th.App.CreateUser(&user2)
+ defer th.App.PermanentDeleteUser(&user1)
+ defer th.App.PermanentDeleteUser(&user2)
+
+ th.App.joinUserToTeam(team, ruser1)
+ th.App.LeaveTeam(team, ruser1, ruser1.Id)
+ th.App.joinUserToTeam(team, ruser2)
+ if _, _, err := th.App.joinUserToTeam(team, ruser1); err == nil {
+ t.Fatal("Should fail")
+ }
+ })
+}
diff --git a/i18n/de.json b/i18n/de.json
index b506e7018..4f9ac581f 100644
--- a/i18n/de.json
+++ b/i18n/de.json
@@ -2184,7 +2184,7 @@
},
{
"id": "api.team.add_user_to_team.added",
- "translation": "%v wurde von %v zum Team hinzugefügt"
+ "translation": "%v wurde von %v zum Team hinzugefügt."
},
{
"id": "api.team.add_user_to_team.missing_parameter.app_error",
@@ -2203,10 +2203,6 @@
"translation": "Der Link ist abgelaufen"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Der Einladungslink scheint nicht gültig zu sein"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Diese URL ist nicht verfügbar. Bitte wähle eine andere."
},
@@ -2711,6 +2707,10 @@
"translation": "Der Registrierungslink scheint nicht gültig zu sein"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Ungültiger Teamname"
},
@@ -4759,6 +4759,10 @@
"translation": "Ungültige Thumbnauilbreite in Dateieinstellungen. Muss eine positive Zahl sein."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Ungültige Diensteinstellungen für Gruppierung von ungelesenen Kanälen. Muss 'disabled', 'default_on' oder default_off' sein."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Ungültiger Bild-Proxy-Typ für Diensteinstellungen."
},
@@ -7291,10 +7295,6 @@
"translation": "Registrieren"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Der Registrierungslink scheint nicht gültig zu sein"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Der Registrierungslink ist abgelaufen"
},
@@ -7311,10 +7311,6 @@
"translation": "Der Registrierungslink ist abgelaufen"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Der Registrierungslink scheint nicht gültig zu sein"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "Dieser Teamtyp erlaubt keine offnen Einladungen"
},
diff --git a/i18n/en.json b/i18n/en.json
index b31a6bd09..3f5d0b4d3 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -2703,11 +2703,11 @@
"translation": "The signup link has expired"
},
{
- "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "id": "api.user.create_user.signup_link_invalid.app_error",
"translation": "The signup link does not appear to be valid"
},
{
- "id": "api.user.create_user.signup_link_invalid.app_error",
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
"translation": "The signup link does not appear to be valid"
},
{
@@ -3127,6 +3127,10 @@
"translation": "Invalid {{.Name}} parameter"
},
{
+ "id": "app.team.join_user_to_team.max_accounts.app_error",
+ "translation": "This team has reached the maximum number of allowed accounts. Contact your systems administrator to set a higher limit."
+ },
+ {
"id": "app.channel.create_channel.no_team_id.app_error",
"translation": "Must specify the team ID to create a channel"
},
diff --git a/i18n/es.json b/i18n/es.json
index c96674885..b3d472b9f 100644
--- a/i18n/es.json
+++ b/i18n/es.json
@@ -2203,10 +2203,6 @@
"translation": "El enlace de registro ha expirado"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "El enlace de registro parece ser inválido"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Este URL no está disponible. Por favor, prueba con otra."
},
@@ -2711,6 +2707,10 @@
"translation": "El enlace de registro parece ser inválido"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Nombre del equipo inválido"
},
@@ -4759,6 +4759,10 @@
"translation": "El ancho para la imagen de miniatura es inválido en la configuración de archivos. Debe ser un número positivo."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Ajuste invalido para el agrupamiento de canales no leídos en la configuración de servicio. Debe ser 'disabled', 'default_on' o 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Tipo de proxy para las imágenes no válido en la configuración del servicio."
},
@@ -7291,10 +7295,6 @@
"translation": "Registrar"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "El enlace de registro parece ser inválido"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "El enlace de registro ha expirado"
},
@@ -7311,10 +7311,6 @@
"translation": "El enlace de registro ha expirado"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "El enlace de registro parece ser inválido"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "El tipo de equipo no permite realizar invitaciones"
},
diff --git a/i18n/fr.json b/i18n/fr.json
index f2c20c29f..66a414e64 100644
--- a/i18n/fr.json
+++ b/i18n/fr.json
@@ -153,7 +153,7 @@
},
{
"id": "api.channel.add_member.added",
- "translation": "%v a été ajouté au canal par %v"
+ "translation": "%v a été ajouté au canal par %v."
},
{
"id": "api.channel.add_member.find_channel.app_error",
@@ -201,11 +201,11 @@
},
{
"id": "api.channel.change_channel_privacy.private_to_public",
- "translation": "This channel has been converted to a Public Channel and can be joined by any team member."
+ "translation": "Ce canal a été converti en canal public et peut être rejoint par tout membre de l'équipe."
},
{
"id": "api.channel.change_channel_privacy.public_to_private",
- "translation": "This channel has been converted to a Private Channel."
+ "translation": "Ce canal a été converti en canal privé."
},
{
"id": "api.channel.create_channel.direct_channel.app_error",
@@ -2184,7 +2184,7 @@
},
{
"id": "api.team.add_user_to_team.added",
- "translation": "%v a été ajouté à l'équipe par %v"
+ "translation": "%v a été ajouté à l'équipe par %v."
},
{
"id": "api.team.add_user_to_team.missing_parameter.app_error",
@@ -2203,10 +2203,6 @@
"translation": "Le lien d'inscription a expiré."
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Le lien d'inscription semble ne pas être valide."
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Cette URL n'est pas disponible. Veuillez en essayer une autre."
},
@@ -2711,6 +2707,10 @@
"translation": "Le lien d'enregistrement n'est pas valide."
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Nom d'équipe incorrect"
},
@@ -2956,7 +2956,7 @@
},
{
"id": "api.user.upload_profile_user.decode_config.app_error",
- "translation": "Impossible de sauvegarder l'image de profile. Le fichier ne semble pas être un fichier d'image valide."
+ "translation": "Impossible de sauvegarder l'image de profil. Le fichier ne semble pas être un fichier d'image valide."
},
{
"id": "api.user.upload_profile_user.encode.app_error",
@@ -3360,7 +3360,7 @@
},
{
"id": "app.import.validate_post_import_data.create_at_zero.error",
- "translation": "La propriété de message CreateAt ne doit pas être 0 si ce champ est défini."
+ "translation": "La propriété de message CreateAt ne doit pas être 0."
},
{
"id": "app.import.validate_post_import_data.message_length.error",
@@ -3380,51 +3380,51 @@
},
{
"id": "app.import.validate_reaction_import_data.create_at_before_parent.error",
- "translation": "Reaction CreateAt property must be greater than the parent post CreateAt."
+ "translation": "La propriété de réponse CreateAt doit être plus grande que la valeur de la propriété CreateAt parente."
},
{
"id": "app.import.validate_reaction_import_data.create_at_missing.error",
- "translation": "La propriété requise pour un message est manquante : create_at."
+ "translation": "La propriété requise de réaction est manquante : create_at."
},
{
"id": "app.import.validate_reaction_import_data.create_at_zero.error",
- "translation": "La propriété de message CreateAt ne doit pas être 0 si ce champ est défini."
+ "translation": "La propriété de réaction CreateAt ne doit pas être 0."
},
{
"id": "app.import.validate_reaction_import_data.emoji_name_length.error",
- "translation": "La propriété Message du message est plus longue que la longueur maximale autorisée."
+ "translation": "La propriété de réaction EmojiName est plus longue que la longueur maximale autorisée."
},
{
"id": "app.import.validate_reaction_import_data.emoji_name_missing.error",
- "translation": "La propriété requise du message est manquante : User."
+ "translation": "La propriété requise de réaction est manquante : EmojiName."
},
{
"id": "app.import.validate_reaction_import_data.user_missing.error",
- "translation": "La propriété requise du message est manquante : User."
+ "translation": "La propriété requise de réaction est manquante : User."
},
{
"id": "app.import.validate_reply_import_data.create_at_before_parent.error",
- "translation": "Reply CreateAt property must be greater than the parent post CreateAt."
+ "translation": "La propriété de réponse CreateAt doit être plus grande que la valeur de la propriété CreateAt parente."
},
{
"id": "app.import.validate_reply_import_data.create_at_missing.error",
- "translation": "La propriété requise pour un message est manquante : create_at."
+ "translation": "La propriété requise de réponse est manquante : create_at."
},
{
"id": "app.import.validate_reply_import_data.create_at_zero.error",
- "translation": "La propriété de message CreateAt ne doit pas être 0 si ce champ est défini."
+ "translation": "La propriété de message CreateAt ne doit pas être 0."
},
{
"id": "app.import.validate_reply_import_data.message_length.error",
- "translation": "La propriété Message du message est plus longue que la longueur maximale autorisée."
+ "translation": "La propriété de réponse Message est plus longue que la longueur maximale autorisée."
},
{
"id": "app.import.validate_reply_import_data.message_missing.error",
- "translation": "La propriété requise du message est manquante : Message."
+ "translation": "La propriété requise de réponse est manquante : Message."
},
{
"id": "app.import.validate_reply_import_data.user_missing.error",
- "translation": "La propriété requise du message est manquante : User."
+ "translation": "La propriété requise de réponse est manquante : User."
},
{
"id": "app.import.validate_team_import_data.allowed_domains_length.error",
@@ -3564,7 +3564,7 @@
},
{
"id": "app.import.validate_user_import_data.profile_image.error",
- "translation": "Invalid profile image."
+ "translation": "Image de profil invalide."
},
{
"id": "app.import.validate_user_import_data.roles_invalid.error",
@@ -4644,7 +4644,7 @@
},
{
"id": "model.config.is_valid.atmos_camo_image_proxy_options.app_error",
- "translation": "Invalid atmos/camo image proxy options for service settings. Must be set to your shared key."
+ "translation": "Les paramètres d'options du proxy d'image atmos/camo sont invalides. Votre clé partagée doit être définie comme paramètre."
},
{
"id": "model.config.is_valid.cluster_email_batching.app_error",
@@ -4759,8 +4759,12 @@
"translation": "Largeur des miniatures invalide dans les paramètres de fichiers. Doit être un entier positif."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Le paramètre de groupement de canaux non lus est invalide. Doit être défini sur « disabled », « default_on » ou « default_off »."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
- "translation": "Invalid image proxy type for service settings."
+ "translation": "Paramètre de type de proxy d'image invalide."
},
{
"id": "model.config.is_valid.ldap_basedn",
@@ -5404,7 +5408,7 @@
},
{
"id": "model.user.is_valid.position.app_error",
- "translation": "Rôle invalide : ne doit pas faire plus de 35 caractères."
+ "translation": "Rôle invalide : ne doit pas faire plus de 128 caractères."
},
{
"id": "model.user.is_valid.pwd.app_error",
@@ -6848,7 +6852,7 @@
},
{
"id": "store.sql_user_access_token.get_all.app_error",
- "translation": "Impossible de récupérer le jeton d'accès personnel"
+ "translation": "Impossible de récupérer tous les jetons d'accès personnel"
},
{
"id": "store.sql_user_access_token.get_by_token.app_error",
@@ -6864,7 +6868,7 @@
},
{
"id": "store.sql_user_access_token.search.app_error",
- "translation": "Nous avons rencontré une erreur lors de la recherche du jeton d'accès"
+ "translation": "Nous avons rencontré une erreur lors de la recherche des jetons d'accès personnel"
},
{
"id": "store.sql_webhooks.analytics_incoming_count.app_error",
@@ -7291,10 +7295,6 @@
"translation": "Inscription"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Le lien d'inscription ne semble pas être valide"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Le lien d'inscription a expiré"
},
@@ -7311,10 +7311,6 @@
"translation": "Le lien d'inscription a expiré"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Le lien d'inscription ne semble pas être valide"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "Le type d'équipe ne permet pas les invitations ouvertes"
},
diff --git a/i18n/it.json b/i18n/it.json
index a58dfa15a..c2f62ae5d 100644
--- a/i18n/it.json
+++ b/i18n/it.json
@@ -2203,10 +2203,6 @@
"translation": "Il collegamento per l'iscrizione è scaduto"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Il collegamento per l'iscrizione non sembra essere valido"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "L'URL non è disponibile. Provane un altro."
},
@@ -2711,6 +2707,10 @@
"translation": "Il collegamento per l'iscrizione non sembra essere valido"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Nome gruppo non valido"
},
@@ -4759,6 +4759,10 @@
"translation": "Larghezza antemprima non valida per le impostazioni file. Deve essere un numero positivo."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Canali non letti del gruppo non validi per le impostazioni del servizio. Dev'essere 'disabled', 'default_on' oppure 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Tipo proxy immagine non valido nelle impostazioni del servizio."
},
@@ -7291,10 +7295,6 @@
"translation": "Iscrizione"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Il collegamento per l'iscrizione non sembra essere valido"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Il collegamento per l'iscrizione è scaduto"
},
@@ -7311,10 +7311,6 @@
"translation": "Il collegamento per l'iscrizione è scaduto"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Il collegamento per l'iscrizione non sembra essere valido"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "La tipologia del gruppo non ammette inviti aperti"
},
diff --git a/i18n/ja.json b/i18n/ja.json
index 3017f94dc..c525f471b 100644
--- a/i18n/ja.json
+++ b/i18n/ja.json
@@ -2203,10 +2203,6 @@
"translation": "利用登録リンクは有効期限が切れています"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "利用登録リンクが不正です"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "このURLは利用できません。他のURLを試してみてください。"
},
@@ -2711,6 +2707,10 @@
"translation": "利用登録リンクが不正です"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "不正なチーム名です"
},
@@ -4759,6 +4759,10 @@
"translation": "ファイル設定のサムネイルの幅が不正です。ゼロ以上の数を指定してください。"
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "未読チャンネルのグループ化設定が不正です。'disabled', 'default_on', 'default_off'のいずれかでなくてはなりません。"
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "画像プロキシタイプの設定が不正です。"
},
@@ -7291,10 +7295,6 @@
"translation": "利用登録"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "利用登録リンクが不正です"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "利用登録リンクの期限が切れています"
},
@@ -7311,10 +7311,6 @@
"translation": "利用登録リンクの期限が切れています"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "利用登録リンクが不正です"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "このチームは誰でも招待できるような形式ではありません"
},
diff --git a/i18n/ko.json b/i18n/ko.json
index bdd2935a4..68fb33734 100644
--- a/i18n/ko.json
+++ b/i18n/ko.json
@@ -2203,10 +2203,6 @@
"translation": "가입 링크가 만료되었습니다."
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "유효하지 않은 가입 링크입니다."
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "유효하지 않는 URL 입니다. 변경 후 다시 시도해주세요."
},
@@ -2711,6 +2707,10 @@
"translation": "유효하지 않은 가입 링크입니다."
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "올바르지 않은 팀 이름"
},
@@ -3136,7 +3136,7 @@
},
{
"id": "app.channel.post_update_channel_purpose_message.post.error",
- "translation": "Failed to post channel purpose message"
+ "translation": "들어옴/나감 메시지를 등록하는 데 실패함"
},
{
"id": "app.channel.post_update_channel_purpose_message.removed",
@@ -4759,6 +4759,10 @@
"translation": "파일 세팅에 대한 잘못된 썸네일 너비값입니다. 0보다 큰 값이여야 합니다."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Invalid group unread channels for service settings. Must be 'disabled', 'default_on', or 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Invalid image proxy type for service settings."
},
@@ -7291,10 +7295,6 @@
"translation": "가입"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "유효하지 않은 가입 링크입니다."
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "가입 링크가 만료되었습니다."
},
@@ -7311,10 +7311,6 @@
"translation": "가입 링크가 만료되었습니다."
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "유효하지 않은 가입 링크입니다."
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "The team type doesn't allow open invites"
},
diff --git a/i18n/nl.json b/i18n/nl.json
index 2e0f54ee4..2e02433e4 100644
--- a/i18n/nl.json
+++ b/i18n/nl.json
@@ -49,7 +49,7 @@
},
{
"id": "api.admin.add_certificate.no_file.app_error",
- "translation": "Geen bestand in 'certificate' veld in aanvraag"
+ "translation": "Geen bestand gevonden in 'certificate' veld in verzoek"
},
{
"id": "api.admin.add_certificate.open.app_error",
@@ -57,15 +57,15 @@
},
{
"id": "api.admin.add_certificate.saving.app_error",
- "translation": "Kon het certificaat-bestand niet opslaan"
+ "translation": "Kon het certificaat-bestand niet opslaan."
},
{
"id": "api.admin.file_read_error",
- "translation": "Fout bij lezen van logbestand"
+ "translation": "Fout bij lezen van logbestand."
},
{
"id": "api.admin.get_brand_image.not_available.app_error",
- "translation": "Personaliseren is niet ondersteund, of niet geconfigureerd op deze server"
+ "translation": "Personalisatie is niet ondersteund of niet geconfigureerd op deze server."
},
{
"id": "api.admin.get_brand_image.storage.app_error",
@@ -73,15 +73,15 @@
},
{
"id": "api.admin.init.debug",
- "translation": "Initialisatie van de admin API routes"
+ "translation": "Initialisatie van de admin API routes."
},
{
"id": "api.admin.recycle_db_end.warn",
- "translation": "Klaar met herstarten van de databaseverbinding"
+ "translation": "Klaar met herstarten van de databaseverbinding."
},
{
"id": "api.admin.recycle_db_start.warn",
- "translation": "Proberen om de databaseverbinding te herstarten"
+ "translation": "Proberen om de databaseverbinding te herstarten."
},
{
"id": "api.admin.remove_certificate.delete.app_error",
@@ -89,7 +89,7 @@
},
{
"id": "api.admin.saml.metadata.app_error",
- "translation": "Er is een fout opgetreden tijdens het opstellen van Service Provider Metadata."
+ "translation": "Er is een fout opgetreden tijdens het opzetten van Service Provider Metadata."
},
{
"id": "api.admin.test_email.body",
@@ -153,7 +153,7 @@
},
{
"id": "api.channel.add_member.added",
- "translation": "%v is door %v aan het kanaal toegevoegd"
+ "translation": "%v is door %v aan het kanaal toegevoegd."
},
{
"id": "api.channel.add_member.find_channel.app_error",
@@ -185,11 +185,11 @@
},
{
"id": "api.channel.can_manage_channel.private_restricted_system_admin.app_error",
- "translation": "Alleen systeembeheerders mogen publieke kanalen beheren en aanmaken."
+ "translation": "Alleen systeembeheerders mogen privékanalen beheren en aanmaken."
},
{
"id": "api.channel.can_manage_channel.private_restricted_team_admin.app_error",
- "translation": "Alleen team- en systeembeheerders mogen publieke kanalen beheren en aanmaken."
+ "translation": "Alleen team- en systeembeheerders mogen privékanalen beheren en aanmaken."
},
{
"id": "api.channel.can_manage_channel.public_restricted_system_admin.app_error",
@@ -201,11 +201,11 @@
},
{
"id": "api.channel.change_channel_privacy.private_to_public",
- "translation": "This channel has been converted to a Public Channel and can be joined by any team member."
+ "translation": "Dit kanaal is omgezet naar een publiek kanaal en is open voor ieder teamlid."
},
{
"id": "api.channel.change_channel_privacy.public_to_private",
- "translation": "This channel has been converted to a Private Channel."
+ "translation": "This kanaal is omgezet naar een privékanaal."
},
{
"id": "api.channel.create_channel.direct_channel.app_error",
@@ -229,15 +229,15 @@
},
{
"id": "api.channel.create_direct_channel.invalid_user.app_error",
- "translation": "Invalid user ID for direct channel creation"
+ "translation": "Onjuiste gebruikers ID voor het aanmaken van een direct kanaal."
},
{
"id": "api.channel.create_group.bad_size.app_error",
- "translation": "Group message channels must contain at least 3 and no more than 8 users"
+ "translation": "Groep bericht kanalen moeten tenminste 3 en niet meer dan 8 gebruikers bevatten"
},
{
"id": "api.channel.create_group.bad_user.app_error",
- "translation": "One of the provided users does not exist"
+ "translation": "Een van de opgegeven gebruikers bestaat niet"
},
{
"id": "api.channel.delete_channel.archived",
@@ -305,7 +305,7 @@
},
{
"id": "api.channel.join_channel.post_and_forget",
- "translation": "%v is het kanaal binnengekomen."
+ "translation": "%v is nu lid van het kanaal."
},
{
"id": "api.channel.leave.default.app_error",
@@ -317,7 +317,7 @@
},
{
"id": "api.channel.leave.last_member.app_error",
- "translation": "U bent het laatste lid, probeer de privégroep te verwijderen in plaats van die te verlaten."
+ "translation": "U bent het laatste lid, probeer de privékanaalte verwijderen in plaats van die te verlaten."
},
{
"id": "api.channel.leave.left",
@@ -329,7 +329,7 @@
},
{
"id": "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error",
- "translation": "Kon de gebruiker niet ophalen tijdens het bewaren van de nieuwe kanaalkoptekst %v"
+ "translation": "Kon de gebruiker niet ophalen tijdens het bijwerken van het kanaal weergavenaam veld"
},
{
"id": "api.channel.post_update_channel_displayname_message_and_forget.updated_from",
@@ -337,7 +337,7 @@
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.post.error",
- "translation": "Failed to post update channel header message"
+ "translation": "Kanaalkoptekst bijwerken mislukt"
},
{
"id": "api.channel.post_update_channel_header_message_and_forget.removed",
@@ -2203,10 +2203,6 @@
"translation": "De aanmeld link is verlopen"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "De aanmeld link is niet geldig"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Deze URL is niet beschikbaar. Probeer een andere."
},
@@ -2711,6 +2707,10 @@
"translation": "De aanmeld link is niet geldig"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Ongeldige team naam"
},
@@ -3136,7 +3136,7 @@
},
{
"id": "app.channel.post_update_channel_purpose_message.post.error",
- "translation": "Failed to post channel purpose message"
+ "translation": "Plaatsen van bericht over binnenkomen/verlaten %v is mislukt"
},
{
"id": "app.channel.post_update_channel_purpose_message.removed",
@@ -3204,7 +3204,7 @@
},
{
"id": "app.import.import_line.null_channel.error",
- "translation": "Import data line has type \"channel\" but the channel object is null."
+ "translation": "Geimporteerde lijn met type \"user\", maar het \"user\" object is null."
},
{
"id": "app.import.import_line.null_direct_channel.error",
@@ -3216,15 +3216,15 @@
},
{
"id": "app.import.import_line.null_post.error",
- "translation": "Import data line has type \"post\" but the post object is null."
+ "translation": "Geimporteerde lijn met type \"user\", maar het \"user\" object is null."
},
{
"id": "app.import.import_line.null_team.error",
- "translation": "Import data line has type \"team\" but the team object is null."
+ "translation": "Geimporteerde lijn met type \"user\", maar het \"user\" object is null."
},
{
"id": "app.import.import_line.null_user.error",
- "translation": "Import data line has type \"user\" but the user object is null."
+ "translation": "Geimporteerde lijn met type \"user\", maar het \"user\" object is null."
},
{
"id": "app.import.import_line.unknown_line_type.error",
@@ -3252,7 +3252,7 @@
},
{
"id": "app.import.validate_channel_import_data.create_at_zero.error",
- "translation": "Channel create_at must not be zero if provided."
+ "translation": "Kanaaleigenschap create_at mag niet 0 zijn indien opgegeven."
},
{
"id": "app.import.validate_channel_import_data.display_name_length.error",
@@ -3276,7 +3276,7 @@
},
{
"id": "app.import.validate_channel_import_data.name_missing.error",
- "translation": "Missing required channel property: name"
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_channel_import_data.purpose_length.error",
@@ -3292,7 +3292,7 @@
},
{
"id": "app.import.validate_channel_import_data.type_missing.error",
- "translation": "Missing required channel property: type."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_direct_channel_import_data.header_length.error",
@@ -3352,7 +3352,7 @@
},
{
"id": "app.import.validate_post_import_data.channel_missing.error",
- "translation": "Missing required Post property: Channel."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_post_import_data.create_at_missing.error",
@@ -3368,19 +3368,19 @@
},
{
"id": "app.import.validate_post_import_data.message_missing.error",
- "translation": "Missing required Post property: Message."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_post_import_data.team_missing.error",
- "translation": "Missing required Post property: Team."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_post_import_data.user_missing.error",
- "translation": "Missing required Post property: User."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_reaction_import_data.create_at_before_parent.error",
- "translation": "Reaction CreateAt property must be greater than the parent post CreateAt."
+ "translation": "Reactie CreateAt eigenschap moet groter zijn dan het hoofdbericht CreateAt"
},
{
"id": "app.import.validate_reaction_import_data.create_at_missing.error",
@@ -3400,11 +3400,11 @@
},
{
"id": "app.import.validate_reaction_import_data.user_missing.error",
- "translation": "Missing required Reaction property: User."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_reply_import_data.create_at_before_parent.error",
- "translation": "Reply CreateAt property must be greater than the parent post CreateAt."
+ "translation": "Reactie CreateAt eigenschap moet groter zijn dan het hoofdbericht CreateAt"
},
{
"id": "app.import.validate_reply_import_data.create_at_missing.error",
@@ -3420,11 +3420,11 @@
},
{
"id": "app.import.validate_reply_import_data.message_missing.error",
- "translation": "Missing required Reply property: Message."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_reply_import_data.user_missing.error",
- "translation": "Missing required Reply property: User."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_team_import_data.allowed_domains_length.error",
@@ -3432,7 +3432,7 @@
},
{
"id": "app.import.validate_team_import_data.create_at_zero.error",
- "translation": "Team create_at must not be zero if provided."
+ "translation": "Kanaaleigenschap create_at mag niet 0 zijn indien opgegeven."
},
{
"id": "app.import.validate_team_import_data.description_length.error",
@@ -3444,7 +3444,7 @@
},
{
"id": "app.import.validate_team_import_data.display_name_missing.error",
- "translation": "Missing required team property: display_name."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_team_import_data.name_characters.error",
@@ -3456,7 +3456,7 @@
},
{
"id": "app.import.validate_team_import_data.name_missing.error",
- "translation": "Missing required team property: name."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_team_import_data.name_reserved.error",
@@ -3468,7 +3468,7 @@
},
{
"id": "app.import.validate_team_import_data.type_missing.error",
- "translation": "Missing required team property: type."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_user_channels_import_data.channel_name_missing.error",
@@ -3508,7 +3508,7 @@
},
{
"id": "app.import.validate_user_import_data.email_missing.error",
- "translation": "Missing required user property: email."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_user_import_data.first_name_length.error",
@@ -3576,7 +3576,7 @@
},
{
"id": "app.import.validate_user_import_data.username_missing.error",
- "translation": "Missing require user property: username."
+ "translation": "Mist vereiste team kenmerk: naam."
},
{
"id": "app.import.validate_user_teams_import_data.invalid_roles.error",
@@ -4028,7 +4028,7 @@
},
{
"id": "ent.elasticsearch.test_config.connect_failed",
- "translation": "Connecting to Elasticsearch server failed."
+ "translation": "Connectie naar Elasticsearch server is mislukt."
},
{
"id": "ent.elasticsearch.test_config.indexing_disabled.error",
@@ -4672,7 +4672,7 @@
},
{
"id": "model.config.is_valid.elastic_search.connection_url.app_error",
- "translation": "Elastic Search ConnectionUrl setting must be provided when Elastic Search indexing is enabled."
+ "translation": "Elastic Search Username instelling moet ingevuld zijn wanneer Elastic Search indexing is ingeschakeld."
},
{
"id": "model.config.is_valid.elastic_search.enable_searching.app_error",
@@ -4684,7 +4684,7 @@
},
{
"id": "model.config.is_valid.elastic_search.password.app_error",
- "translation": "Elastic Search Password setting must be provided when Elastic Search indexing is enabled."
+ "translation": "Elastic Search Username instelling moet ingevuld zijn wanneer Elastic Search indexing is ingeschakeld."
},
{
"id": "model.config.is_valid.elastic_search.posts_aggregator_job_start_time.app_error",
@@ -4696,7 +4696,7 @@
},
{
"id": "model.config.is_valid.elastic_search.username.app_error",
- "translation": "Elastic Search Username setting must be provided when Elastic Search indexing is enabled."
+ "translation": "Elastic Search Username instelling moet ingevuld zijn wanneer Elastic Search indexing is ingeschakeld."
},
{
"id": "model.config.is_valid.email_batching_buffer_size.app_error",
@@ -4759,6 +4759,10 @@
"translation": "Ongeldige voorvertonings breedte bij bestands instellingen. Moet een getal groter dan 0 zijn."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Invalid group unread channels for service settings. Must be 'disabled', 'default_on', or 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Invalid image proxy type for service settings."
},
@@ -7291,10 +7295,6 @@
"translation": "Aanmelden"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "De aanmeld link is niet geldig"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "De aanmeld link is verlopen"
},
@@ -7311,10 +7311,6 @@
"translation": "De aanmeld link is verlopen"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "De aanmeld link is niet geldig"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "Het team type staat open uitnodiging niet toe"
},
diff --git a/i18n/pl.json b/i18n/pl.json
index ccf9fed39..d149f38b0 100644
--- a/i18n/pl.json
+++ b/i18n/pl.json
@@ -2203,10 +2203,6 @@
"translation": "Odnośnik zapisu jest przeterminowany"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Odnośnik zapisu nie wydaje się być poprawny"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Ten adres URL jest niedostępny. Proszę wybrać inny."
},
@@ -2711,6 +2707,10 @@
"translation": "Link rejestracyjny wydaje się być niepoprawny"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Niepoprawna nazwa zespołu"
},
@@ -4759,6 +4759,10 @@
"translation": "Nieprawidłowa szerokość miniaturki dla ustawień plików. Musi być liczbą większą od 0."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Invalid group unread channels for service settings. Must be 'disabled', 'default_on', or 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Invalid image proxy type for service settings."
},
@@ -7291,10 +7295,6 @@
"translation": "Rejestracja"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Link do rejestracji jest niepoprawny"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Link do rejestracji wygasł"
},
@@ -7311,10 +7311,6 @@
"translation": "Link do rejestracji wygasł"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Link do rejestracji jest niepoprawny"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "The team type doesn't allow open invites"
},
diff --git a/i18n/pt-BR.json b/i18n/pt-BR.json
index b07cb452e..3ec45c2eb 100644
--- a/i18n/pt-BR.json
+++ b/i18n/pt-BR.json
@@ -2203,10 +2203,6 @@
"translation": "O link de inscrição expirou"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "O link de inscrição não parece ser válido"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Esta URL não está disponível. Por favor, tente outra."
},
@@ -2711,6 +2707,10 @@
"translation": "O link de inscrição não parece ser válido"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Inválido nome de equipe"
},
@@ -4759,6 +4759,10 @@
"translation": "Definição da largura do thumbnail inválida. Deve ser um número positivo."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Grupo de canais não lidos inválido nas configurações do serviço. Deve ser 'disabled', 'default_on', ou 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Tipo de proxy de imagem inválido nas configurações de serviços."
},
@@ -7291,10 +7295,6 @@
"translation": "Inscrever-se"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "O link de inscrição não parece ser válido"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "O link de inscrição expirou"
},
@@ -7311,10 +7311,6 @@
"translation": "O link de inscrição expirou"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "O link de inscrição não parece ser válido"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "O tipo da equipe não permite convites abertos"
},
diff --git a/i18n/ru.json b/i18n/ru.json
index b1e37d191..cb4d26d45 100644
--- a/i18n/ru.json
+++ b/i18n/ru.json
@@ -201,11 +201,11 @@
},
{
"id": "api.channel.change_channel_privacy.private_to_public",
- "translation": "This channel has been converted to a Public Channel and can be joined by any team member."
+ "translation": "Канал преобразован в публичный и к нему может присоединиться любой участник."
},
{
"id": "api.channel.change_channel_privacy.public_to_private",
- "translation": "This channel has been converted to a Private Channel."
+ "translation": "Канал преобразован в приватный."
},
{
"id": "api.channel.create_channel.direct_channel.app_error",
@@ -2203,10 +2203,6 @@
"translation": "Ссылка на регистрацию устарела"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Неправильная ссылка на регистрацию"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Этот URL-адрес недоступен. Пожалуйста, попробуйте другой."
},
@@ -2711,6 +2707,10 @@
"translation": "Ссылка для регистрации, похоже, неверна."
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Неверное имя команды"
},
@@ -3248,7 +3248,7 @@
},
{
"id": "app.import.import_user_channels.save_preferences.error",
- "translation": "Error importing user channel memberships. Failed to save preferences."
+ "translation": "Ошибка импорта участия пользователя в каналах. Не удалось сохранить настройки."
},
{
"id": "app.import.validate_channel_import_data.create_at_zero.error",
@@ -3296,7 +3296,7 @@
},
{
"id": "app.import.validate_direct_channel_import_data.header_length.error",
- "translation": "Direct channel header is too long"
+ "translation": "Заголовок личного канала слишком длинный."
},
{
"id": "app.import.validate_direct_channel_import_data.members_required.error",
@@ -3304,11 +3304,11 @@
},
{
"id": "app.import.validate_direct_channel_import_data.members_too_few.error",
- "translation": "Direct channel members list contains too few items"
+ "translation": "В списке пользователей личного канала слишком мало элементов."
},
{
"id": "app.import.validate_direct_channel_import_data.members_too_many.error",
- "translation": "Direct channel members list contains too many items"
+ "translation": "В списке пользователей личного канала слишком много элементов."
},
{
"id": "app.import.validate_direct_channel_import_data.unknown_favoriter.error",
@@ -3320,11 +3320,11 @@
},
{
"id": "app.import.validate_direct_post_import_data.channel_members_too_few.error",
- "translation": "Direct post channel members list contains too few items"
+ "translation": "В списке пользователей личного канала слишком мало элементов."
},
{
"id": "app.import.validate_direct_post_import_data.channel_members_too_many.error",
- "translation": "Direct post channel members list contains too many items"
+ "translation": "В списке пользователей личного канала слишком много элементов."
},
{
"id": "app.import.validate_direct_post_import_data.create_at_missing.error",
@@ -4759,6 +4759,10 @@
"translation": "Неверная ширина миниатюры в настройках файлов. Число должно быть положительным."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Invalid group unread channels for service settings. Must be 'disabled', 'default_on', or 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Invalid image proxy type for service settings."
},
@@ -7291,10 +7295,6 @@
"translation": "Регистрация"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Ссылка для регистрации, похоже, недействительна"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Ссылка для регистрации устарела"
},
@@ -7311,10 +7311,6 @@
"translation": "Ссылка для регистрации устарела"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Ссылка для регистрации, похоже, недействительна"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "Тип команды не позволяет открытые приглашения"
},
diff --git a/i18n/tr.json b/i18n/tr.json
index b95c9b542..ae782ddb4 100644
--- a/i18n/tr.json
+++ b/i18n/tr.json
@@ -2203,10 +2203,6 @@
"translation": "Hesap açma bağlantısının süresi geçmiş"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "Hesap açma bağlantısı geçersiz görünüyor"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "Adres kullanılamıyor. Lütfen yeniden deneyin."
},
@@ -2711,6 +2707,10 @@
"translation": "Hesap açma bağlantısı geçersiz görünüyor"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "Takım adı geçersiz"
},
@@ -4759,6 +4759,10 @@
"translation": "Küçük görsel genişliği dosya ayarı geçersiz. Sıfır ya da pozitif bir sayı olmalı."
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Hizmet ayarları okunmamış kanallar gruplansın geçersiz. 'disabled', 'default_on' ya da 'default_off' olmalıdır."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "Hizmet ayarlarında görsel vekil sunucu türü geçersiz."
},
@@ -7291,10 +7295,6 @@
"translation": "Hesap Açın"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "Hesap açma bağlantısı geçersiz görünüyor"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "Hesap açma bağlantısının süresi geçmiş"
},
@@ -7311,10 +7311,6 @@
"translation": "Hesap açma bağlantısının süresi geçmiş"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "Hesap açma bağlantısı geçersiz görünüyor"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "Takım türü açık çağrılara izin vermiyor"
},
diff --git a/i18n/zh-CN.json b/i18n/zh-CN.json
index fb484b50d..9186f936e 100644
--- a/i18n/zh-CN.json
+++ b/i18n/zh-CN.json
@@ -2203,10 +2203,6 @@
"translation": "注册链接已过期"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "注册链接无效"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "该URL无效。请尝试其他。"
},
@@ -2711,6 +2707,10 @@
"translation": "注册链接无效"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "无效团队名称"
},
@@ -4759,6 +4759,10 @@
"translation": "文件设置时缩略图宽度无效。必须是正数。"
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "Invalid group unread channels for service settings. Must be 'disabled', 'default_on', or 'default_off'."
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
"translation": "无效的图片代理类型服务设定。"
},
@@ -7291,10 +7295,6 @@
"translation": "注册"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "注册链接无效"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "注册链接已过期"
},
@@ -7311,10 +7311,6 @@
"translation": "注册链接已过期"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "注册链接无效"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "团队类型不允许公开邀请"
},
diff --git a/i18n/zh-TW.json b/i18n/zh-TW.json
index a7387d88f..e31a35941 100644
--- a/i18n/zh-TW.json
+++ b/i18n/zh-TW.json
@@ -2203,10 +2203,6 @@
"translation": "註冊連結已過期"
},
{
- "id": "api.team.create_team_from_signup.invalid_link.app_error",
- "translation": "此註冊連結不是有效連結"
- },
- {
"id": "api.team.create_team_from_signup.unavailable.app_error",
"translation": "這個網址不存在。請嘗試其他的。"
},
@@ -2711,6 +2707,10 @@
"translation": "此註冊連結不是有效連結"
},
{
+ "id": "api.user.create_user.signup_link_mismatched_invite_id.app_error",
+ "translation": "The signup link does not appear to be valid"
+ },
+ {
"id": "api.user.create_user.team_name.app_error",
"translation": "無效的團隊名稱"
},
@@ -3564,7 +3564,7 @@
},
{
"id": "app.import.validate_user_import_data.profile_image.error",
- "translation": "Invalid profile image."
+ "translation": "無效的個人頭像。"
},
{
"id": "app.import.validate_user_import_data.roles_invalid.error",
@@ -4644,7 +4644,7 @@
},
{
"id": "model.config.is_valid.atmos_camo_image_proxy_options.app_error",
- "translation": "Invalid atmos/camo image proxy options for service settings. Must be set to your shared key."
+ "translation": "服務設定中的 atmos/camo 圖片代理無效。必須設定為分享金鑰。"
},
{
"id": "model.config.is_valid.cluster_email_batching.app_error",
@@ -4759,8 +4759,12 @@
"translation": "檔案設定中縮圖寬度無效。必須為正數。"
},
{
+ "id": "model.config.is_valid.group_unread_channels.app_error",
+ "translation": "服務設定中的未讀頻道分組無效。必須為 'disabled' 、 'default_on' 或 'default_off'。"
+ },
+ {
"id": "model.config.is_valid.image_proxy_type.app_error",
- "translation": "Invalid image proxy type for service settings."
+ "translation": "服務設定中的圖片代理類型無效。"
},
{
"id": "model.config.is_valid.ldap_basedn",
@@ -5404,7 +5408,7 @@
},
{
"id": "model.user.is_valid.position.app_error",
- "translation": "無效的位置:不能超過35個字元。"
+ "translation": "無效的位置:不能超過128個字元。"
},
{
"id": "model.user.is_valid.pwd.app_error",
@@ -6848,7 +6852,7 @@
},
{
"id": "store.sql_user_access_token.get_all.app_error",
- "translation": "無法取得個人存取 Token"
+ "translation": "無法取得全部的個人存取 Token"
},
{
"id": "store.sql_user_access_token.get_by_token.app_error",
@@ -7291,10 +7295,6 @@
"translation": "註冊"
},
{
- "id": "web.signup_team_complete.invalid_link.app_error",
- "translation": "此註冊連結不是有效連結"
- },
- {
"id": "web.signup_team_complete.link_expired.app_error",
"translation": "註冊連結已過期"
},
@@ -7311,10 +7311,6 @@
"translation": "註冊連結已過期"
},
{
- "id": "web.signup_user_complete.link_invalid.app_error",
- "translation": "此註冊連結不是有效連結"
- },
- {
"id": "web.signup_user_complete.no_invites.app_error",
"translation": "此團隊類型不允許自由加入"
},
diff --git a/model/channel_member_history_result.go b/model/channel_member_history_result.go
new file mode 100644
index 000000000..ed3e79639
--- /dev/null
+++ b/model/channel_member_history_result.go
@@ -0,0 +1,15 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+type ChannelMemberHistoryResult struct {
+ ChannelId string
+ UserId string
+ JoinTime int64
+ LeaveTime *int64
+
+ // these two fields are never set in the database - when we SELECT, we join on Users to get them
+ UserEmail string `db:"Email"`
+ Username string
+}
diff --git a/store/sqlstore/channel_member_history_store.go b/store/sqlstore/channel_member_history_store.go
index 182f37ce9..9d077ab51 100644
--- a/store/sqlstore/channel_member_history_store.go
+++ b/store/sqlstore/channel_member_history_store.go
@@ -106,7 +106,7 @@ func (s SqlChannelMemberHistoryStore) hasDataAtOrBefore(time int64) (bool, error
}
}
-func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) {
+func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistoryResult, error) {
query := `
SELECT
cmh.*,
@@ -119,7 +119,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime
ORDER BY cmh.JoinTime ASC`
params := map[string]interface{}{"ChannelId": channelId, "StartTime": startTime, "EndTime": endTime}
- var histories []*model.ChannelMemberHistory
+ var histories []*model.ChannelMemberHistoryResult
if _, err := s.GetReplica().Select(&histories, query, params); err != nil {
return nil, err
} else {
@@ -127,7 +127,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime
}
}
-func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) {
+func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistoryResult, error) {
query := `
SELECT DISTINCT
ch.ChannelId,
@@ -138,7 +138,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64
WHERE ch.ChannelId = :ChannelId`
params := map[string]interface{}{"ChannelId": channelId}
- var histories []*model.ChannelMemberHistory
+ var histories []*model.ChannelMemberHistoryResult
if _, err := s.GetReplica().Select(&histories, query, params); err != nil {
return nil, err
} else {
diff --git a/store/sqlstore/upgrade.go b/store/sqlstore/upgrade.go
index 7c1522f25..75286d214 100644
--- a/store/sqlstore/upgrade.go
+++ b/store/sqlstore/upgrade.go
@@ -344,6 +344,8 @@ func UpgradeDatabaseToVersion47(sqlStore SqlStore) {
if shouldPerformUpgrade(sqlStore, VERSION_4_6_0, VERSION_4_7_0) {
sqlStore.AlterColumnTypeIfExists("Users", "Position", "varchar(128)", "varchar(128)")
sqlStore.AlterColumnTypeIfExists("OAuthAuthData", "State", "varchar(1024)", "varchar(1024)")
+ sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Email")
+ sqlStore.RemoveColumnIfExists("ChannelMemberHistory", "Username")
saveSchemaVersion(sqlStore, VERSION_4_7_0)
}
}
diff --git a/store/storetest/channel_member_history_store.go b/store/storetest/channel_member_history_store.go
index 6fe73478c..0d0cac81d 100644
--- a/store/storetest/channel_member_history_store.go
+++ b/store/storetest/channel_member_history_store.go
@@ -99,11 +99,11 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
store.Must(ss.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, joinTime))
// case 1: user joins and leaves the channel before the export period begins
- channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 0)
// case 2: user joins the channel after the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -112,7 +112,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Nil(t, channelMembers[0].LeaveTime)
// case 3: user joins the channel before the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -124,7 +124,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
store.Must(ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, leaveTime))
// case 4: user joins the channel before the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -133,7 +133,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime)
// case 5: user joins the channel after the export period begins, and leaves the channel before the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -142,7 +142,7 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime)
// case 6: user has joined and left the channel long before the export period begins
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 0)
}
@@ -187,7 +187,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
// the past, even though the time that they were actually in the channel doesn't necessarily overlap with the export period
// case 1: user joins and leaves the channel before the export period begins
- channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-500, joinTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -196,7 +196,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, joinTime-100, *channelMembers[0].LeaveTime)
// case 2: user joins the channel after the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -205,7 +205,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime)
// case 3: user joins the channel before the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, joinTime+500, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -214,7 +214,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime)
// case 4: user joins the channel before the export period begins, but has not yet left the channel when the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+100, leaveTime-100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -223,7 +223,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, leaveTime-100, *channelMembers[0].LeaveTime)
// case 5: user joins the channel after the export period begins, and leaves the channel before the export period ends
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime-100, leaveTime+100, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -232,7 +232,7 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, leaveTime+100, *channelMembers[0].LeaveTime)
// case 6: user has joined and left the channel long before the export period begins
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(leaveTime+100, leaveTime+200, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId)
@@ -274,7 +274,7 @@ func testPermanentDeleteBatch(t *testing.T, ss store.Store) {
store.Must(ss.ChannelMemberHistory().LogJoinEvent(user2.Id, channel.Id, joinTime))
// in between the join time and the leave time, both users were members of the channel
- channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers := store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 2)
// the permanent delete should delete at least one record
@@ -282,7 +282,7 @@ func testPermanentDeleteBatch(t *testing.T, ss store.Store) {
assert.NotEqual(t, int64(0), rowsDeleted)
// after the delete, there should be one less member in the channel
- channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistory)
+ channelMembers = store.Must(ss.ChannelMemberHistory().GetUsersInChannelDuring(joinTime+10, leaveTime-10, channel.Id)).([]*model.ChannelMemberHistoryResult)
assert.Len(t, channelMembers, 1)
assert.Equal(t, user2.Id, channelMembers[0].UserId)
}