diff --git a/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts index 9c67b1250b..232f62acdf 100644 --- a/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts @@ -69,7 +69,7 @@ describe('Verify Accessibility Support in Channel Sidebar Navigation', () => { cy.uiGetLHSAddChannelButton().focus().tab().tab({shift: true}); // * Verify if the Plus button has focus - cy.findByRole('button', {name: 'Add Channel Dropdown'}).should('be.focused'); + cy.uiGetLHSAddChannelButton().should('be.focused'); cy.focused().tab(); // * Verify if the Plus button has focus diff --git a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts index bf2f6e9011..f7b71b4115 100644 --- a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts @@ -140,7 +140,7 @@ function createCategoryFromSidebarMenu() { const categoryName = `category-${getRandomId()}`; // # Click on the sidebar menu dropdown - cy.findByLabelText('Add Channel Dropdown').click(); + cy.uiGetLHSAddChannelButton().click(); // # Click on create category link cy.findByText('Create New Category').should('be.visible').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts index 69086ce680..82e3b4a086 100644 --- a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts @@ -23,7 +23,7 @@ describe('Category sorting', () => { it('MM-T3916 Create Category character limit', () => { // # Click on the sidebar menu dropdown - cy.findByLabelText('Add Channel Dropdown').click(); + cy.uiGetLHSAddChannelButton().click(); // # Click on create category link cy.findByText('Create New Category').should('be.visible').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts index 30918ebbb3..4822d10432 100644 --- a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts @@ -90,7 +90,7 @@ function createCategoryFromSidebarMenu() { const categoryName = `category-${getRandomId()}`; // # Click on the sidebar menu dropdown - cy.findByLabelText('Add Channel Dropdown').click(); + cy.uiGetLHSAddChannelButton().click(); // # Click on create category link cy.findByText('Create New Category').should('be.visible').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts index 17114e21aa..4aad6c337a 100644 --- a/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts @@ -62,7 +62,7 @@ describe('Channel sidebar', () => { cy.url().should('include', `/${teamName}/channels/town-square`); // # Click the New Channel Dropdown button - cy.get('.AddChannelDropdown_dropdownButton').should('be.visible').click(); + cy.uiGetLHSAddChannelButton().should('be.visible').click(); // # Click the Browse Channels dropdown item cy.get('.AddChannelDropdown .MenuItem:contains(Browse Channels) button').should('be.visible').click(); diff --git a/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts index 0d016ea33d..fcaeb3b38b 100644 --- a/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts @@ -105,7 +105,10 @@ describe('Recent Emoji', () => { cy.uiGetPostTextBox().type('{enter} {enter}').wait(TIMEOUTS.TWO_SEC); // # Hover over the last post by opening dot menu on it - cy.clickPostDotMenu(); + cy.getLastPostId().then((postId) => { + // # Click on post dot menu so we can check for reaction icon + cy.get(`#post_${postId}`).trigger('mouseover'); + }); cy.get('#recent_reaction_0').should('exist').then((recentReaction) => { // * Assert that custom emoji is present as most recent in quick reaction menu @@ -152,7 +155,10 @@ describe('Recent Emoji', () => { cy.reload(); // # Hover over the last post by opening dot menu on it - cy.clickPostDotMenu(); + cy.getLastPostId().then((postId) => { + // # Click on post dot menu so we can check for reaction icon + cy.get(`#post_${postId}`).trigger('mouseover'); + }); cy.get('#recent_reaction_0').should('exist').then((recentReaction) => { // * Assert that instead of custom emoji the system emoji is present as most recent in quick reaction menu diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js index 8626033949..08f25fc8d4 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js @@ -196,7 +196,7 @@ describe('Verify Accessibility Support in different input fields', () => { cy.get('#FormattingControl_ul').should('be.focused').and('have.attr', 'aria-label', 'bulleted list').tab(); // * Verify if the focus is on the numbered list button - cy.get('#FormattingControl_ol').should('be.focused').and('have.attr', 'aria-label', 'numbered list').tab(); + cy.get('#FormattingControl_ol').should('be.focused').and('have.attr', 'aria-label', 'numbered list').tab().tab(); // * Verify if the focus is on the formatting options button cy.get('#toggleFormattingBarButton').should('be.focused').and('have.attr', 'aria-label', 'formatting').tab(); diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts index aa12dae759..396869cd8e 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts @@ -223,4 +223,15 @@ describe('Guest Account - Guest User Invitation Flow', () => { // * Verify invite more button is present cy.findByTestId('invite-more').should('be.visible'); }); + + it('hides the copy link button when inviting guests', () => { + // # Open team menu and click 'Invite People' + cy.uiOpenTeamMenu('Invite People'); + + // # Select Guest + cy.findByTestId('inviteGuestLink').should('be.visible').click(); + + // * The button "Copy invite link" should not exist + cy.findByTestId('InviteView__copyInviteLink').should('not.exist'); + }); }); diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js index fda7dca517..79dbf33ab8 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js @@ -159,7 +159,7 @@ describe('LDAP guest', () => { // # Create team if no membership cy.skipOrCreateTeam(testSettings, getRandomId()).then(() => { // * Verify user is a member - cy.findByRole('button', {name: 'Add Channel Dropdown'}).should('exist'); + cy.uiGetLHSAddChannelButton().should('exist'); // # Demote the user demoteUserToGuest(user2Data); @@ -173,7 +173,7 @@ describe('LDAP guest', () => { cy.uiAddDirectMessage().should('exist'); // * Check the user is a guest - cy.findByRole('button', {name: 'Add Channel Dropdown'}).should('not.exist'); + cy.uiGetLHSAddChannelButton().should('not.exist'); }); }); }); diff --git a/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js index 53e063aef9..33ae5b8c77 100644 --- a/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js +++ b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js @@ -53,7 +53,7 @@ describe('System Scheme', () => { cy.findByTestId('systemScheme-link').should('be.visible').click().wait(TIMEOUTS.HALF_SEC); // # Click on `Reset to defaults` - cy.findByTestId('resetPermissionsToDefault').should('be.visible').click().wait(TIMEOUTS.HALF_SEC); + cy.findByTestId('resetPermissionsToDefault').scrollIntoView().should('be.visible').click().wait(TIMEOUTS.HALF_SEC); // # Confirm the dialog cy.get('#confirmModalButton').click().wait(TIMEOUTS.TWO_SEC); @@ -78,10 +78,10 @@ describe('System Scheme', () => { cy.findByTestId('all_users-private_channel-create_private_channel-checkbox').should('not.have.class', 'checked'); // # Click on `Reset to defaults` - cy.findByTestId('resetPermissionsToDefault').should('be.visible').click().wait(TIMEOUTS.HALF_SEC); + cy.findByTestId('resetPermissionsToDefault').scrollIntoView().should('be.visible').click().wait(TIMEOUTS.HALF_SEC); // # Confirm the dialog - cy.get('#confirmModalButton').click().wait(TIMEOUTS.HALF_SEC); + cy.get('#confirmModalButton').scrollIntoView().click().wait(TIMEOUTS.HALF_SEC); // # Save changes cy.get('#saveSetting').click().wait(TIMEOUTS.TWO_SEC); diff --git a/e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js index 4482bcb782..fbcbea8f4b 100644 --- a/e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js +++ b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js @@ -21,6 +21,7 @@ export function markAsUnreadShouldBeAbsent(postId, prefix = 'post', location = ' within(() => { cy.findByText('Mark as Unread').should('not.exist'); }); + cy.get('body').type('esc'); } export function switchToChannel(channel) { diff --git a/e2e-tests/cypress/tests/support/ui/sidebar_left.ts b/e2e-tests/cypress/tests/support/ui/sidebar_left.ts index 1168b705dd..58ae372f82 100644 --- a/e2e-tests/cypress/tests/support/ui/sidebar_left.ts +++ b/e2e-tests/cypress/tests/support/ui/sidebar_left.ts @@ -32,7 +32,7 @@ Cypress.Commands.add('uiOpenTeamMenu', (item = '') => { Cypress.Commands.add('uiGetLHSAddChannelButton', () => { return cy.uiGetLHS(). - findByRole('button', {name: 'Add Channel Dropdown'}); + find('.AddChannelDropdown_dropdownButton'); }); Cypress.Commands.add('uiGetLHSTeamMenu', () => { @@ -89,7 +89,7 @@ Cypress.Commands.add('uiGetLhsSection', (section) => { }); Cypress.Commands.add('uiBrowseOrCreateChannel', (item) => { - cy.findByRole('button', {name: 'Add Channel Dropdown'}). + cy.get('.AddChannelDropdown_dropdownButton'). should('be.visible'). click(); cy.get('.dropdown-menu').should('be.visible'); diff --git a/e2e-tests/playwright/support/server/default_config.ts b/e2e-tests/playwright/support/server/default_config.ts index 5d6e56f7d5..33d545537b 100644 --- a/e2e-tests/playwright/support/server/default_config.ts +++ b/e2e-tests/playwright/support/server/default_config.ts @@ -697,6 +697,7 @@ const defaultServerConfig: AdminConfig = { ThreadsEverywhere: false, GlobalDrafts: true, OnboardingTourTips: true, + AppsSidebarCategory: false, }, ImportSettings: { Directory: './import', diff --git a/model/config.go b/model/config.go index 6c5306950d..4868229bbf 100644 --- a/model/config.go +++ b/model/config.go @@ -314,7 +314,7 @@ type ServiceSettings struct { RestrictLinkPreviews *string `access:"site_posts"` EnableTesting *bool `access:"environment_developer,write_restrictable,cloud_restrictable"` EnableDeveloper *bool `access:"environment_developer,write_restrictable,cloud_restrictable"` - DeveloperFlags *string `access:"environment_developer"` + DeveloperFlags *string `access:"environment_developer,cloud_restrictable"` EnableClientPerformanceDebugging *bool `access:"environment_developer,write_restrictable,cloud_restrictable"` EnableOpenTracing *bool `access:"write_restrictable,cloud_restrictable"` EnableSecurityFixAlert *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"` diff --git a/model/draft.go b/model/draft.go index a9741e5727..73d1e69f98 100644 --- a/model/draft.go +++ b/model/draft.go @@ -81,9 +81,11 @@ func (o *Draft) GetProps() StringInterface { func (o *Draft) PreSave() { if o.CreateAt == 0 { o.CreateAt = GetMillis() + o.UpdateAt = o.CreateAt + } else { + o.UpdateAt = GetMillis() } - o.UpdateAt = o.CreateAt o.DeleteAt = 0 o.PreCommit() } @@ -100,8 +102,3 @@ func (o *Draft) PreCommit() { // There's a rare bug where the client sends up duplicate FileIds so protect against that o.FileIds = RemoveDuplicateStrings(o.FileIds) } - -func (o *Draft) PreUpdate() { - o.UpdateAt = GetMillis() - o.PreCommit() -} diff --git a/model/draft_test.go b/model/draft_test.go index 2e931c31dd..dec7e56a17 100644 --- a/model/draft_test.go +++ b/model/draft_test.go @@ -65,16 +65,3 @@ func TestDraftPreSave(t *testing.T) { assert.LessOrEqual(t, o.CreateAt, past) } - -func TestDraftPreUpdate(t *testing.T) { - o := Draft{Message: "test"} - o.PreUpdate() - - assert.NotEqual(t, 0, o.UpdateAt) - - past := GetMillis() - 1 - o = Draft{Message: "test", UpdateAt: past} - o.PreSave() - - assert.GreaterOrEqual(t, o.UpdateAt, past) -} diff --git a/model/feature_flags.go b/model/feature_flags.go index 689ff32fd6..792ae834e9 100644 --- a/model/feature_flags.go +++ b/model/feature_flags.go @@ -74,6 +74,8 @@ type FeatureFlags struct { GlobalDrafts bool OnboardingTourTips bool + + AppsSidebarCategory bool } func (f *FeatureFlags) SetDefaults() { @@ -95,13 +97,14 @@ func (f *FeatureFlags) SetDefaults() { f.SendWelcomePost = true f.PostPriority = true f.PeopleProduct = false - f.WorkTemplate = false + f.WorkTemplate = true f.ReduceOnBoardingTaskList = false f.ThreadsEverywhere = false f.GlobalDrafts = true f.WysiwygEditor = false f.OnboardingAutoShowLinkedBoard = false f.OnboardingTourTips = true + f.AppsSidebarCategory = false } func (f *FeatureFlags) Plugins() map[string]string { diff --git a/model/hosted_customer.go b/model/hosted_customer.go index 543ea12b74..608892e5e5 100644 --- a/model/hosted_customer.go +++ b/model/hosted_customer.go @@ -8,6 +8,12 @@ type BootstrapSelfHostedSignupRequest struct { Reset bool `json:"reset"` } +type SubscribeNewsletterRequest struct { + Email string `json:"email"` + ServerID string `json:"server_id"` + SubscribedContent string `json:"subscribed_content"` +} + type BootstrapSelfHostedSignupResponse struct { Progress string `json:"progress"` // email listed on the JWT claim diff --git a/server/boards/api/files.go b/server/boards/api/files.go index 344933fc5d..4a7eb5e6e7 100644 --- a/server/boards/api/files.go +++ b/server/boards/api/files.go @@ -145,6 +145,12 @@ func (a *API) handleServeFile(w http.ResponseWriter, r *http.Request) { _ = a.app.MoveFile(board.ChannelID, board.TeamID, boardID, filename) } + if err != nil { + // if err is still not nil then it is an error other than `not found` so we must + // return the error to the requestor. fileReader and Fileinfo are nil in this case. + a.errorResponse(w, r, err) + } + defer fileReader.Close() mimeType := "" diff --git a/server/channels/api4/drafts.go b/server/channels/api4/drafts.go index 2b11bf258a..bfd1112f94 100644 --- a/server/channels/api4/drafts.go +++ b/server/channels/api4/drafts.go @@ -62,7 +62,7 @@ func upsertDraft(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(dt); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -94,7 +94,7 @@ func getDrafts(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(drafts); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/server/channels/api4/hosted_customer.go b/server/channels/api4/hosted_customer.go index bbed311ea4..ba791c28cc 100644 --- a/server/channels/api4/hosted_customer.go +++ b/server/channels/api4/hosted_customer.go @@ -36,6 +36,8 @@ func (api *API) InitHostedCustomer() { api.BaseRoutes.HostedCustomer.Handle("/invoices", api.APISessionRequired(selfHostedInvoices)).Methods("GET") // GET /api/v4/hosted_customer/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf api.BaseRoutes.HostedCustomer.Handle("/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf", api.APISessionRequired(selfHostedInvoicePDF)).Methods("GET") + + api.BaseRoutes.HostedCustomer.Handle("/subscribe-newsletter", api.APIHandler(handleSubscribeToNewsletter)).Methods(http.MethodPost) } func ensureSelfHostedAdmin(c *Context, where string) { @@ -293,3 +295,33 @@ func selfHostedInvoicePDF(c *Context, w http.ResponseWriter, r *http.Request) { r, ) } + +func handleSubscribeToNewsletter(c *Context, w http.ResponseWriter, r *http.Request) { + const where = "Api4.handleSubscribeToNewsletter" + ensured := ensureCloudInterface(c, where) + if !ensured { + return + } + + bodyBytes, err := io.ReadAll(r.Body) + if err != nil { + c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err) + return + } + + req := new(model.SubscribeNewsletterRequest) + err = json.Unmarshal(bodyBytes, req) + if err != nil { + c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err) + return + } + + req.ServerID = c.App.Srv().TelemetryId() + + if err := c.App.Cloud().SubscribeToNewsletter("", req); err != nil { + c.Err = model.NewAppError(where, "api.server.cws.subscribe_to_newsletter.app_error", nil, "CWS Server failed to subscribe to newsletter.", http.StatusInternalServerError).Wrap(err) + return + } + + ReturnStatusOK(w) +} diff --git a/server/channels/api4/user.go b/server/channels/api4/user.go index ba2ab6e336..11d4a71e0f 100644 --- a/server/channels/api4/user.go +++ b/server/channels/api4/user.go @@ -2372,10 +2372,14 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { audit.AddEventParameter(auditRec, "user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) - if user, err := c.App.GetUser(c.Params.UserId); err == nil { - audit.AddEventParameterAuditable(auditRec, "user", user) + user, err := c.App.GetUser(c.Params.UserId) + if err != nil { + c.Err = err + return } + audit.AddEventParameterAuditable(auditRec, "user", user) + if c.AppContext.Session().IsOAuth { c.SetPermissionError(model.PermissionCreateUserAccessToken) c.Err.DetailedError += ", attempted access by oauth app" @@ -2405,6 +2409,11 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { return } + if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { + c.SetPermissionError(model.PermissionManageSystem) + return + } + accessToken.UserId = c.Params.UserId accessToken.Token = "" diff --git a/server/channels/api4/user_test.go b/server/channels/api4/user_test.go index 893d7f6aca..b6dde5e2a1 100644 --- a/server/channels/api4/user_test.go +++ b/server/channels/api4/user_test.go @@ -4339,7 +4339,38 @@ func TestCreateUserAccessToken(t *testing.T) { CheckForbiddenStatus(t, resp) }) - t.Run("create user access token for basic user as as system admin", func(t *testing.T) { + t.Run("create user access token for another user, with permission", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) + th.AddPermissionToRole(model.PermissionEditOtherUsers.Id, model.SystemUserManagerRoleId) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserManagerRoleId+" "+model.SystemUserAccessTokenRoleId, false) + + rtoken, _, err := th.Client.CreateUserAccessToken(th.BasicUser2.Id, "test token") + require.NoError(t, err) + assert.Equal(t, th.BasicUser2.Id, rtoken.UserId) + + oldSessionToken := th.Client.AuthToken + defer func() { th.Client.AuthToken = oldSessionToken }() + + assertToken(t, th, rtoken, th.BasicUser2.Id) + }) + + t.Run("create user access token for system admin, as system user manager", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) + th.AddPermissionToRole(model.PermissionEditOtherUsers.Id, model.SystemUserManagerRoleId) + th.App.UpdateUserRoles(th.Context, th.BasicUser.Id, model.SystemUserManagerRoleId+" "+model.SystemUserAccessTokenRoleId, false) + + _, resp, err := th.Client.CreateUserAccessToken(th.SystemAdminUser.Id, "test token") + require.Error(t, err) + CheckForbiddenStatus(t, resp) + }) + + t.Run("create user access token for basic user as a system admin", func(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() diff --git a/server/channels/api4/work_templates.go b/server/channels/api4/work_templates.go index a2d26e7b0e..2f6836682e 100644 --- a/server/channels/api4/work_templates.go +++ b/server/channels/api4/work_templates.go @@ -22,23 +22,6 @@ func areWorkTemplatesEnabled(c *Context) *model.AppError { return model.NewAppError("areWorkTemplatesEnabled", "api.work_templates.disabled", nil, "feature flag is off", http.StatusNotFound) } - // we have to make sure that playbooks plugin is enabled and board is a product - pbActive, err := c.App.IsPluginActive(model.PluginIdPlaybooks) - if err != nil { - return model.NewAppError("areWorkTemplatesEnabled", "api.work_templates.disabled", nil, "", http.StatusInternalServerError).Wrap(err) - } - if !pbActive { - return model.NewAppError("areWorkTemplatesEnabled", "api.work_templates.disabled", nil, "playbook plugin not active", http.StatusNotFound) - } - - hasBoard, err := c.App.HasBoardProduct() - if err != nil { - return model.NewAppError("areWorkTemplatesEnabled", "api.work_templates.disabled", nil, "", http.StatusInternalServerError).Wrap(err) - } - if !hasBoard { - return model.NewAppError("areWorkTemplatesEnabled", "api.work_templates.disabled", nil, "board product not found", http.StatusNotFound) - } - return nil } diff --git a/server/channels/app/app_iface.go b/server/channels/app/app_iface.go index cf749c3fc9..eb30bc0779 100644 --- a/server/channels/app/app_iface.go +++ b/server/channels/app/app_iface.go @@ -482,7 +482,6 @@ type AppIface interface { CreateChannelWithUser(c request.CTX, channel *model.Channel, userID string) (*model.Channel, *model.AppError) CreateCommand(cmd *model.Command) (*model.Command, *model.AppError) CreateCommandWebhook(commandID string, args *model.CommandArgs) (*model.CommandWebhook, *model.AppError) - CreateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) CreateEmoji(c request.CTX, sessionUserId string, emoji *model.Emoji, multiPartImageData *multipart.Form) (*model.Emoji, *model.AppError) CreateGroup(group *model.Group) (*model.Group, *model.AppError) CreateGroupChannel(c request.CTX, userIDs []string, creatorId string) (*model.Channel, *model.AppError) @@ -1121,7 +1120,6 @@ type AppIface interface { UpdateChannelPrivacy(c request.CTX, oldChannel *model.Channel, user *model.User) (*model.Channel, *model.AppError) UpdateCommand(oldCmd, updatedCmd *model.Command) (*model.Command, *model.AppError) UpdateConfig(f func(*model.Config)) - UpdateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) UpdateEphemeralPost(c request.CTX, userID string, post *model.Post) *model.Post UpdateExpiredDNDStatuses() ([]*model.Status, error) UpdateGroup(group *model.Group) (*model.Group, *model.AppError) diff --git a/server/channels/app/draft.go b/server/channels/app/draft.go index 3521adea71..a8ca1ef9d2 100644 --- a/server/channels/app/draft.go +++ b/server/channels/app/draft.go @@ -35,33 +35,6 @@ func (a *App) GetDraft(userID, channelID, rootID string) (*model.Draft, *model.A } func (a *App) UpsertDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) { - if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts { - return nil, model.NewAppError("UpsertDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented) - } - - dt, dErr := a.Srv().Store().Draft().Get(draft.UserId, draft.ChannelId, draft.RootId, true) - var notFoundErr *store.ErrNotFound - if dErr != nil && !errors.As(dErr, ¬FoundErr) { - return nil, model.NewAppError("UpsertDraft", "app.select_error", nil, dErr.Error(), http.StatusInternalServerError) - } - - var err *model.AppError - if dt == nil { - dt, err = a.CreateDraft(c, draft, connectionID) - if err != nil { - return nil, err - } - } else { - dt, err = a.UpdateDraft(c, draft, connectionID) - if err != nil { - return nil, err - } - } - - return dt, nil -} - -func (a *App) CreateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) { if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts { return nil, model.NewAppError("CreateDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented) } @@ -83,7 +56,7 @@ func (a *App) CreateDraft(c *request.Context, draft *model.Draft, connectionID s return nil, model.NewAppError("CreateDraft", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) } - dt, nErr := a.Srv().Store().Draft().Save(draft) + dt, nErr := a.Srv().Store().Draft().Upsert(draft) if nErr != nil { return nil, model.NewAppError("CreateDraft", "app.draft.save.app_error", nil, nErr.Error(), http.StatusInternalServerError) } @@ -101,46 +74,6 @@ func (a *App) CreateDraft(c *request.Context, draft *model.Draft, connectionID s return dt, nil } -func (a *App) UpdateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) { - if !a.Config().FeatureFlags.GlobalDrafts { - return nil, model.NewAppError("UpsertDraft", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented) - } - - // Check that channel exists and has not been deleted - channel, errCh := a.Srv().Store().Channel().Get(draft.ChannelId, true) - if errCh != nil { - err := model.NewAppError("UpdateDraft", "api.context.invalid_param.app_error", map[string]interface{}{"Name": "draft.channel_id"}, errCh.Error(), http.StatusBadRequest) - return nil, err - } - - if channel.DeleteAt != 0 { - err := model.NewAppError("UpdateDraft", "api.draft.create_draft.can_not_draft_to_deleted.error", nil, "", http.StatusBadRequest) - return nil, err - } - - _, nErr := a.Srv().Store().User().Get(context.Background(), draft.UserId) - if nErr != nil { - return nil, model.NewAppError("UpdateDraft", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) - } - - dt, nErr := a.Srv().Store().Draft().Update(draft) - if nErr != nil { - return nil, model.NewAppError("UpdateDraft", "app.draft.update.app_error", nil, nErr.Error(), http.StatusInternalServerError) - } - - dt = a.prepareDraftWithFileInfos(draft.UserId, dt) - - message := model.NewWebSocketEvent(model.WebsocketEventDraftUpdated, "", draft.ChannelId, draft.UserId, nil, connectionID) - draftJSON, jsonErr := json.Marshal(dt) - if jsonErr != nil { - mlog.Warn("Failed to encode draft to JSON", mlog.Err(jsonErr)) - } - message.Add("draft", string(draftJSON)) - a.Publish(message) - - return dt, nil -} - func (a *App) GetDraftsForUser(userID, teamID string) ([]*model.Draft, *model.AppError) { if !a.Config().FeatureFlags.GlobalDrafts || !*a.Config().ServiceSettings.AllowSyncedDrafts { return nil, model.NewAppError("GetDraftsForUser", "app.draft.feature_disabled", nil, "", http.StatusNotImplemented) diff --git a/server/channels/app/draft_test.go b/server/channels/app/draft_test.go index 287ce82430..4b52efd8e9 100644 --- a/server/channels/app/draft_test.go +++ b/server/channels/app/draft_test.go @@ -81,34 +81,41 @@ func TestUpsertDraft(t *testing.T) { user := th.BasicUser channel := th.BasicChannel - draft1 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00001, + draft := &model.Draft{ UserId: user.Id, ChannelId: channel.Id, - Message: "draft1", + Message: "draft", } - draft2 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00002, - UserId: user.Id, - ChannelId: channel.Id, - Message: "draft2", - } - - _, createDraftErr := th.App.CreateDraft(th.Context, draft1, "") - assert.Nil(t, createDraftErr) - t.Run("upsert draft", func(t *testing.T) { - draftResp, err := th.App.UpsertDraft(th.Context, draft2, "") + _, err := th.App.UpsertDraft(th.Context, draft, "") assert.Nil(t, err) - assert.Equal(t, draft2.Message, draftResp.Message) - assert.Equal(t, draft2.ChannelId, draftResp.ChannelId) - assert.Equal(t, draft2.CreateAt, draftResp.CreateAt) + drafts, err := th.App.GetDraftsForUser(user.Id, th.BasicTeam.Id) + assert.Nil(t, err) + assert.Len(t, drafts, 1) + draft1 := drafts[0] - assert.NotEqual(t, draft1.UpdateAt, draftResp.UpdateAt) + assert.Equal(t, "draft", draft1.Message) + assert.Equal(t, channel.Id, draft1.ChannelId) + assert.Greater(t, draft1.CreateAt, int64(0)) + + draft = &model.Draft{ + UserId: user.Id, + ChannelId: channel.Id, + Message: "updated draft", + } + _, err = th.App.UpsertDraft(th.Context, draft, "") + assert.Nil(t, err) + + drafts, err = th.App.GetDraftsForUser(user.Id, th.BasicTeam.Id) + assert.Nil(t, err) + assert.Len(t, drafts, 1) + draft2 := drafts[0] + + assert.Equal(t, "updated draft", draft2.Message) + assert.Equal(t, channel.Id, draft2.ChannelId) + assert.Equal(t, draft1.CreateAt, draft2.CreateAt) }) t.Run("upsert draft feature flag", func(t *testing.T) { @@ -123,7 +130,7 @@ func TestUpsertDraft(t *testing.T) { defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true }) defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true }) - _, err := th.App.UpsertDraft(th.Context, draft1, "") + _, err := th.App.UpsertDraft(th.Context, draft, "") assert.NotNil(t, err) }) } @@ -160,7 +167,7 @@ func TestCreateDraft(t *testing.T) { } t.Run("create draft", func(t *testing.T) { - draftResp, err := th.App.CreateDraft(th.Context, draft1, "") + draftResp, err := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, err) assert.Equal(t, draft1.Message, draftResp.Message) @@ -178,29 +185,13 @@ func TestCreateDraft(t *testing.T) { draftWithFiles := draft2 draftWithFiles.FileIds = []string{fileResp.Id} - draftResp, err := th.App.CreateDraft(th.Context, draftWithFiles, "") + draftResp, err := th.App.UpsertDraft(th.Context, draftWithFiles, "") assert.Nil(t, err) assert.Equal(t, draftWithFiles.Message, draftResp.Message) assert.Equal(t, draftWithFiles.ChannelId, draftResp.ChannelId) assert.ElementsMatch(t, draftWithFiles.FileIds, draftResp.FileIds) }) - - t.Run("create draft feature flag", func(t *testing.T) { - os.Setenv("MM_FEATUREFLAGS_GLOBALDRAFTS", "false") - defer os.Unsetenv("MM_FEATUREFLAGS_GLOBALDRAFTS") - os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false") - defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS") - - th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false }) - - defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true }) - defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true }) - - _, err := th.App.CreateDraft(th.Context, draft1, "") - assert.NotNil(t, err) - }) } func TestUpdateDraft(t *testing.T) { @@ -217,34 +208,14 @@ func TestUpdateDraft(t *testing.T) { channel := th.BasicChannel draft1 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00001, UserId: user.Id, ChannelId: channel.Id, Message: "draft1", } - draft2 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00002, - UserId: user.Id, - ChannelId: channel.Id, - Message: "draft2", - } - - _, createDraftErr := th.App.CreateDraft(th.Context, draft1, "") + _, createDraftErr := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, createDraftErr) - t.Run("update draft", func(t *testing.T) { - draftResp, err := th.App.UpdateDraft(th.Context, draft2, "") - assert.Nil(t, err) - - assert.Equal(t, draft2.Message, draftResp.Message) - assert.Equal(t, draft2.ChannelId, draftResp.ChannelId) - - assert.NotEqual(t, draft1.UpdateAt, draftResp.UpdateAt) - }) - t.Run("update draft with files", func(t *testing.T) { // upload file sent, readFileErr := testutils.ReadTestFile("test.png") @@ -256,29 +227,17 @@ func TestUpdateDraft(t *testing.T) { draftWithFiles := draft1 draftWithFiles.FileIds = []string{fileResp.Id} - draftResp, err := th.App.UpdateDraft(th.Context, draft1, "") + _, err := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, err) + drafts, err := th.App.GetDraftsForUser(user.Id, th.BasicTeam.Id) + assert.Nil(t, err) + + draftResp := drafts[0] assert.Equal(t, draftWithFiles.Message, draftResp.Message) assert.Equal(t, draftWithFiles.ChannelId, draftResp.ChannelId) assert.ElementsMatch(t, draftWithFiles.FileIds, draftResp.FileIds) }) - - t.Run("create draft feature flag", func(t *testing.T) { - os.Setenv("MM_FEATUREFLAGS_GLOBALDRAFTS", "false") - defer os.Unsetenv("MM_FEATUREFLAGS_GLOBALDRAFTS") - os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false") - defer os.Unsetenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS") - - th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = false }) - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = false }) - - defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.FeatureFlags.GlobalDrafts = true }) - defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowSyncedDrafts = true }) - - _, err := th.App.UpdateDraft(th.Context, draft1, "") - assert.NotNil(t, err) - }) } func TestGetDraftsForUser(t *testing.T) { @@ -312,10 +271,10 @@ func TestGetDraftsForUser(t *testing.T) { Message: "draft2", } - _, createDraftErr1 := th.App.CreateDraft(th.Context, draft1, "") + _, createDraftErr1 := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, createDraftErr1) - _, createDraftErr2 := th.App.CreateDraft(th.Context, draft2, "") + _, createDraftErr2 := th.App.UpsertDraft(th.Context, draft2, "") assert.Nil(t, createDraftErr2) t.Run("get drafts", func(t *testing.T) { @@ -340,7 +299,7 @@ func TestGetDraftsForUser(t *testing.T) { draftWithFiles := draft1 draftWithFiles.FileIds = []string{fileResp.Id} - draftResp, updateDraftErr := th.App.UpdateDraft(th.Context, draft1, "") + draftResp, updateDraftErr := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, updateDraftErr) assert.Equal(t, draftWithFiles.Message, draftResp.Message) @@ -397,7 +356,7 @@ func TestDeleteDraft(t *testing.T) { Message: "draft1", } - _, createDraftErr := th.App.CreateDraft(th.Context, draft1, "") + _, createDraftErr := th.App.UpsertDraft(th.Context, draft1, "") assert.Nil(t, createDraftErr) t.Run("delete draft", func(t *testing.T) { @@ -411,7 +370,7 @@ func TestDeleteDraft(t *testing.T) { assert.Equal(t, draft1.ChannelId, draftResp.ChannelId) }) - t.Run("get drafts feature flag", func(t *testing.T) { + t.Run("delete drafts feature flag", func(t *testing.T) { os.Setenv("MM_FEATUREFLAGS_GLOBALDRAFTS", "false") defer os.Unsetenv("MM_FEATUREFLAGS_GLOBALDRAFTS") os.Setenv("MM_SERVICESETTINGS_ALLOWSYNCEDDRAFTS", "false") diff --git a/server/channels/app/opentracing/opentracing_layer.go b/server/channels/app/opentracing/opentracing_layer.go index 4a4cd72441..6e522bb971 100644 --- a/server/channels/app/opentracing/opentracing_layer.go +++ b/server/channels/app/opentracing/opentracing_layer.go @@ -2026,28 +2026,6 @@ func (a *OpenTracingAppLayer) CreateDefaultMemberships(c *request.Context, param return resultVar0 } -func (a *OpenTracingAppLayer) CreateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) { - origCtx := a.ctx - span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateDraft") - - a.ctx = newCtx - a.app.Srv().Store().SetContext(newCtx) - defer func() { - a.app.Srv().Store().SetContext(origCtx) - a.ctx = origCtx - }() - - defer span.Finish() - resultVar0, resultVar1 := a.app.CreateDraft(c, draft, connectionID) - - if resultVar1 != nil { - span.LogFields(spanlog.Error(resultVar1)) - ext.Error.Set(span, true) - } - - return resultVar0, resultVar1 -} - func (a *OpenTracingAppLayer) CreateEmoji(c request.CTX, sessionUserId string, emoji *model.Emoji, multiPartImageData *multipart.Form) (*model.Emoji, *model.AppError) { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CreateEmoji") @@ -17381,28 +17359,6 @@ func (a *OpenTracingAppLayer) UpdateDNDStatusOfUsers() { a.app.UpdateDNDStatusOfUsers() } -func (a *OpenTracingAppLayer) UpdateDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError) { - origCtx := a.ctx - span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateDraft") - - a.ctx = newCtx - a.app.Srv().Store().SetContext(newCtx) - defer func() { - a.app.Srv().Store().SetContext(origCtx) - a.ctx = origCtx - }() - - defer span.Finish() - resultVar0, resultVar1 := a.app.UpdateDraft(c, draft, connectionID) - - if resultVar1 != nil { - span.LogFields(spanlog.Error(resultVar1)) - ext.Error.Set(span, true) - } - - return resultVar0, resultVar1 -} - func (a *OpenTracingAppLayer) UpdateEphemeralPost(c request.CTX, userID string, post *model.Post) *model.Post { origCtx := a.ctx span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UpdateEphemeralPost") diff --git a/server/channels/app/slashcommands/command_loadtest.go b/server/channels/app/slashcommands/command_loadtest.go index cd7ab9f217..a0b02267b4 100644 --- a/server/channels/app/slashcommands/command_loadtest.go +++ b/server/channels/app/slashcommands/command_loadtest.go @@ -629,7 +629,7 @@ func (*LoadTestProvider) URLCommand(a *app.App, c request.CTX, args *model.Comma // provide a shortcut to easily access tests stored in doc/developer/tests if !strings.HasPrefix(url, "http") { - url = "https://raw.githubusercontent.com/mattermost/mattermost-server/master/tests/" + url + url = "https://raw.githubusercontent.com/mattermost/mattermost-server/master/server/tests/" + url if path.Ext(url) == "" { url += ".md" @@ -683,7 +683,7 @@ func (*LoadTestProvider) JsonCommand(a *app.App, c request.CTX, args *model.Comm // provide a shortcut to easily access tests stored in doc/developer/tests if !strings.HasPrefix(url, "http") { - url = "https://raw.githubusercontent.com/mattermost/mattermost-server/master/tests/" + url + url = "https://raw.githubusercontent.com/mattermost/mattermost-server/master/server/tests/" + url if path.Ext(url) == "" { url += ".json" diff --git a/server/channels/app/worktemplates/templates.yaml b/server/channels/app/worktemplates/templates.yaml index 008c16c0e2..d935f9308c 100644 --- a/server/channels/app/worktemplates/templates.yaml +++ b/server/channels/app/worktemplates/templates.yaml @@ -9,16 +9,16 @@ visibility: public description: channel: id: "worktemplate.product_teams.feature_release.description.channel" - defaultMessage: "Chat with your team in a Feature Release channel that connects easily with your boards, playbooks and app bots." + defaultMessage: "Chat with your team about any release blockers and changes in a channel that connects easily with your boards, playbooks and other integrations." board: id: "worktemplate.product_teams.feature_release.description.board" - defaultMessage: "Use our Meeting Agenda board template for recurring meetings like standup and our Project Tasks board to manage the progress of tasks along the way." + defaultMessage: "Keep meetings on track with the Meeting Agenda board. Manage your workload with the Project Tasks board." playbook: id: "worktemplate.product_teams.feature_release.description.playbook" - defaultMessage: "Create transparent workflows across development teams to ensure your feature development process is seamless." + defaultMessage: "Boost cross-functional team collaboration with task checklists and automation that support your feature development process. When you’re done, run a retrospective and make improvements for your next release." integration: id: "worktemplate.product_teams.feature_release.description.integration" - defaultMessage: "Increase productivity in your channel by integrating a Jira bot and Github bot. These will be downloaded for you." + defaultMessage: "Increase productivity in your channel by integrating your most commonly used tools to support your feature release, such as GitHub. These will be downloaded for you." illustration: "/static/worktemplates/integrations.png" content: - channel: @@ -42,7 +42,7 @@ content: template: "Product Release" name: "Feature release" id: product-release-playbook - illustration: "/static/worktemplates/playbooks/product_release.png" + illustration: "/static/worktemplates/product_teams/feature_release/playbook.png" - integration: id: jira - integration: @@ -57,21 +57,15 @@ description: channel: id: worktemplate.product_teams.goals_and_okrs.channel defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel. board: id: worktemplate.product_teams.goals_and_okrs.board defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. integration: id: worktemplate.product_teams.goals_and_okrs.integration defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - channel: @@ -103,23 +97,15 @@ description: channel: id: worktemplate.product_teams.bug_bash.channel defaultMessage: >- - Get organized and bash all the bugs with this project! Build momentum and - measure progress using included Playbook, Board, and Channel. - board: - id: worktemplate.product_teams.bug_bash.board - defaultMessage: >- - Get organized and bash all the bugs with this project! Build momentum and - measure progress using included Playbook, Board, and Channel. + Plan and manage bug reports and resolutions in a single channel, that’s easily accessible to your team and organization. playbook: id: worktemplate.product_teams.bug_bash.playbook defaultMessage: >- - Get organized and bash all the bugs with this project! Build momentum and - measure progress using included Playbook, Board, and Channel. + Use checklists to assign testing areas and automated tasks to run a comprehensive bug bash process. Use a retrospective to review your process and improve it for next time. integration: id: worktemplate.product_teams.bug_bash.integration defaultMessage: >- - Get organized and bash all the bugs with this project! Build momentum and - measure progress using included Playbook, Board, and Channel. + Increase productivity in your channel by integrating your most commonly used tools, such as Jira, to track your bug bash progress. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - playbook: @@ -144,24 +130,15 @@ description: channel: id: worktemplate.product_teams.sprint_planning.channel defaultMessage: >- - Use a Project to make sprint planning a breeze. The channel keeps the - conversation and questions focused. The sprint plan keeps everyone on task - for the week and the Retrospective board brings the team together to - continuously improve. + Chat with your team in a channel that connects easily with your boards and integrations. board: id: worktemplate.product_teams.sprint_planning.board defaultMessage: >- - Use a Project to make sprint planning a breeze. The channel keeps the - conversation and questions focused. The sprint plan keeps everyone on task - for the week and the Retrospective board brings the team together to - continuously improve. + Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments. integration: id: worktemplate.product_teams.sprint_planning.integration defaultMessage: >- - Use a Project to make sprint planning a breeze. The channel keeps the - conversation and questions focused. The sprint plan keeps everyone on task - for the week and the Retrospective board brings the team together to - continuously improve. + Increase productivity in your channel by integrating your most commonly used tools, such as Zoom. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - channel: @@ -185,10 +162,10 @@ visibility: public description: channel: id: worktemplate.product_teams.product_roadmap.channel - defaultMessage: Description of why the channel(s) are needed + defaultMessage: Chat with your team about your customers' feedback, prioritization, and get aligned on progress together. board: id: worktemplate.product_teams.product_roadmap.board - defaultMessage: Description of why the board(s) are needed + defaultMessage: Use the Product Roadmap board to manage user feedback, assign resources, view deliverables in a calendar view, and prioritize issues. content: - channel: id: channel-1674851139450 @@ -212,13 +189,13 @@ visibility: public description: channel: id: "worktemplate.devops.incident_resolution.description.channel" - defaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + defaultMessage: "Chat with your team about priorities, add stakeholders, provide updates, and work toward a resolution in a single channel." board: id: "worktemplate.devops.incident_resolution.description.board" - defaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + defaultMessage: "Use the Incident Resolution board to support repeatable processes and assign defined tasks across the team." playbook: id: "worktemplate.devops.incident_resolution.description.playbook" - defaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + defaultMessage: "Use checklists and automation to bring in key team members, and share how your incident is tracking toward resolution." content: - playbook: id: irpb @@ -245,30 +222,30 @@ visibility: public description: channel: id: worktemplate.devops.product_release.channel - defaultMessage: Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page. + defaultMessage: Chat with your team about daily milestones, any blockers, and changes to deliverables, easily and quickly. board: id: worktemplate.devops.product_release.board - defaultMessage: Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page. + defaultMessage: Use the Product Release board to support your release timeframe and process, ensuring everyone knows which tasks are due. playbook: id: worktemplate.devops.product_release.playbook - defaultMessage: Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page. + defaultMessage: Create repeatable workflows that are easy to follow and implement so product releases are reliable and on time. content: - playbook: id: playbook-1674851385983 template: Product Release name: Product Release illustration: /static/worktemplates/playbooks/product_release.png - - channel: - id: channel-1674851385983 - illustration: /static/worktemplates/devops/product_release/channel.png - name: Product Release - playbook: playbook-1674851385983 - board: id: board-1674851386432 template: a4ec399ab4f2088b1051c3cdf1dde4c3 name: Product Release illustration: /static/worktemplates/boards/project_tasks.png channel: channel-1674851385983 + - channel: + id: channel-1674851385983 + illustration: /static/worktemplates/devops/product_release/channel.png + name: Product Release + playbook: playbook-1674851385983 --- ###################### # COMPANY WIDE @@ -282,21 +259,15 @@ description: channel: id: worktemplate.companywide.goals_and_okrs.channel defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel. board: id: worktemplate.companywide.goals_and_okrs.board defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. integration: id: worktemplate.companywide.goals_and_okrs.integration defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - channel: @@ -315,24 +286,21 @@ content: id: 'companywide/create_project:v1' category: companywide useCase: Create a project -illustration: /static/worktemplates/companywide/create_project/create_project.svg +illustration: /static/worktemplates/companywide/create_project/create_project.png visibility: public description: channel: id: worktemplate.companywide.create_project.channel defaultMessage: >- - Plan a Roadmap using this Project Board and collaborate on topic in the - channel created with this template. + Chat with your team about your new project and decide how you’re going to structure it, in a collaborative channel. board: id: worktemplate.companywide.create_project.board defaultMessage: >- - Plan a Roadmap using this Project Board and collaborate on topic in the - channel created with this template. + Use a Kanban board to define and track your project tasks and progress. integration: id: worktemplate.companywide.create_project.integration defaultMessage: >- - Plan a Roadmap using this Project Board and collaborate on topic in the - channel created with this template. + Increase productivity in your channel by integrating your most commonly used tools. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - channel: @@ -365,21 +333,15 @@ description: channel: id: worktemplate.leadership.goals_and_okrs.channel defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel. board: id: worktemplate.leadership.goals_and_okrs.board defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. integration: id: worktemplate.leadership.goals_and_okrs.integration defaultMessage: >- - Clear focus is essential to team success and with this Project you can - document the team’s goals and OKR’s as well as post updates in the - dedicated channel. + Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you. illustration: /static/worktemplates/integrations.png content: - channel: diff --git a/server/channels/app/worktemplates/worktemplate_generated.go b/server/channels/app/worktemplates/worktemplate_generated.go index 4e99e0dd1e..95e77edee5 100644 --- a/server/channels/app/worktemplates/worktemplate_generated.go +++ b/server/channels/app/worktemplates/worktemplate_generated.go @@ -37,7 +37,6 @@ func init() { _ = T("worktemplate.product_teams.goals_and_okrs.board") _ = T("worktemplate.product_teams.goals_and_okrs.integration") _ = T("worktemplate.product_teams.bug_bash.channel") - _ = T("worktemplate.product_teams.bug_bash.board") _ = T("worktemplate.product_teams.bug_bash.playbook") _ = T("worktemplate.product_teams.bug_bash.integration") _ = T("worktemplate.product_teams.sprint_planning.channel") @@ -92,22 +91,22 @@ var wt00a1b44a5831c0a3acb14787b3fdd352 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.product_teams.feature_release.description.channel", - DefaultMessage: "Chat with your team in a Feature Release channel that connects easily with your boards, playbooks and app bots.", + DefaultMessage: "Chat with your team about any release blockers and changes in a channel that connects easily with your boards, playbooks and other integrations.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.product_teams.feature_release.description.board", - DefaultMessage: "Use our Meeting Agenda board template for recurring meetings like standup and our Project Tasks board to manage the progress of tasks along the way.", + DefaultMessage: "Keep meetings on track with the Meeting Agenda board. Manage your workload with the Project Tasks board.", Illustration: "", }, Playbook: &TranslatableString{ ID: "worktemplate.product_teams.feature_release.description.playbook", - DefaultMessage: "Create transparent workflows across development teams to ensure your feature development process is seamless.", + DefaultMessage: "Boost cross-functional team collaboration with task checklists and automation that support your feature development process. When you’re done, run a retrospective and make improvements for your next release.", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.product_teams.feature_release.description.integration", - DefaultMessage: "Increase productivity in your channel by integrating a Jira bot and Github bot. These will be downloaded for you.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools to support your feature release, such as GitHub. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -144,7 +143,7 @@ var wt00a1b44a5831c0a3acb14787b3fdd352 = &WorkTemplate{ Template: "Product Release", Name: "Feature release", ID: "product-release-playbook", - Illustration: "/static/worktemplates/playbooks/product_release.png", + Illustration: "/static/worktemplates/product_teams/feature_release/playbook.png", }, }, { @@ -170,18 +169,18 @@ var wt5baa68055bf9ea423273662e01ccc575 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.product_teams.goals_and_okrs.channel", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.product_teams.goals_and_okrs.board", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.product_teams.goals_and_okrs.integration", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -231,22 +230,18 @@ var wtfeb56bc6a8f277c47b503bd1c92d830e = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.product_teams.bug_bash.channel", - DefaultMessage: "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel.", - Illustration: "", - }, - Board: &TranslatableString{ - ID: "worktemplate.product_teams.bug_bash.board", - DefaultMessage: "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel.", + DefaultMessage: "Plan and manage bug reports and resolutions in a single channel, that’s easily accessible to your team and organization.", Illustration: "", }, + Playbook: &TranslatableString{ ID: "worktemplate.product_teams.bug_bash.playbook", - DefaultMessage: "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel.", + DefaultMessage: "Use checklists to assign testing areas and automated tasks to run a comprehensive bug bash process. Use a retrospective to review your process and improve it for next time.", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.product_teams.bug_bash.integration", - DefaultMessage: "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools, such as Jira, to track your bug bash progress. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -286,18 +281,18 @@ var wt8d2ef53deac5517eb349dc5de6150196 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.product_teams.sprint_planning.channel", - DefaultMessage: "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve.", + DefaultMessage: "Chat with your team in a channel that connects easily with your boards and integrations.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.product_teams.sprint_planning.board", - DefaultMessage: "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve.", + DefaultMessage: "Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments. ", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.product_teams.sprint_planning.integration", - DefaultMessage: "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -338,12 +333,12 @@ var wt00ab91a945627f4a624957dd80490bb2 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.product_teams.product_roadmap.channel", - DefaultMessage: "Description of why the channel(s) are needed", + DefaultMessage: "Chat with your team about your customers' feedback, prioritization, and get aligned on progress together.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.product_teams.product_roadmap.board", - DefaultMessage: "Description of why the board(s) are needed", + DefaultMessage: "Use the Product Roadmap board to manage user feedback, assign resources, view deliverables in a calendar view, and prioritize issues.", Illustration: "", }, }, @@ -379,17 +374,17 @@ var wtce19b9352a59d6a5d26f292d83e84377 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.devops.incident_resolution.description.channel", - DefaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way.", + DefaultMessage: "Chat with your team about priorities, add stakeholders, provide updates, and work toward a resolution in a single channel.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.devops.incident_resolution.description.board", - DefaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way.", + DefaultMessage: "Use the Incident Resolution board to support repeatable processes and assign defined tasks across the team.", Illustration: "", }, Playbook: &TranslatableString{ ID: "worktemplate.devops.incident_resolution.description.playbook", - DefaultMessage: "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way.", + DefaultMessage: "Use checklists and automation to bring in key team members, and share how your incident is tracking toward resolution.", Illustration: "", }, }, @@ -433,17 +428,17 @@ var wt37406285a41c18bcdeb881189f7acde0 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.devops.product_release.channel", - DefaultMessage: "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page.", + DefaultMessage: "Chat with your team about daily milestones, any blockers, and changes to deliverables, easily and quickly.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.devops.product_release.board", - DefaultMessage: "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page.", + DefaultMessage: "Use the Product Release board to support your release timeframe and process, ensuring everyone knows which tasks are due.", Illustration: "", }, Playbook: &TranslatableString{ ID: "worktemplate.devops.product_release.playbook", - DefaultMessage: "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page.", + DefaultMessage: "Create repeatable workflows that are easy to follow and implement so product releases are reliable and on time.", Illustration: "", }, }, @@ -456,15 +451,6 @@ var wt37406285a41c18bcdeb881189f7acde0 = &WorkTemplate{ Illustration: "/static/worktemplates/playbooks/product_release.png", }, }, - { - Channel: &Channel{ - ID: "channel-1674851385983", - Name: "Product Release", - Purpose: "", - Playbook: "playbook-1674851385983", - Illustration: "/static/worktemplates/devops/product_release/channel.png", - }, - }, { Board: &Board{ ID: "board-1674851386432", @@ -474,6 +460,15 @@ var wt37406285a41c18bcdeb881189f7acde0 = &WorkTemplate{ Illustration: "/static/worktemplates/boards/project_tasks.png", }, }, + { + Channel: &Channel{ + ID: "channel-1674851385983", + Name: "Product Release", + Purpose: "", + Playbook: "playbook-1674851385983", + Illustration: "/static/worktemplates/devops/product_release/channel.png", + }, + }, }, } @@ -487,18 +482,18 @@ var wtf7b846d35810f8272eeb9a1a562025b5 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.companywide.goals_and_okrs.channel", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.companywide.goals_and_okrs.board", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.companywide.goals_and_okrs.integration", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -533,24 +528,24 @@ var wtb9ab412890c2410c7b49eec8f12e7edc = &WorkTemplate{ ID: "companywide/create_project:v1", Category: "companywide", UseCase: "Create a project", - Illustration: "/static/worktemplates/companywide/create_project/create_project.svg", + Illustration: "/static/worktemplates/companywide/create_project/create_project.png", Visibility: "public", Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.companywide.create_project.channel", - DefaultMessage: "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template.", + DefaultMessage: "Chat with your team about your new project and decide how you’re going to structure it, in a collaborative channel.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.companywide.create_project.board", - DefaultMessage: "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template.", + DefaultMessage: "Use a Kanban board to define and track your project tasks and progress.", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.companywide.create_project.integration", - DefaultMessage: "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, @@ -601,18 +596,18 @@ var wt32ab773bfe021e3d4913931041552559 = &WorkTemplate{ Description: Description{ Channel: &TranslatableString{ ID: "worktemplate.leadership.goals_and_okrs.channel", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel.", Illustration: "", }, Board: &TranslatableString{ ID: "worktemplate.leadership.goals_and_okrs.board", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board. ", Illustration: "", }, Integration: &TranslatableString{ ID: "worktemplate.leadership.goals_and_okrs.integration", - DefaultMessage: "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel.", + DefaultMessage: "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you.", Illustration: "/static/worktemplates/integrations.png", }, }, diff --git a/server/channels/einterfaces/cloud.go b/server/channels/einterfaces/cloud.go index b5d6a75b68..70cdc4676a 100644 --- a/server/channels/einterfaces/cloud.go +++ b/server/channels/einterfaces/cloud.go @@ -47,4 +47,5 @@ type CloudInterface interface { CheckCWSConnection(userId string) error SelfServeDeleteWorkspace(userID string, deletionRequest *model.WorkspaceDeletionRequest) error + SubscribeToNewsletter(userID string, req *model.SubscribeNewsletterRequest) error } diff --git a/server/channels/einterfaces/mocks/CloudInterface.go b/server/channels/einterfaces/mocks/CloudInterface.go index db7c86acc2..2dd2711650 100644 --- a/server/channels/einterfaces/mocks/CloudInterface.go +++ b/server/channels/einterfaces/mocks/CloudInterface.go @@ -540,6 +540,20 @@ func (_m *CloudInterface) SelfServeDeleteWorkspace(userID string, deletionReques return r0 } +// SubscribeToNewsletter provides a mock function with given fields: userID, req +func (_m *CloudInterface) SubscribeToNewsletter(userID string, req *model.SubscribeNewsletterRequest) error { + ret := _m.Called(userID, req) + + var r0 error + if rf, ok := ret.Get(0).(func(string, *model.SubscribeNewsletterRequest) error); ok { + r0 = rf(userID, req) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // UpdateCloudCustomer provides a mock function with given fields: userID, customerInfo func (_m *CloudInterface) UpdateCloudCustomer(userID string, customerInfo *model.CloudCustomerInfo) (*model.CloudCustomer, error) { ret := _m.Called(userID, customerInfo) diff --git a/server/channels/store/opentracinglayer/opentracinglayer.go b/server/channels/store/opentracinglayer/opentracinglayer.go index 15d32a18e2..723b8a4775 100644 --- a/server/channels/store/opentracinglayer/opentracinglayer.go +++ b/server/channels/store/opentracinglayer/opentracinglayer.go @@ -3315,34 +3315,16 @@ func (s *OpenTracingLayerDraftStore) GetDraftsForUser(userID string, teamID stri return result, err } -func (s *OpenTracingLayerDraftStore) Save(d *model.Draft) (*model.Draft, error) { +func (s *OpenTracingLayerDraftStore) Upsert(d *model.Draft) (*model.Draft, error) { origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "DraftStore.Save") + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "DraftStore.Upsert") s.Root.Store.SetContext(newCtx) defer func() { s.Root.Store.SetContext(origCtx) }() defer span.Finish() - result, err := s.DraftStore.Save(d) - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - -func (s *OpenTracingLayerDraftStore) Update(d *model.Draft) (*model.Draft, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "DraftStore.Update") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.DraftStore.Update(d) + result, err := s.DraftStore.Upsert(d) if err != nil { span.LogFields(spanlog.Error(err)) ext.Error.Set(span, true) diff --git a/server/channels/store/retrylayer/retrylayer.go b/server/channels/store/retrylayer/retrylayer.go index 07997b61ac..3603bd7f7e 100644 --- a/server/channels/store/retrylayer/retrylayer.go +++ b/server/channels/store/retrylayer/retrylayer.go @@ -3703,32 +3703,11 @@ func (s *RetryLayerDraftStore) GetDraftsForUser(userID string, teamID string) ([ } -func (s *RetryLayerDraftStore) Save(d *model.Draft) (*model.Draft, error) { +func (s *RetryLayerDraftStore) Upsert(d *model.Draft) (*model.Draft, error) { tries := 0 for { - result, err := s.DraftStore.Save(d) - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - -func (s *RetryLayerDraftStore) Update(d *model.Draft) (*model.Draft, error) { - - tries := 0 - for { - result, err := s.DraftStore.Update(d) + result, err := s.DraftStore.Upsert(d) if err == nil { return result, nil } diff --git a/server/channels/store/sqlstore/draft_store.go b/server/channels/store/sqlstore/draft_store.go index b5b7dee743..7d4137a8e5 100644 --- a/server/channels/store/sqlstore/draft_store.go +++ b/server/channels/store/sqlstore/draft_store.go @@ -88,7 +88,7 @@ func (s *SqlDraftStore) Get(userId, channelId, rootId string, includeDeleted boo return &dt, nil } -func (s *SqlDraftStore) Save(draft *model.Draft) (*model.Draft, error) { +func (s *SqlDraftStore) Upsert(draft *model.Draft) (*model.Draft, error) { draft.PreSave() maxDraftSize := s.GetMaxDraftSize() if err := draft.IsValid(maxDraftSize); err != nil { @@ -96,6 +96,13 @@ func (s *SqlDraftStore) Save(draft *model.Draft) (*model.Draft, error) { } builder := s.getQueryBuilder().Insert("Drafts").Columns(draftSliceColumns()...).Values(draftToSlice(draft)...) + + if s.DriverName() == model.DatabaseDriverMysql { + builder = builder.SuffixExpr(sq.Expr("ON DUPLICATE KEY UPDATE UpdateAt = ?, Message = ?, Props = ?, FileIds = ?, Priority = ?, DeleteAt = ?", draft.UpdateAt, draft.Message, draft.Props, draft.FileIds, draft.Priority, 0)) + } else { + builder = builder.SuffixExpr(sq.Expr("ON CONFLICT (UserId, ChannelId, RootId) DO UPDATE SET UpdateAt = ?, Message = ?, Props = ?, FileIds = ?, Priority = ?, DeleteAt = ?", draft.UpdateAt, draft.Message, draft.Props, draft.FileIds, draft.Priority, 0)) + } + query, args, err := builder.ToSql() if err != nil { @@ -103,36 +110,7 @@ func (s *SqlDraftStore) Save(draft *model.Draft) (*model.Draft, error) { } if _, err = s.GetMasterX().Exec(query, args...); err != nil { - return nil, errors.Wrap(err, "failed to save Draft") - } - - return draft, nil -} - -func (s *SqlDraftStore) Update(draft *model.Draft) (*model.Draft, error) { - draft.PreUpdate() - - maxDraftSize := s.GetMaxDraftSize() - if err := draft.IsValid(maxDraftSize); err != nil { - return nil, err - } - - query := s.getQueryBuilder(). - Update("Drafts"). - Set("UpdateAt", draft.UpdateAt). - Set("Message", draft.Message). - Set("Props", draft.Props). - Set("FileIds", draft.FileIds). - Set("Priority", draft.Priority). - Set("DeleteAt", 0). - Where(sq.Eq{ - "UserId": draft.UserId, - "ChannelId": draft.ChannelId, - "RootId": draft.RootId, - }) - - if _, err := s.GetMasterX().ExecBuilder(query); err != nil { - return nil, errors.Wrapf(err, "failed to update Draft with channelid=%s", draft.ChannelId) + return nil, errors.Wrap(err, "failed to upsert Draft") } return draft, nil diff --git a/server/channels/store/sqlstore/store.go b/server/channels/store/sqlstore/store.go index a1d7380b38..8000384e95 100644 --- a/server/channels/store/sqlstore/store.go +++ b/server/channels/store/sqlstore/store.go @@ -237,7 +237,9 @@ func SetupConnection(connType string, dataSource string, settings *model.SqlSett } for i := 0; i < DBPingAttempts; i++ { - mlog.Info("Pinging SQL", mlog.String("database", connType), mlog.String("dataSource", dataSource)) + // At this point, we have passed sql.Open, so we deliberately ignore any errors. + sanitized, _ := SanitizeDataSource(*settings.DriverName, dataSource) + mlog.Info("Pinging SQL", mlog.String("database", connType), mlog.String("dataSource", sanitized)) ctx, cancel := context.WithTimeout(context.Background(), DBPingTimeoutSecs*time.Second) defer cancel() err = db.PingContext(ctx) diff --git a/server/channels/store/sqlstore/utils.go b/server/channels/store/sqlstore/utils.go index 809439c820..5242f0c527 100644 --- a/server/channels/store/sqlstore/utils.go +++ b/server/channels/store/sqlstore/utils.go @@ -5,6 +5,7 @@ package sqlstore import ( "database/sql" + "errors" "io" "net/url" "strconv" @@ -206,3 +207,29 @@ func ResetReadTimeout(dataSource string) (string, error) { config.ReadTimeout = 0 return config.FormatDSN(), nil } + +func SanitizeDataSource(driverName, dataSource string) (string, error) { + switch driverName { + case model.DatabaseDriverPostgres: + u, err := url.Parse(dataSource) + if err != nil { + return "", err + } + u.User = url.UserPassword("****", "****") + params := u.Query() + params.Del("user") + params.Del("password") + u.RawQuery = params.Encode() + return u.String(), nil + case model.DatabaseDriverMysql: + cfg, err := mysql.ParseDSN(dataSource) + if err != nil { + return "", err + } + cfg.User = "****" + cfg.Passwd = "****" + return cfg.FormatDSN(), nil + default: + return "", errors.New("invalid drivername. Not postgres or mysql.") + } +} diff --git a/server/channels/store/sqlstore/utils_test.go b/server/channels/store/sqlstore/utils_test.go index 811ebf001a..96468323bb 100644 --- a/server/channels/store/sqlstore/utils_test.go +++ b/server/channels/store/sqlstore/utils_test.go @@ -6,6 +6,7 @@ package sqlstore import ( "testing" + "github.com/mattermost/mattermost-server/v6/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -160,3 +161,45 @@ func TestAppendMultipleStatementsFlag(t *testing.T) { }) } } + +func TestSanitizeDataSource(t *testing.T) { + t.Run(model.DatabaseDriverPostgres, func(t *testing.T) { + testCases := []struct { + Original string + Sanitized string + }{ + { + "postgres://mmuser:mostest@localhost/dummy?sslmode=disable", + "postgres://%2A%2A%2A%2A:%2A%2A%2A%2A@localhost/dummy?sslmode=disable", + }, + { + "postgres://localhost/dummy?sslmode=disable&user=mmuser&password=mostest", + "postgres://%2A%2A%2A%2A:%2A%2A%2A%2A@localhost/dummy?sslmode=disable", + }, + } + driver := model.DatabaseDriverPostgres + for _, tc := range testCases { + out, err := SanitizeDataSource(driver, tc.Original) + require.NoError(t, err) + assert.Equal(t, tc.Sanitized, out) + } + }) + + t.Run(model.DatabaseDriverMysql, func(t *testing.T) { + testCases := []struct { + Original string + Sanitized string + }{ + { + "mmuser:mostest@tcp(localhost:3306)/mattermost_test?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s", + "****:****@tcp(localhost:3306)/mattermost_test?readTimeout=30s&writeTimeout=30s&charset=utf8mb4%2Cutf8", + }, + } + driver := model.DatabaseDriverMysql + for _, tc := range testCases { + out, err := SanitizeDataSource(driver, tc.Original) + require.NoError(t, err) + assert.Equal(t, tc.Sanitized, out) + } + }) +} diff --git a/server/channels/store/store.go b/server/channels/store/store.go index dec4fa0f89..e52c2037ab 100644 --- a/server/channels/store/store.go +++ b/server/channels/store/store.go @@ -985,11 +985,10 @@ type PostPriorityStore interface { } type DraftStore interface { - Save(d *model.Draft) (*model.Draft, error) + Upsert(d *model.Draft) (*model.Draft, error) Get(userID, channelID, rootID string, includeDeleted bool) (*model.Draft, error) Delete(userID, channelID, rootID string) error GetDraftsForUser(userID, teamID string) ([]*model.Draft, error) - Update(d *model.Draft) (*model.Draft, error) } type PostAcknowledgementStore interface { diff --git a/server/channels/store/storetest/draft_store.go b/server/channels/store/storetest/draft_store.go index 377f36fa60..45eb33cae9 100644 --- a/server/channels/store/storetest/draft_store.go +++ b/server/channels/store/storetest/draft_store.go @@ -68,17 +68,21 @@ func testSaveDraft(t *testing.T, ss store.Store) { } t.Run("save drafts", func(t *testing.T) { - draftResp, err := ss.Draft().Save(draft1) + draftResp, err := ss.Draft().Upsert(draft1) assert.NoError(t, err) assert.Equal(t, draft1.Message, draftResp.Message) assert.Equal(t, draft1.ChannelId, draftResp.ChannelId) - draftResp, err = ss.Draft().Save(draft2) + draftResp, err = ss.Draft().Upsert(draft2) assert.NoError(t, err) assert.Equal(t, draft2.Message, draftResp.Message) assert.Equal(t, draft2.ChannelId, draftResp.ChannelId) + + drafts, err := ss.Draft().GetDraftsForUser(user.Id, "") + assert.NoError(t, err) + assert.Len(t, drafts, 2) }) } @@ -90,56 +94,52 @@ func testUpdateDraft(t *testing.T, ss store.Store) { channel := &model.Channel{ Id: model.NewId(), } - channel2 := &model.Channel{ - Id: model.NewId(), - } - member1 := &model.ChannelMember{ + member := &model.ChannelMember{ ChannelId: channel.Id, UserId: user.Id, NotifyProps: model.GetDefaultChannelNotifyProps(), } - member2 := &model.ChannelMember{ - ChannelId: channel2.Id, - UserId: user.Id, - NotifyProps: model.GetDefaultChannelNotifyProps(), - } - - _, err := ss.Channel().SaveMember(member1) + _, err := ss.Channel().SaveMember(member) require.NoError(t, err) - _, err = ss.Channel().SaveMember(member2) - require.NoError(t, err) - - draft1 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00001, - UserId: user.Id, - ChannelId: channel.Id, - Message: "draft1", - } - - draft2 := &model.Draft{ - CreateAt: 00005, - UpdateAt: 00005, - UserId: user.Id, - ChannelId: channel2.Id, - Message: "draft2", - } - t.Run("update drafts", func(t *testing.T) { - draftResp, err := ss.Draft().Update(draft1) + draft := &model.Draft{ + UserId: user.Id, + ChannelId: channel.Id, + Message: "draft", + } + _, err := ss.Draft().Upsert(draft) assert.NoError(t, err) - assert.Equal(t, draft1.Message, draftResp.Message) - assert.Equal(t, draft1.ChannelId, draftResp.ChannelId) + drafts, err := ss.Draft().GetDraftsForUser(user.Id, "") + assert.NoError(t, err) + assert.Len(t, drafts, 1) + draft1 := drafts[0] - draftResp, err = ss.Draft().Update(draft2) + assert.Greater(t, draft1.CreateAt, int64(0)) + assert.Equal(t, draft1.UpdateAt, draft1.CreateAt) + assert.Equal(t, channel.Id, draft1.ChannelId) + assert.Equal(t, "draft", draft1.Message) + + updatedDraft := &model.Draft{ + UserId: user.Id, + ChannelId: channel.Id, + Message: "updatedDraft", + } + _, err = ss.Draft().Upsert(updatedDraft) assert.NoError(t, err) - assert.Equal(t, draft2.Message, draftResp.Message) - assert.Equal(t, draft2.ChannelId, draftResp.ChannelId) + drafts, err = ss.Draft().GetDraftsForUser(user.Id, "") + assert.NoError(t, err) + assert.Len(t, drafts, 1) + draft2 := drafts[0] + + assert.Greater(t, draft2.CreateAt, int64(0)) + assert.Equal(t, "updatedDraft", draft2.Message) + assert.Equal(t, channel.Id, draft2.ChannelId) + assert.Equal(t, draft1.CreateAt, draft2.CreateAt) }) } @@ -189,10 +189,10 @@ func testDeleteDraft(t *testing.T, ss store.Store) { Message: "draft2", } - _, err = ss.Draft().Save(draft1) + _, err = ss.Draft().Upsert(draft1) require.NoError(t, err) - _, err = ss.Draft().Save(draft2) + _, err = ss.Draft().Upsert(draft2) require.NoError(t, err) t.Run("delete drafts", func(t *testing.T) { @@ -258,10 +258,10 @@ func testGetDraft(t *testing.T, ss store.Store) { Message: "draft2", } - _, err = ss.Draft().Save(draft1) + _, err = ss.Draft().Upsert(draft1) require.NoError(t, err) - _, err = ss.Draft().Save(draft2) + _, err = ss.Draft().Upsert(draft2) require.NoError(t, err) t.Run("get drafts", func(t *testing.T) { @@ -326,35 +326,28 @@ func testGetDraftsForUser(t *testing.T, ss store.Store) { require.NoError(t, err) draft1 := &model.Draft{ - CreateAt: 00001, - UpdateAt: 00001, UserId: user.Id, ChannelId: channel.Id, Message: "draft1", } draft2 := &model.Draft{ - CreateAt: 00005, - UpdateAt: 00005, UserId: user.Id, ChannelId: channel2.Id, Message: "draft2", } - _, err = ss.Draft().Save(draft1) + _, err = ss.Draft().Upsert(draft1) require.NoError(t, err) - _, err = ss.Draft().Save(draft2) + _, err = ss.Draft().Upsert(draft2) require.NoError(t, err) t.Run("get drafts", func(t *testing.T) { draftResp, err := ss.Draft().GetDraftsForUser(user.Id, "") assert.NoError(t, err) + assert.Len(t, draftResp, 2) - assert.Equal(t, draft2.Message, draftResp[0].Message) - assert.Equal(t, draft2.ChannelId, draftResp[0].ChannelId) - - assert.Equal(t, draft1.Message, draftResp[1].Message) - assert.Equal(t, draft1.ChannelId, draftResp[1].ChannelId) + assert.ElementsMatch(t, []*model.Draft{draft1, draft2}, draftResp) }) } diff --git a/server/channels/store/storetest/mocks/DraftStore.go b/server/channels/store/storetest/mocks/DraftStore.go index 1eb7d5f17b..924bb49883 100644 --- a/server/channels/store/storetest/mocks/DraftStore.go +++ b/server/channels/store/storetest/mocks/DraftStore.go @@ -74,31 +74,8 @@ func (_m *DraftStore) GetDraftsForUser(userID string, teamID string) ([]*model.D return r0, r1 } -// Save provides a mock function with given fields: d -func (_m *DraftStore) Save(d *model.Draft) (*model.Draft, error) { - ret := _m.Called(d) - - var r0 *model.Draft - if rf, ok := ret.Get(0).(func(*model.Draft) *model.Draft); ok { - r0 = rf(d) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Draft) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*model.Draft) error); ok { - r1 = rf(d) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Update provides a mock function with given fields: d -func (_m *DraftStore) Update(d *model.Draft) (*model.Draft, error) { +// Upsert provides a mock function with given fields: d +func (_m *DraftStore) Upsert(d *model.Draft) (*model.Draft, error) { ret := _m.Called(d) var r0 *model.Draft diff --git a/server/channels/store/timerlayer/timerlayer.go b/server/channels/store/timerlayer/timerlayer.go index 8199138ac2..2c156ccbe5 100644 --- a/server/channels/store/timerlayer/timerlayer.go +++ b/server/channels/store/timerlayer/timerlayer.go @@ -3038,10 +3038,10 @@ func (s *TimerLayerDraftStore) GetDraftsForUser(userID string, teamID string) ([ return result, err } -func (s *TimerLayerDraftStore) Save(d *model.Draft) (*model.Draft, error) { +func (s *TimerLayerDraftStore) Upsert(d *model.Draft) (*model.Draft, error) { start := time.Now() - result, err := s.DraftStore.Save(d) + result, err := s.DraftStore.Upsert(d) elapsed := float64(time.Since(start)) / float64(time.Second) if s.Root.Metrics != nil { @@ -3049,23 +3049,7 @@ func (s *TimerLayerDraftStore) Save(d *model.Draft) (*model.Draft, error) { if err == nil { success = "true" } - s.Root.Metrics.ObserveStoreMethodDuration("DraftStore.Save", success, elapsed) - } - return result, err -} - -func (s *TimerLayerDraftStore) Update(d *model.Draft) (*model.Draft, error) { - start := time.Now() - - result, err := s.DraftStore.Update(d) - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("DraftStore.Update", success, elapsed) + s.Root.Metrics.ObserveStoreMethodDuration("DraftStore.Upsert", success, elapsed) } return result, err } diff --git a/server/config/database.go b/server/config/database.go index f2463e33b4..dd508d9c4f 100644 --- a/server/config/database.go +++ b/server/config/database.go @@ -407,7 +407,10 @@ func (ds *DatabaseStore) RemoveFile(name string) error { // String returns the path to the database backing the config, masking the password. func (ds *DatabaseStore) String() string { - return stripPassword(ds.originalDsn, ds.driverName) + // This is called during the running of MM, so we expect the parsing of DSN + // to be successful. + sanitized, _ := sqlstore.SanitizeDataSource(ds.driverName, ds.originalDsn) + return sanitized } // Close cleans up resources associated with the store. diff --git a/server/config/database_test.go b/server/config/database_test.go index 4eab71fc5c..6954461a08 100644 --- a/server/config/database_test.go +++ b/server/config/database_test.go @@ -1107,12 +1107,12 @@ func TestDatabaseStoreString(t *testing.T) { if *mainHelper.GetSQLSettings().DriverName == "postgres" { maskedDSN := ds.String() assert.True(t, strings.HasPrefix(maskedDSN, "postgres://")) - assert.True(t, strings.Contains(maskedDSN, "mmuser")) + assert.False(t, strings.Contains(maskedDSN, "mmuser")) assert.False(t, strings.Contains(maskedDSN, "mostest")) } else { maskedDSN := ds.String() - assert.True(t, strings.HasPrefix(maskedDSN, "mysql://")) - assert.True(t, strings.Contains(maskedDSN, "mmuser")) + assert.False(t, strings.HasPrefix(maskedDSN, "mysql://")) + assert.False(t, strings.Contains(maskedDSN, "mmuser")) assert.False(t, strings.Contains(maskedDSN, "mostest")) } } diff --git a/server/config/utils.go b/server/config/utils.go index b343106562..f247ea4a43 100644 --- a/server/config/utils.go +++ b/server/config/utils.go @@ -179,27 +179,6 @@ func IsDatabaseDSN(dsn string) bool { strings.HasPrefix(dsn, "postgresql://") } -// stripPassword remove the password from a given DSN -func stripPassword(dsn, schema string) string { - prefix := schema + "://" - dsn = strings.TrimPrefix(dsn, prefix) - - i := strings.Index(dsn, ":") - j := strings.LastIndex(dsn, "@") - - // Return error if no @ sign is found - if j < 0 { - return "(omitted due to error parsing the DSN)" - } - - // Return back the input if no password is found - if i < 0 || i > j { - return prefix + dsn - } - - return prefix + dsn[:i+1] + dsn[j:] -} - func isJSONMap(data string) bool { var m map[string]any return json.Unmarshal([]byte(data), &m) == nil diff --git a/server/config/utils_test.go b/server/config/utils_test.go index e3b903eeb1..9c8de20d23 100644 --- a/server/config/utils_test.go +++ b/server/config/utils_test.go @@ -197,61 +197,6 @@ func TestIsDatabaseDSN(t *testing.T) { } } -func TestStripPassword(t *testing.T) { - for name, test := range map[string]struct { - DSN string - Schema string - ExpectedOut string - }{ - "mysql": { - DSN: "mysql://mmuser:password@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - Schema: "mysql", - ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - }, - "mysql idempotent": { - DSN: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - Schema: "mysql", - ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - }, - "mysql: password with : and @": { - DSN: "mysql://mmuser:p:assw@ord@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - Schema: "mysql", - ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - }, - "mysql: password with @ and :": { - DSN: "mysql://mmuser:pa@sswo:rd@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - Schema: "mysql", - ExpectedOut: "mysql://mmuser:@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s", - }, - "postgres": { - DSN: "postgres://mmuser:password@localhost:5432/mattermost?sslmode=disable&connect_timeout=10", - Schema: "postgres", - ExpectedOut: "postgres://mmuser:@localhost:5432/mattermost?sslmode=disable&connect_timeout=10", - }, - "pipe": { - DSN: "mysql://user@unix(/path/to/socket)/dbname", - Schema: "mysql", - ExpectedOut: "mysql://user@unix(/path/to/socket)/dbname", - }, - "malformed without :": { - DSN: "postgres://mmuserpassword@localhost:5432/mattermost?sslmode=disable&connect_timeout=10", - Schema: "postgres", - ExpectedOut: "postgres://mmuserpassword@localhost:5432/mattermost?sslmode=disable&connect_timeout=10", - }, - "malformed without @": { - DSN: "postgres://mmuser:passwordlocalhost:5432/mattermost?sslmode=disable&connect_timeout=10", - Schema: "postgres", - ExpectedOut: "(omitted due to error parsing the DSN)", - }, - } { - t.Run(name, func(t *testing.T) { - out := stripPassword(test.DSN, test.Schema) - - assert.Equal(t, test.ExpectedOut, out) - }) - } -} - func TestIsJSONMap(t *testing.T) { tests := []struct { name string diff --git a/server/i18n/de.json b/server/i18n/de.json index 7d7cefc91d..3e7aed88f5 100644 --- a/server/i18n/de.json +++ b/server/i18n/de.json @@ -9022,50 +9022,6 @@ "id": "api.custom_groups.count_err", "translation": "Fehler beim Zählen der Gruppen" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Erhöhe die Produktivität mit diesen tollen Funktionen" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hi {{.Name}}, wir haben bemerkt, dass Dein Mattermost Server etwas Staub ansetzt, Schau mal auf die neuen Funktionen, die Dir helfen die Belastung Deines Team zu senken." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Öffne Mattermost um Dein Team produktiver zu machen!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Verwalte Aufgaben mit " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Arbeitsablauf-Verwaltung mit " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Gastzugriff auf angegebene " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Komm und teste es!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Öffne Mattermost" - }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "Kanäle" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "Kann nicht alle Jobs nach Typ und Status holen." @@ -9170,10 +9126,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Die Elasticsearch-Einstellungen haben nicht definierte Werte." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Du hast diese einmalige E-Mail erhalten, weil dein Mattermost-Server für mehr als {{.Hours}} Stunden inaktiv war. Diese E-Mail wurde automatisch von deinem Mattermost-Server generiert." - }, { "id": "api.file.cloud_upload.app_error", "translation": "Hochladen über mmctl zu einer Cloud Instanz wird nicht unterstützt. Bitte prüfe die Dokumentation: https://docs.mattermost.com/manage/cloud-data-export.html." @@ -9510,10 +9462,6 @@ "id": "model.group.name.reserved_name.app_error", "translation": "Gruppenname existiert bereits als reservierter Name" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Plugin {{.Name}} kann im Produktmodus nicht aktiviert werden." - }, { "id": "api.team.invite_guests_to_channels.license.error", "translation": "Deine Lizenz unterstützt Gastkonten nicht" @@ -9586,10 +9534,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Die Priorität der Nachricht kann nicht ermittelt werden" }, - { - "id": "app.draft.update.app_error", - "translation": "Die Aktualisierung des Entwurfs ist nicht möglich." - }, { "id": "app.draft.save.app_error", "translation": "Der Entwurf kann nicht gespeichert werden." @@ -9662,17 +9606,9 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Du kannst eine Bestätigung in einem archivierten Kanal nicht entfernen." }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Chatten mit deinem Team in einem Feature-Release-Kanal, der sich problemlos mit deinen Boards, Playbooks und App-Bots verbinden lässt." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Verwende unsere Vorlage für die Besprechungsagenda für wiederkehrende Besprechungen wie z. B. Standup-Meetings und unsere Projektaufgabentafel, um den Fortschritt der Aufgaben zu verwalten." - }, { "id": "worktemplate.category.product_teams", - "translation": "Produkt-Teams" + "translation": "Produkt" }, { "id": "model.draft.is_valid.priority.app_error", @@ -9686,13 +9622,9 @@ "id": "app.worktemplates.get_categories.app_error", "translation": "Arbeitsvorlagenkategorien können nicht abgerufen werden" }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Erstelle transparente Arbeitsabläufe zwischen den Entwicklungsteams, um einen nahtlosen Entwicklungsprozess zu gewährleisten." - }, { "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Steigere die Produktivität in deinem Kanal durch die Integration eines Jira-Bots und eines Github-Bots. Diese werden für dich heruntergeladen." + "translation": "Steigere die Produktivität in deinem Kanal durch die Integration deiner am meistern verwendeten Tools, wie GitHub oder Jira. Diese werden für dich heruntergeladen." }, { "id": "api.templates.cloud_welcome_email.yearly_plan_button", @@ -9810,121 +9742,13 @@ "id": "app.worktemplates.execute_work_template.playbooks.find_channel_error", "translation": "Kanal, der mit einem Playbook verbunden ist, kann nicht gefunden werden." }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Verwende ein Projekt, um die Sprint-Planung zum Kinderspiel zu machen. Der Kanal sorgt dafür, dass die Unterhaltungen und Fragen fokussiert bleiben. Der Sprintplan hält alle Beteiligten auf dem Laufenden, und das Retrospektive Board bringt das Team zusammen, um sich kontinuierlich zu verbessern." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Verwende ein Projekt, um die Sprint-Planung zum Kinderspiel zu machen. Der Kanal sorgt dafür, dass die Unterhaltungen und Fragen fokussiert bleiben. Der Sprintplan hält alle Beteiligten auf dem Laufenden, und das Retrospektive Board bringt das Team zusammen, um sich kontinuierlich zu verbessern." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Verwende ein Projekt, um die Sprint-Planung zum Kinderspiel zu machen. Der Kanal sorgt dafür, dass die Unterhaltungen und Fragen fokussiert bleiben. Der Sprintplan hält alle Beteiligten auf dem Laufenden, und das Retrospektive Board bringt das Team zusammen, um sich kontinuierlich zu verbessern." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Beschreibung, warum der/die Kanal/Kanäle benötigt werden" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Beschreibung, warum das/die Board(s) benötigt werden" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Organisiere dich und beseitige alle Bugs mit diesem Projekt! Bauen eine Dynamik auf und messe den Fortschritt mit dem zugeordneten Playbook, Board und Kanal." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Organisiere dich und beseitige alle Bugs mit diesem Projekt! Bauen eine Dynamik auf und messe den Fortschritt mit dem zugeordneten Playbook, Board und Kanal." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Organisiere dich und beseitige alle Bugs mit diesem Projekt! Bauen eine Dynamik auf und messe den Fortschritt mit dem zugeordneten Playbook, Board und Kanal." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Organisiere dich und beseitige alle Bugs mit diesem Projekt! Bauen eine Dynamik auf und messe den Fortschritt mit dem zugeordneten Playbook, Board und Kanal." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Verpasse mit diesem Projekt keinen Schritt während einer Produktfreigabe. Weise Aufgaben aus der Playbook-Checkliste zu und setze Meilensteine mit dem Board. Verwende Kanäle, um alle auf dem gleichen Stand zu halten." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Verpasse mit diesem Projekt keinen Schritt während einer Produktfreigabe. Weise Aufgaben aus der Playbook-Checkliste zu und setze Meilensteine mit dem Board. Verwende Kanäle, um alle auf dem gleichen Stand zu halten." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Verpasse mit diesem Projekt keinen Schritt während einer Produktfreigabe. Weise Aufgaben aus der Playbook-Checkliste zu und setze Meilensteine mit dem Board. Verwende Kanäle, um alle auf dem gleichen Stand zu halten." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "Wenn alles schief läuft, ist ein wiederholbarer Prozess der Schlüssel, um sicherzustellen, dass alles so schnell wie möglich in Ordnung gebracht wird. Dieses Projekt kombiniert alles, was Mattermost bietet, um sicherzustellen, dass die Probleme gelöst und die Beteiligten auf dem Weg dahin informiert werden." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "Wenn alles schief läuft, ist ein wiederholbarer Prozess der Schlüssel, um sicherzustellen, dass alles so schnell wie möglich in Ordnung gebracht wird. Dieses Projekt kombiniert alles, was Mattermost bietet, um sicherzustellen, dass die Probleme gelöst und die Beteiligten auf dem Weg dahin informiert werden." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "Wenn alles schief läuft, ist ein wiederholbarer Prozess der Schlüssel, um sicherzustellen, dass alles so schnell wie möglich in Ordnung gebracht wird. Dieses Projekt kombiniert alles, was Mattermost bietet, um sicherzustellen, dass die Probleme gelöst und die Beteiligten auf dem Weg dahin informiert werden." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Ein klarer Fokus ist für den Teamerfolg unerlässlich. Mit diesem Projekt kannst du die Ziele und OKRs des Teams dokumentieren und Aktualisierungen in den entsprechenden Kanal einstellen." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Plane eine Roadmap mit diesem Projekt-Board und arbeite gemeinsam in dem mit dieser Vorlage erstellten Kanal an einem Thema." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Plane eine Roadmap mit diesem Projekt-Board und arbeite im Team in dem mit dieser Vorlage erstellten Kanal an einem Thema." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Plane mit diesem Projektboard eine Roadmap und arbeite in dem mit dieser Vorlage erstellten Kanal an einem Thema." - }, { "id": "worktemplate.category.leadership", "translation": "Führung" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", @@ -10221,5 +10045,125 @@ { "id": "app.command.execute.error", "translation": "Kann Befehl nicht ausführen." + }, + { + "id": "api.license.request-trial.bad-request.business-email", + "translation": "Ungültige geschäftliche E-Mail für den Test" + }, + { + "id": "worktemplate.product_teams.sprint_planning.integration", + "translation": "Steigere die Produktivität deines Kanals, indem du die am häufigsten verwendeten Tools wie z. B. Zoom integrierst. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.product_teams.sprint_planning.channel", + "translation": "Chatte mit deinem Team in einem Kanal, der sich leicht mit deinen Boards und Integrationen verbinden lässt." + }, + { + "id": "worktemplate.product_teams.sprint_planning.board", + "translation": "Verfolge den Fortschritt deines Teams bei der Erreichung der wöchentlichen Ziele mit Sprintaufteilung, Priorisierung, Zuweisung von Verantwortlichen und Kommentaren." + }, + { + "id": "worktemplate.product_teams.product_roadmap.channel", + "translation": "Chatte mit deinem Team über das Feedback deiner Kunden, setze Prioritäten und stimmt euch gemeinsam über den Fortschritt ab." + }, + { + "id": "worktemplate.product_teams.product_roadmap.board", + "translation": "Verwende das Produkt-Roadmap-Board, um Benutzer-Feedback zu verwalten, Ressourcen zuzuweisen, Ergebnisse in einer Kalenderansicht anzuzeigen und Probleme nach Priorität zu ordnen." + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.integration", + "translation": "Steigere die Produktivität in deinem Kanal, indem du die am häufigsten verwendeten Tools wie Zoom integrierst, um die Zusammenarbeit zu erleichtern. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.channel", + "translation": "Chatte mit deinem Team über Ziele und Fortschritte, asynchron oder in Echtzeit, und bleibe über Änderungen in einem einzigen Kanal auf dem Laufenden." + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.board", + "translation": "Verfolge den Fortschritt deines Teams auf dem Weg zu den Unternehmenszielen mit dem Ziele und OKR Board. Halten Besprechungen mit der Besprechungsagenda auf Kurs." + }, + { + "id": "worktemplate.product_teams.feature_release.description.playbook", + "translation": "Fördere die funktionsübergreifende Zusammenarbeit im Team mit Aufgaben-Checklisten und Automatisierungen, die deinen Entwicklungsprozess unterstützen. Führe anschließend eine Retrospektive durch und nimm Verbesserungen für deine nächste Version vor." + }, + { + "id": "worktemplate.product_teams.feature_release.description.channel", + "translation": "Chatte mit deinem Team über alle Release-Blocker und Änderungen in einem Kanal, der sich leicht mit deinen Boards, Playbooks und anderen Integrationen verbinden lässt." + }, + { + "id": "worktemplate.product_teams.feature_release.description.board", + "translation": "Halte Besprechungen mit der Besprechungsagenda auf dem Laufenden. Verwalte dein Arbeitspensum mit dem Projektaufgabenboard." + }, + { + "id": "worktemplate.product_teams.bug_bash.playbook", + "translation": "Verwende Checklisten, um Testbereiche zuzuweisen, und automatisierte Aufgaben, um einen umfassenden Fehlerbehebungsprozess durchzuführen. Nutze eine Retrospektive, um deinen Prozess zu überprüfen und ihn für das nächste Mal zu verbessern." + }, + { + "id": "worktemplate.product_teams.bug_bash.integration", + "translation": "Steigere die Produktivität in deinem Kanal, indem du die am häufigsten verwendeten Tools, wie z. B. Jira, integrierst, um den Fortschritt bei der Fehlerbehebung zu verfolgen. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.product_teams.bug_bash.channel", + "translation": "Plane und verwalte Fehlerberichte und -behebungen in einem einzigen Kanal, der für dein Team und deine Organisation leicht zugänglich ist." + }, + { + "id": "worktemplate.leadership.goals_and_okrs.integration", + "translation": "Steigere die Produktivität in deinem Kanal, indem du die am häufigsten verwendeten Tools wie Zoom integrierst, um die Zusammenarbeit zu erleichtern. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.leadership.goals_and_okrs.channel", + "translation": "Chatte mit deinem Team über Ziele und Fortschritte, asynchron oder in Echtzeit, und bleibe über Änderungen in einem einzigen Kanal auf dem Laufenden." + }, + { + "id": "worktemplate.leadership.goals_and_okrs.board", + "translation": "Verfolge den Fortschritt deines Teams auf dem Weg zu den Unternehmenszielen mit dem Ziele und OKR Board. Halten Besprechungen mit der Besprechungsagenda auf Kurs." + }, + { + "id": "worktemplate.devops.product_release.playbook", + "translation": "Erstelle wiederholbare Arbeitsabläufe, die einfach zu befolgen und zu implementieren sind, damit die Produktveröffentlichungen zuverlässig und pünktlich erfolgen." + }, + { + "id": "worktemplate.devops.product_release.channel", + "translation": "Chatte einfach und schnell mit deinem Team über tägliche Meilensteine, eventuelle Hindernisse und Änderungen an den zu erbringenden Leistungen." + }, + { + "id": "worktemplate.devops.product_release.board", + "translation": "Verwende das Product Release Board, um den Zeitrahmen und den Prozess für die Freigabe zu unterstützen und sicherzustellen, dass jeder weiß, welche Aufgaben fällig sind." + }, + { + "id": "worktemplate.devops.incident_resolution.description.playbook", + "translation": "Nutze Checklisten und Automatisierungen, um wichtige Teammitglieder einzubeziehen, und teile mit, wie der Vorfall gelöst wird." + }, + { + "id": "worktemplate.devops.incident_resolution.description.channel", + "translation": "Chatte mit deinem Team über Prioritäten, füge Beteiligte hinzu, liefere Updates und arbeite an einer Lösung in einem einzigen Kanal." + }, + { + "id": "worktemplate.devops.incident_resolution.description.board", + "translation": "Verwende das Incident Resolution Board, um wiederholbare Prozesse zu unterstützen und definierte Aufgaben im Team zuzuweisen." + }, + { + "id": "worktemplate.companywide.goals_and_okrs.integration", + "translation": "Steigere die Produktivität in deinem Kanal, indem du die am häufigsten verwendeten Tools wie Zoom integrierst, um die Zusammenarbeit zu erleichtern. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.companywide.goals_and_okrs.channel", + "translation": "Chatte mit deinem Team über Ziele und Fortschritte, asynchron oder in Echtzeit, und bleibe über Änderungen in einem einzigen Kanal auf dem Laufenden." + }, + { + "id": "worktemplate.companywide.goals_and_okrs.board", + "translation": "Verfolge den Fortschritt deines Teams auf dem Weg zu den Unternehmenszielen mit dem Ziele und OKR Board. Halten Besprechungen mit der Besprechungsagenda auf Kurs." + }, + { + "id": "worktemplate.companywide.create_project.integration", + "translation": "Steigere die Produktivität deines Kanals durch die Integration am deiner am häufigsten verwendeten Tools. Diese werden für dich heruntergeladen." + }, + { + "id": "worktemplate.companywide.create_project.channel", + "translation": "Chatte mit deinem Team über ein neues Projekt und entscheide, wie es strukturiert werden soll, und zwar in einem Kanal zur Zusammenarbeit." + }, + { + "id": "worktemplate.companywide.create_project.board", + "translation": "Verwend eine Kanban-Board, um deine Projektaufgaben und -fortschritte zu definieren und zu verfolgen." } ] diff --git a/server/i18n/en.json b/server/i18n/en.json index 0994b13552..e73fa524c8 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -2591,6 +2591,10 @@ "id": "api.server.cws.needs_enterprise_edition", "translation": "Service only available in Mattermost Enterprise edition" }, + { + "id": "api.server.cws.subscribe_to_newsletter.app_error", + "translation": "CWS Server failed to subscribe to newsletter." + }, { "id": "api.server.hosted_signup_unavailable.error", "translation": "Portal unavailable for self-hosted signup." @@ -5027,10 +5031,6 @@ "id": "app.draft.save.app_error", "translation": "Unable to save the Draft." }, - { - "id": "app.draft.update.app_error", - "translation": "Unable to update the Draft." - }, { "id": "app.email.no_rate_limiter.app_error", "translation": "Rate limiter is not set up." @@ -10033,11 +10033,11 @@ }, { "id": "worktemplate.category.companywide", - "translation": "Company - Wide" + "translation": "Company-wide" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.leadership", @@ -10045,130 +10045,126 @@ }, { "id": "worktemplate.category.product_teams", - "translation": "Product Teams" + "translation": "Product" }, { "id": "worktemplate.companywide.create_project.board", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." + "translation": "Use a Kanban board to define and track your project tasks and progress." }, { "id": "worktemplate.companywide.create_project.channel", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." + "translation": "Chat with your team about your new project and decide how you’re going to structure it, in a collaborative channel." }, { "id": "worktemplate.companywide.create_project.integration", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." + "translation": "Increase productivity in your channel by integrating your most commonly used tools. These will be downloaded for you." }, { "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board." }, { "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel." }, { "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you." }, { "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + "translation": "Use the Incident Resolution board to support repeatable processes and assign defined tasks across the team." }, { "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + "translation": "Chat with your team about priorities, add stakeholders, provide updates, and work toward a resolution in a single channel." }, { "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure the fires are put out and stakeholders informed along the way." + "translation": "Use checklists and automation to bring in key team members, and share how your incident is tracking toward resolution." }, { "id": "worktemplate.devops.product_release.board", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." + "translation": "Use the Product Release board to support your release timeframe and process, ensuring everyone knows which tasks are due." }, { "id": "worktemplate.devops.product_release.channel", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." + "translation": "Chat with your team about daily milestones, any blockers, and changes to deliverables, easily and quickly." }, { "id": "worktemplate.devops.product_release.playbook", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." + "translation": "Create repeatable workflows that are easy to follow and implement so product releases are reliable and on time." }, { "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board." }, { "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel." }, { "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel." + "translation": "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you." }, { "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel." + "translation": "Plan and manage bug reports and resolutions in a single channel, that’s easily accessible to your team and organization." }, { "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel." + "translation": "Increase productivity in your channel by integrating your most commonly used tools, such as Jira, to track your bug bash progress. These will be downloaded for you." }, { "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Get organized and bash all the bugs with this project! Build momentum and measure progress using included Playbook, Board, and Channel." + "translation": "Use checklists to assign testing areas and automated tasks to run a comprehensive bug bash process. Use a retrospective to review your process and improve it for next time." }, { "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Use our Meeting Agenda board template for recurring meetings like standup and our Project Tasks board to manage the progress of tasks along the way." + "translation": "Keep meetings on track with the Meeting Agenda board. Manage your workload with the Project Tasks board." }, { "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Chat with your team in a Feature Release channel that connects easily with your boards, playbooks and app bots." + "translation": "Chat with your team about any release blockers and changes in a channel that connects easily with your boards, playbooks and other integrations." }, { "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Increase productivity in your channel by integrating a Jira bot and Github bot. These will be downloaded for you." + "translation": "Increase productivity in your channel by integrating your most commonly used tools to support your feature release, such as GitHub. These will be downloaded for you." }, { "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Create transparent workflows across development teams to ensure your feature development process is seamless." + "translation": "Boost cross-functional team collaboration with task checklists and automation that support your feature development process. When you're done, run a retrospective and make improvements for your next release." }, { "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Track your team's progress toward organizational goals with the Goals and OKR board. Keep meetings on track with the Meeting Agenda board." }, { "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Chat about your goals and progress with your team, async or real-time, and stay up to date with changes in a single channel." }, { "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKR’s as well as post updates in the dedicated channel." + "translation": "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom, to facilitate easy collaboration. These will be downloaded for you." }, { "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Description of why the board(s) are needed" + "translation": "Use the Product Roadmap board to manage user feedback, assign resources, view deliverables in a calendar view, and prioritize issues." }, { "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Description of why the channel(s) are needed" + "translation": "Chat with your team about your customers' feedback, prioritization, and get aligned on progress together." }, { "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." + "translation": "Track your team's progress toward weekly goals with sprint breakdowns, prioritization, owner assignment, and comments." }, { "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." + "translation": "Chat with your team in a channel that connects easily with your boards and integrations." }, { "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." + "translation": "Increase productivity in your channel by integrating your most commonly used tools, such as Zoom. These will be downloaded for you." } ] diff --git a/server/i18n/en_AU.json b/server/i18n/en_AU.json index d5847594f7..8a71e91c0d 100644 --- a/server/i18n/en_AU.json +++ b/server/i18n/en_AU.json @@ -9026,50 +9026,6 @@ "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "Unable to get the all jobs by type and status." }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Unlock increased productivity with these awesome features" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hey {{.Name}}, your Mattermost server has been a bit inactive. Would you like to take a look at some features that can help lighten your team's workload?" - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Open Mattermost to increase your team’s productivity!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Manage tasks using " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Workflow management with " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Guest Access to specified " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Come and check it out!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Open Mattermost" - }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "Channels" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "app.prepackged-plugin.invalid_version.app_error", "translation": "A prepackged plugin version could not be parsed." @@ -9166,10 +9122,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Elasticsearch settings has unset values." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "You received this one-time email because your Mattermost server was inactive for more than {{.Hours}} hours. This email was automatically generated by your Mattermost server." - }, { "id": "app.recent_searches.app_error", "translation": "An error occurred while fetching recent searches" @@ -9518,10 +9470,6 @@ "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Invalid time range." }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Plugin {{.Name}} cannot be enabled in product mode." - }, { "id": "api.team.invite_guests_to_channels.license.error", "translation": "Your workspace licence does not support guest accounts" @@ -9594,10 +9542,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Unable to get post priority for post" }, - { - "id": "app.draft.update.app_error", - "translation": "Unable to update the draft." - }, { "id": "app.draft.save.app_error", "translation": "Unable to save the draft." @@ -9650,13 +9594,9 @@ "id": "worktemplate.product_teams.feature_release.description.channel", "translation": "Chat with your team in a Feature Release channel that connects easily with your boards, playbooks and app bots." }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Use the Meeting Agenda board template for recurring meetings like standup and the Project Tasks board to manage the progress of tasks along the way." - }, { "id": "worktemplate.category.product_teams", - "translation": "Product Teams" + "translation": "Product" }, { "id": "model.draft.is_valid.priority.app_error", @@ -9766,125 +9706,17 @@ "id": "api.acknowledgement.delete.deadline.app_error", "translation": "You cannot delete an acknowledgment after 5 minutes has elapsed." }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Use a Project to make sprint planning a breeze. The channel keeps the conversation and questions focused. The sprint plan keeps everyone on task for the week and the Retrospective board brings the team together to continuously improve." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Description of why the channel(s) are necessary" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Description of why the board(s) are necessary" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Get organised and squash all the bugs with this project! Build momentum and measure progress using included Playbook, Board and Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Get organised and squash all the bugs with this project! Build momentum and measure progress using included Playbook, Board and Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Get organised and squash all the bugs with this project! Build momentum and measure progress using included Playbook, Board and Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Get organised and squash all the bugs with this project! Build momentum and measure progress using included Playbook, Board and Channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Don’t miss a step during a product release with this Project. Assign tasks from the Playbook checklist and hit milestones with the Board. Use Channels to keep everyone on the same page." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure issues are resolved and stakeholders informed along the way." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure issues are resolved and stakeholders informed along the way." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "When everything is going wrong, having a repeatable process is the key to making sure everything is made right as quickly as possible. This Project combines everything Mattermost offers to ensure issues are resolved and stakeholders informed along the way." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Clear focus is essential to team success and with this Project you can document the team’s goals and OKRs, as well as post updates in the dedicated channel." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Plan a Roadmap using this Project Board and collaborate on topic in the channel created with this template." - }, { "id": "worktemplate.category.leadership", "translation": "Leadership" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", - "translation": "Company - Wide" + "translation": "Company-wide" }, { "id": "app.worktemplates.execute_work_template.playbooks.find_channel_error", diff --git a/server/i18n/es.json b/server/i18n/es.json index 0e1791f125..6a8f3c43ce 100644 --- a/server/i18n/es.json +++ b/server/i18n/es.json @@ -8975,10 +8975,6 @@ "id": "model.config.is_valid.elastic_search.bulk_indexing_batch_size.app_error", "translation": "El tamaño del lote de indexación masiva de Elasticsearch debe ser al menos de {{.BatchSize}}." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Recibiste este correo electrónico único porque tu servidor Mattermost estuvo inactivo durante más de {{.Hours}} horas. Este correo electrónico fue generado automáticamente por tu servidor Mattermost." - }, { "id": "api.custom_groups.no_remote_id", "translation": " " @@ -8987,10 +8983,6 @@ "id": "app.system.get_onboarding_request.app_error", "translation": "No se pudo obtener el estado de finalización de inducción." }, - { - "id": "Boards", - "translation": " " - }, { "id": "app.custom_group.unique_name", "translation": " " @@ -9059,26 +9051,6 @@ "id": "api.getThreadsForUser.bad_only_params", "translation": " " }, - { - "id": "api.templates.server_inactivity_button", - "translation": " " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "¡Ven y dale un vistazo!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": " " - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hey {{.Name}}, notamos que tu servidor Mattermost está acumulando algo de polvo. Da un vistazo a algunas características que pueden aligerar la carga de trabajo de tu equipo." - }, - { - "id": "api.templates.server_inactivity_title", - "translation": " " - }, { "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "No se pudo obtener todos los jobs por tipo y estado." @@ -9115,14 +9087,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Los ajustes de Búsqueda Elástica tienen valores no establecidos." }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": " " - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "¡Ven y abre Mattermost para aumentar la productividad de tu equipo!" - }, { "id": "api.team.invite_members_to_team_and_channels.invalid_body.app_error", "translation": "Cuerpo de solicitud no válido." @@ -9207,10 +9171,6 @@ "id": "api.templates.invite_team_and_channel_body.title", "translation": "{{ .SenderName }} te invitó a unirte al Canal {{ .ChannelName }} en el Equipo {{ .TeamDisplayName}}" }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": " " - }, { "id": "api.templates.cloud_upgrade_confirmation.title", "translation": "¡Ahora estás actualizado!" @@ -9227,14 +9187,6 @@ "id": "api.team.invite_members.unable_to_send_email_with_defaults.app_error", "translation": " " }, - { - "id": "Playbooks", - "translation": " " - }, - { - "id": "Channels", - "translation": " " - }, { "id": "api.user.authorize_oauth_user.saml_response_too_long.app_error", "translation": " " @@ -9487,10 +9439,6 @@ "id": "app.post.get_top_dms_for_user_since.app_error", "translation": "No es posible obtener los DMs principales para el usuario." }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "El plugin {{.Name}} no se pudo activar en el modo producto." - }, { "id": "app.notify_admin.send_notification_post.app_error", "translation": "No es posible enviar la publicación de notificación." diff --git a/server/i18n/fr.json b/server/i18n/fr.json index 50b5d159c8..77720df20d 100644 --- a/server/i18n/fr.json +++ b/server/i18n/fr.json @@ -8571,34 +8571,6 @@ "id": "api.license.request_renewal_link.cannot_renew_on_cws", "translation": "Le renouvellement de cette licence sur le portail n'est pas possible" }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Bonjour {{.Name}}, nous avons remarqué que votre serveur Mattermost collecte un peu la poussière. Découvrez quelques fonctionnalités qui peuvent vous aider à alléger la charge de travail de votre équipe." - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Gérez des tâches en utilisant " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Venez et regardez ça !" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Ouvrir Mattermost" - }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "Channels" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "app.prepackged-plugin.invalid_version.app_error", "translation": "La version du plugin pré-packagé n'a pas pu être traitée." @@ -8755,26 +8727,6 @@ "id": "api.user.view_archived_channels.get_posts_for_channel.app_error", "translation": "Impossible de retrouver les messages pour un canal archivé" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Augmentez votre productivité en déverrouillant ces fonctionnalités géniales" - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Ouvrez Mattermost pour augmenter la productivité de votre équipe !" - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Gestion du déroulement des opérations avec " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Accès des invités à l'espace spécifié " - }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Vous avez reçu ce courriel unique parce que votre serveur Mattermost est inactif depuis plus de {{.Hours}} heures. Ce courriel a été généré automatiquement par votre serveur Mattermost." - }, { "id": "api.templates.invite_team_and_channels_subject", "translation": "[{{ .SiteName}}] {{ .SenderName }} vous a invité à rejoindre {{ .ChannelsLen }} canaux de l'équipe {{ .TeamDisplayName }}" diff --git a/server/i18n/hu.json b/server/i18n/hu.json index 11194850f6..e66cb9ae7f 100644 --- a/server/i18n/hu.json +++ b/server/i18n/hu.json @@ -9019,50 +9019,6 @@ "id": "app.member_count", "translation": "hiba a tagok számának lekérdezésében" }, - { - "id": "Boards", - "translation": "Táblák" - }, - { - "id": "Channels", - "translation": "Csatornák" - }, - { - "id": "Playbooks", - "translation": "Forgatókönyvek" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Mattermost megnyitása" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Helló {{.Name}}, észrevettük, hogy a Mattermost szervered egy kicsit porosodik. Vess egy pillantást néhány funkcióra, amelyek segíthetnek könnyíteni csapatod munkaterhét." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Nyissa meg a Mattermostot, hogy növelje csapata termelékenységét!" - }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Növelje a termelékenységet ezekkel a fantasztikus funkciókkal" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Feladatok kezelése a " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Munkafolyamatok kezelése a " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Vendég hozzáférés a megadott " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Jöjjön és nézze meg!" - }, { "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "Nem lehet lekérni az összes munkát típus és státusz szerint." @@ -9163,10 +9119,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Az Elasticsearch beállításában nem mentett értékek vannak." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Ezt az egyszeri e-mailt azért kapta, mert a Mattermost szervere több mint {{.Hours}} órán keresztül inaktív volt. Ezt az e-mailt a Mattermost szervere automatikusan generálta." - }, { "id": "api.file.cloud_upload.app_error", "translation": "Az mmctl segítségével történő feltöltés egy felhő alapú példányra nem támogatott. Kérjük, tekintse meg a dokumentációt itt: https://docs.mattermost.com/manage/cloud-data-export.html." diff --git a/server/i18n/it.json b/server/i18n/it.json index 14f201c891..0129b143eb 100644 --- a/server/i18n/it.json +++ b/server/i18n/it.json @@ -7359,14 +7359,6 @@ "id": "api.upgrade_to_enterprise.invalid-user.app_error", "translation": " " }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": " " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": " " - }, { "id": "api.templates.email_footer_v2", "translation": " " @@ -7479,10 +7471,6 @@ "id": "api.command_share.fetch_remote_status.error", "translation": " " }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": " " - }, { "id": "api.templates.invite_team_and_channels_body.title", "translation": " " @@ -7527,10 +7515,6 @@ "id": "api.command_remote.remote_add_remove.help", "translation": " " }, - { - "id": "api.templates.server_inactivity_title", - "translation": " " - }, { "id": "api.templates.invite_team_and_channels_subject", "translation": " " @@ -7863,10 +7847,6 @@ "id": "api.templates.invite_body_guest.subTitle", "translation": " " }, - { - "id": "Playbooks", - "translation": " " - }, { "id": "api.command_custom_status.hint", "translation": " " @@ -8199,10 +8179,6 @@ "id": "api.system.update_notices.clear_failed", "translation": " " }, - { - "id": "api.templates.server_inactivity_info", - "translation": " " - }, { "id": "app.system.complete_onboarding_request.no_first_user", "translation": " " @@ -8211,14 +8187,6 @@ "id": "app.user.get_unread_count.app_error", "translation": " " }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": " " - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": " " - }, { "id": "app.team.join_user_to_team.save_member.conflict.app_error", "translation": " " @@ -8419,18 +8387,10 @@ "id": "model.reaction.is_valid.update_at.app_error", "translation": " " }, - { - "id": "Boards", - "translation": " " - }, { "id": "app.notification.footer.info", "translation": " " }, - { - "id": "api.templates.server_inactivity_button", - "translation": " " - }, { "id": "api.command_share.remote_id_invalid.error", "translation": " " @@ -8499,10 +8459,6 @@ "id": "api.post.send_notification_and_forget.push_comment_on_crt_thread_dm", "translation": " " }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": " " - }, { "id": "import_process.worker.do_job.missing_jsonl", "translation": " " @@ -9231,10 +9187,6 @@ "id": "api.command_custom_status.clear.app_error", "translation": " " }, - { - "id": "Channels", - "translation": " " - }, { "id": "api.admin.add_certificate.parseform.app_error", "translation": " " diff --git a/server/i18n/ja.json b/server/i18n/ja.json index f42157caa1..58aa66d022 100644 --- a/server/i18n/ja.json +++ b/server/i18n/ja.json @@ -8983,18 +8983,6 @@ "id": "api.custom_groups.count_err", "translation": "グループのカウント中にエラーが発生しました" }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "チャンネル" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "model.emoji.system_emoji_name.app_error", "translation": "既存のシステム絵文字名と名前が競合しています。" @@ -9019,38 +9007,6 @@ "id": "app.custom_group.unique_name", "translation": "グループ名が重複しています" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "これらの機能による生産性の向上をアンロックする" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "{{.Name}} さん、あなたのMattermostサーバーが少し埃をかぶっていることに気づきました。チームの作業負荷を軽減するのに役立ついくつかの機能を確認してみてください。" - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Mattermostを開いてチームの生産性を向上しましょう!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "タスク管理のための " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "ワークフロー管理のための " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "ゲストアクセス可能な " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "ぜひご覧ください!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Mattermostを開く" - }, { "id": "api.license_error", "translation": "APIエンドポイントにはライセンスが必要です" @@ -9163,10 +9119,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Elasticsearchの設定に未設定の値があります。" }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "あなたの Mattermost サーバが {{.Hours}} 時間以上アクティブでなかったため、このワンタイム電子メールが送信されました。この電子メールは、Mattermost サーバによって自動的に生成されたものです。" - }, { "id": "app.recent_searches.app_error", "translation": "最近の検索履歴を取得する際にエラーが発生しました" @@ -9499,10 +9451,6 @@ "id": "model.group.name.reserved_name.app_error", "translation": "グループ名は予約語として既に登録されています" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "プラグイン {{.Name}} はプロダクトモードでは有効化できません。" - }, { "id": "app.last_accessible_file.app_error", "translation": "最後にアクセスしたファイルの取得エラー" @@ -9571,10 +9519,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "投稿に対する優先度を取得できませんでした" }, - { - "id": "app.draft.update.app_error", - "translation": "下書きを更新できませんでした。" - }, { "id": "app.draft.save.app_error", "translation": "下書きを保存できませんでした。" @@ -9655,22 +9599,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "アーカイブされたチャンネルでは、確認応答を削除することはできません。" }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "開発チーム間で透明性の高いワークフローを作成し、機能開発プロセスをシームレスにすることができます。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Jira BotやGitHub Botと統合し、生産性を高めましょう。これらはあなたのためにダウンロードされます。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Boards、Playbooks、Botと簡単に接続できる Feature Release チャンネルでチームとチャットできます。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "スタンドアップなどの定期的なミーティングには Meeting Agenda Boardテンプレート、タスクの進捗管理には Project Task Boardをご利用ください。" - }, { "id": "worktemplate.category.product_teams", "translation": "製品チーム" @@ -9747,121 +9675,13 @@ "id": "api.license.true_up_review.user_count_fail", "translation": "総アクティブユーザー数を取得できませんでした" }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "プロジェクトを使うことでスプリント計画が楽になります。チャンネルは会話と質問に集中することができます。スプリント計画では、全員がその週のタスクに集中し、レトロスペクティブBoardでチームが一丸となって継続的に改善することができます。" - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "プロジェクトを使うことでスプリント計画が楽になります。チャンネルは会話と質問に集中することができます。スプリント計画では、全員がその週のタスクに集中し、レトロスペクティブBoardでチームが一丸となって継続的に改善することができます。" - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "プロジェクトを使うことでスプリント計画が楽になります。チャンネルは会話と質問に集中することができます。スプリント計画では、全員がその週のタスクに集中し、レトロスペクティブBoardでチームが一丸となって継続的に改善することができます。" - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "チャンネルが必要な理由について" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Boardが必要な理由について" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "このプロジェクトで、すべてのバグに対応しましょう! Playbook、Board、Channelを使ってテンポ良く仕事を進めましょう。" - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "このプロジェクトで、すべてのバグに対応しましょう! Playbook、Board、Channelを使ってテンポ良く仕事を進めましょう。" - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "このプロジェクトで、すべてのバグに対応しましょう! Playbook、Board、Channelを使ってテンポ良く仕事を進めましょう。" - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "このプロジェクトで、すべてのバグに対応しましょう! Playbook、Board、Channelを使ってテンポ良く仕事を進めましょう。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "このプロジェクトで、製品リリース時の手順を見落とさないようにしましょう。Playbookのチェックリストからタスクを割り当て、Boardと共にマイルストーンを達成し、チャンネルを使用して全員が同じ情報を目にできるようにしましょう。" - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "このプロジェクトで、製品リリース時の手順を見落とさないようにしましょう。Playbookのチェックリストからタスクを割り当て、Boardと共にマイルストーンを達成し、チャンネルを使用して全員が同じ情報を目にできるようにしましょう。" - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "このプロジェクトで、製品リリース時の手順を見落とさないようにしましょう。Playbookのチェックリストからタスクを割り当て、Boardと共にマイルストーンを達成し、チャンネルを使用して全員が同じ情報を目にできるようにしましょう。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "すべてがうまくいかないとき、再現可能なプロセスを用意することは、正しい方向へ導くためのキーとなります。このプロジェクトは、Mattermostが提供するあらゆるものを組み合わせて、炎上を抑え、利害関係者に正しく情報を提供するものです。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "すべてがうまくいかないとき、再現可能なプロセスを用意することは、正しい方向へ導くためのキーとなります。このプロジェクトは、Mattermostが提供するあらゆるものを組み合わせて、炎上を抑え、利害関係者に正しく情報を提供するものです。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "すべてがうまくいかないとき、再現可能なプロセスを用意することは、正しい方向へ導くためのキーとなります。このプロジェクトは、Mattermostが提供するあらゆるものを組み合わせて、炎上を抑え、利害関係者に正しく情報を提供するものです。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "チームの成功には明確な焦点が必要です。このプロジェクトでは、専用のチャンネルに更新状況を投稿することで、チームの目標やOKRを文書化することができます。" - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "このProject Boardを使用してロードマップを計画し、このテンプレートで作成されたチャンネルでトピックについてコラボレーションを行うことができます。" - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "このProject Boardを使用してロードマップを計画し、このテンプレートで作成されたチャンネルでトピックについてコラボレーションを行うことができます。" - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "このProject Boardを使用してロードマップを計画し、このテンプレートで作成されたチャンネルでトピックについてコラボレーションを行うことができます。" - }, { "id": "worktemplate.category.leadership", "translation": "リーダーシップ" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", diff --git a/server/i18n/ko.json b/server/i18n/ko.json index 6e71b18d58..ddd30b9753 100644 --- a/server/i18n/ko.json +++ b/server/i18n/ko.json @@ -7859,10 +7859,6 @@ "id": "bleveengine.delete_post_files.error", "translation": "게시된 파일을 삭제하지 못했습니다." }, - { - "id": "Boards", - "translation": "보드" - }, { "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Elasticsearch 설정에 설정되지 않은 값이 있습니다." @@ -7887,14 +7883,6 @@ "id": "api.cloud.notify_admin_to_upgrade_error.already_notified", "translation": "이미 관리자에게 통지됨" }, - { - "id": "Playbooks", - "translation": "플레이북" - }, - { - "id": "Channels", - "translation": "채널" - }, { "id": "api.custom_groups.feature_disabled", "translation": "사용자 정의 그룹 기능은 비활성화되어 있습니다" @@ -8106,5 +8094,337 @@ { "id": "api.config.update_config.translations.app_error", "translation": "서버 번역 업데이트가 실패하였습니다." + }, + { + "id": "api.user.create_user.bad_token_email_data.app_error", + "translation": "토큰의 전자우편 주소가 사용자 데이터의 전자우편 주소와 일치하지 않습니다." + }, + { + "id": "api.user.authorize_oauth_user.saml_response_too_long.app_error", + "translation": "SAML 응답이 너무 깁니다" + }, + { + "id": "api.user.add_user_to_group_syncables.not_ldap_user.app_error", + "translation": "LDAP 사용자가 아님" + }, + { + "id": "api.upload.upload_data.multipart_error", + "translation": "멀티파트 데이터를 처리하지 못했습니다." + }, + { + "id": "api.upload.upload_data.invalid_content_type", + "translation": "멀티파트 업로드에 대한 Content-Type이 잘못되었습니다." + }, + { + "id": "api.upload.upload_data.invalid_content_length", + "translation": "유효하지 않은 Content-Length입니다." + }, + { + "id": "api.upload.get_upload.forbidden.app_error", + "translation": "업로드에 실패했습니다." + }, + { + "id": "api.upload.create.upload_too_large.app_error", + "translation": "파일을 업로드할 수 없습니다. 파일이 너무 큽니다." + }, + { + "id": "api.unable_to_read_file_from_backend", + "translation": "백엔드에서 파일 읽기 오류" + }, + { + "id": "api.templates.welcome_body.subTitle2", + "translation": "아래를 클릭하여 전자우편 주소를 인증하세요." + }, + { + "id": "api.templates.welcome_body.info1", + "translation": "수신자가 당신이 아닌 경우, 이 전자우편은 무시해도 됩니다." + }, + { + "id": "api.templates.verify_body.subTitle2", + "translation": "아래를 클릭하여 전자우편 주소를 인증하세요." + }, + { + "id": "api.templates.verify_body.subTitle1", + "translation": "참여해 주셔서 감사합니다 " + }, + { + "id": "api.templates.verify_body.serverURL", + "translation": "{{ .ServerURL }}." + }, + { + "id": "api.templates.verify_body.info1", + "translation": "수신자가 당신이 아닌 경우, 이 전자우편은 무시해도 됩니다." + }, + { + "id": "api.templates.reset_body.subTitle", + "translation": "비밀번호를 재설정하려면 아래 버튼을 클릭하세요. 요청하지 않은 경우 이 전자우편은 무시해도 됩니다." + }, + { + "id": "api.templates.reset_body.info", + "translation": "비밀번호 재설정 링크는 24시간 후에 만료됩니다." + }, + { + "id": "api.templates.questions_footer.title", + "translation": "질문이 있으신가요?" + }, + { + "id": "api.templates.questions_footer.info", + "translation": "도움이 필요하거나 질문이 있으신가요? 다음 주소로 전자우편을 보내주세요 " + }, + { + "id": "api.templates.payment_failed_no_card.title", + "translation": "Mattermost Cloud 청구서 마감일" + }, + { + "id": "api.templates.payment_failed_no_card.subject", + "translation": "Mattermost Cloud 구독에 대한 결제가 완료되었습니다" + }, + { + "id": "api.templates.payment_failed_no_card.info3", + "translation": "청구서를 검토하고 결제 방법을 추가하려면 지금 결제를 선택합니다." + }, + { + "id": "api.templates.payment_failed_no_card.info1", + "translation": "가장 최근 청구 기간에 대한 Mattermost Cloud 청구서가 처리되었습니다. 하지만 결제 세부 정보가 등록되어 있지 않습니다." + }, + { + "id": "api.templates.payment_failed_no_card.button", + "translation": "지금 결제하기" + }, + { + "id": "api.templates.payment_failed.title", + "translation": "결제가 성공하지 못했습니다" + }, + { + "id": "api.templates.payment_failed.info2", + "translation": "그들은 다음과 같은 이유를 제시했습니다:" + }, + { + "id": "api.templates.license_up_for_renewal_title", + "translation": "Mattermost 구독이 갱신될 예정입니다" + }, + { + "id": "api.templates.license_up_for_renewal_subtitle_two", + "translation": "갱신하려면 고객 계정으로 로그인하세요" + }, + { + "id": "api.templates.license_up_for_renewal_subject", + "translation": "라이선스 갱신 기간 만료" + }, + { + "id": "api.templates.license_up_for_renewal_contact_sales", + "translation": "영업팀에 문의" + }, + { + "id": "api.templates.invite_body_guest.subTitle", + "translation": "팀과의 공동 작업을 위해 게스트로 초대되었습니다" + }, + { + "id": "api.templates.invite_body_footer.info", + "translation": "Mattermost는 안전한 팀 협업을 지원하는 유연한 오픈소스 메시징 플랫폼입니다." + }, + { + "id": "api.templates.email_us_anytime_at", + "translation": "언제든지 다음 주소로 전자우편을 보내주세요 " + }, + { + "id": "api.templates.delinquency_90.title", + "translation": "Mattermost 워크스페이스가 다운그레이드되었습니다" + }, + { + "id": "api.templates.delinquency_90.subtitle2", + "translation": "또한 Cloud Free 제한으로 인해 데이터가 보관 처리되었을 수도 있습니다." + }, + { + "id": "api.templates.delinquency_90.subtitle3", + "translation": "데이터 보관을 해제하고 유료 기능을 계속 사용하려면 결제 정보를 업데이트하세요." + }, + { + "id": "api.templates.delinquency_90.subtitle1", + "translation": "중요한 비즈니스 운영에 Cloud Professional 또는 Enterprise 기능을 사용하는 경우 이러한 기능을 더 이상 사용할 수 없으며 성능이 저하됩니다." + }, + { + "id": "api.templates.delinquency_90.subject", + "translation": "Mattermost Cloud 워크스페이스가 다운그레이드되었습니다" + }, + { + "id": "api.templates.delinquency_90.secondary_action_button", + "translation": "플랜과 가격 보기" + }, + { + "id": "api.templates.delinquency_75.subtitle3", + "translation": "지금 결제 정보를 업데이트하거나 Cloud Free로 다운그레이드하세요." + }, + { + "id": "api.templates.delinquency_75.title", + "translation": "워크스페이스가 15일 후에 다운그레이드됩니다" + }, + { + "id": "api.templates.delinquency_90.button", + "translation": "결제 갱신" + }, + { + "id": "api.templates.delinquency_75.subject", + "translation": "Mattermost {{.Plan}} 플랜이 15일 후에 다운그레이드됩니다" + }, + { + "id": "api.templates.delinquency_75.downgrade_to_free", + "translation": "Cloud Free로 다운그레이드" + }, + { + "id": "api.templates.delinquency_75.button", + "translation": "결제 갱신" + }, + { + "id": "api.templates.delinquency_7.title", + "translation": "결제가 완료되지 않았습니다" + }, + { + "id": "api.templates.delinquency_7.subtitle1", + "translation": "가장 최근 결제를 처리하지 못했습니다." + }, + { + "id": "api.templates.delinquency_7.button", + "translation": "결제 갱신" + }, + { + "id": "api.templates.delinquency_60.title", + "translation": "Mattermost 워크스페이스가 30일 후에 다운그레이드됩니다" + }, + { + "id": "api.templates.delinquency_30.limits_documentation", + "translation": "모든 제한 문서 보기." + }, + { + "id": "api.templates.delinquency_30.button", + "translation": "결제 갱신" + }, + { + "id": "api.templates.delinquency_30.bullet.message_history", + "translation": "메시지 역사" + }, + { + "id": "api.templates.delinquency_30.bullet.files", + "translation": "파일" + }, + { + "id": "api.server.warn_metric.number_of_posts_2M.notification_title", + "translation": "성능 향상" + }, + { + "id": "api.server.warn_metric.number_of_teams_5.notification_title", + "translation": "고급 권한 사용 중" + }, + { + "id": "api.server.warn_metric.number_of_teams_5.start_trial_notification_success.message", + "translation": "엔터프라이즈 체험판이 활성화되었습니다. **시스템 콘솔 > 사용자 관리 > 권한** 에서 고급 권한 설정을 활성화하세요." + }, + { + "id": "api.system.logs.invalidFilter", + "translation": "유효하지 않은 로그 필터" + }, + { + "id": "api.team.add_team_member.invalid_body.app_error", + "translation": "요청 본문을 구문 분석할 수 없습니다." + }, + { + "id": "api.team.import_team.unknown_import_from.app_error", + "translation": "알 수 없는 들여오기 원본입니다." + }, + { + "id": "api.team.invite_guests_to_channels.disabled.error", + "translation": "게스트 계정이 비활성화되었습니다" + }, + { + "id": "api.team.invite_guests_to_channels.invalid_body.app_error", + "translation": "요청 본문이 유효하지 않거나 누락되었습니다." + }, + { + "id": "api.team.invite_guests_to_channels.license.error", + "translation": "게스트 계정을 지원하지 않는 라이선스입니다" + }, + { + "id": "api.team.invite_members.unable_to_send_email.app_error", + "translation": "전자우편을 보내는 중에 오류가 발생했습니다" + }, + { + "id": "api.team.invite_members.unable_to_send_email_with_defaults.app_error", + "translation": "시스템 콘솔에서 SMTP가 설정되지 않았습니다" + }, + { + "id": "api.team.invite_members_to_team_and_channels.invalid_body.app_error", + "translation": "유효하지 않은 요청 본문입니다." + }, + { + "id": "api.team.invite_members_to_team_and_channels.invalid_body_parsing.app_error", + "translation": "본문 데이터를 구문 분석하는 동안 오류가 발생했습니다." + }, + { + "id": "api.team.set_team_icon.check_image_limits.app_error", + "translation": "이미지 제한 확인에 실패했습니다. 해상도가 너무 높습니다." + }, + { + "id": "api.templates.cloud_upgrade_confirmation.subject", + "translation": "Mattermots 업그레이드 확인" + }, + { + "id": "api.templates.cloud_upgrade_confirmation.title", + "translation": "업그레이드 되었습니다!" + }, + { + "id": "api.templates.cloud_upgrade_confirmation_monthly.subtitle", + "translation": "{{.WorkspaceName}} 워크스페이스가 업그레이드 되었습니다. {{.Data}}에 결제가 됩니다" + }, + { + "id": "api.templates.cloud_upgrade_confirmation_yearly.subtitle", + "translation": "{{.WorkspaceName}} 워크스페이스가 업그레이드 되었습니다." + }, + { + "id": "api.templates.cloud_welcome_email.add_apps_info", + "translation": "워크스페이스에 앱들을 추가합니다" + }, + { + "id": "api.templates.cloud_welcome_email.app_market_place", + "translation": "앱 마켓플레이스." + }, + { + "id": "api.templates.cloud_welcome_email.button", + "translation": "매터모스트 열기" + }, + { + "id": "api.license.request-trial.can-start-trial.error", + "translation": "평가판을 시작할 수 있는지 확인할 수 없습니다" + }, + { + "id": "api.file.test_connection_s3_settings_nil.app_error", + "translation": "파일 저장소 설정에 설정되지 않은 값이 있습니다." + }, + { + "id": "api.error_set_first_admin_visit_marketplace_status", + "translation": "스토어에 초기 관리자 마켓플레이스 방문 상태를 저장하는 동안 오류가 발생했습니다." + }, + { + "id": "api.command_templates.unsupported.app_error", + "translation": "이 장치에서는 템플릿 명령이 지원되지 않습니다." + }, + { + "id": "api.command_templates.name", + "translation": "템플릿" + }, + { + "id": "api.command_templates.desc", + "translation": "템플릿에서 만들기 창을 엽니다" + }, + { + "id": "api.acknowledgement.save.archived_channel.app_error", + "translation": "보관된 채널에서는 승인할 수 없습니다." + }, + { + "id": "api.acknowledgement.delete.deadline.app_error", + "translation": "5분이 경과한 후에는 확인을 삭제할 수 없습니다." + }, + { + "id": "api.acknowledgement.delete.archived_channel.app_error", + "translation": "보관된 채널에서는 승인 내용을 삭제할 수 없습니다." } ] diff --git a/server/i18n/nl.json b/server/i18n/nl.json index a4e634b187..95097c7095 100644 --- a/server/i18n/nl.json +++ b/server/i18n/nl.json @@ -9026,50 +9026,6 @@ "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "Het lukt niet om alle jobs op type en status op te halen." }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Verhoog jouw productiviteit met deze geweldige functies" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hey {{.Naam}}, we hebben gemerkt dat jouw Mattermost server een beetje stof aan het verzamelen is. Kijk eens naar enkele functies die kunnen helpen om de werklast van jouw team te verlichten." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Open Mattermost om de productiviteit van je team te verhogen!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Beheer taken met " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Workflowbeheer met " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Gast-toegang tot gespecificeerd(e) " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Kom maar eens kijken!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Mattermost openen" - }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "Kanalen" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "api.team.invite_members.unable_to_send_email_with_defaults.app_error", "translation": "SMTP is niet geconfigureerd in Systeem Console" @@ -9162,10 +9118,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "De instellingen van Elasticsearch bevat niet-ingestelde waarden." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Je hebt deze eenmalige email ontvangen omdat jouw Mattermost server inactief was voor meer dan {{.Hours}} uur. Deze e-mail werd automatisch aangemaakt door jouw Mattermost server." - }, { "id": "api.templates.cloud_upgrade_confirmation.title", "translation": "Je bent nu geüpgraded!" @@ -9502,10 +9454,6 @@ "id": "model.group.name.reserved_name.app_error", "translation": "groepsnaam bestaat al als een gereserveerde naam" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Plugin {{.Name}} kan niet worden ingeschakeld in de productmodus." - }, { "id": "app.last_accessible_file.app_error", "translation": "Fout bij het ophalen van het laatst toegankelijke bestand" @@ -9554,22 +9502,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Je kan een bevestiging in een gearchiveerd kanaal niet verwijderen." }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Creëer transparante workflows tussen ontwikkelingsteams om ervoor te zorgen dat jouw ontwikkelingsproces naadloos verloopt." - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Verhoog de productiviteit in je kanaal door een Jira bot en Github bot te integreren. Deze worden voor jou gedownload." - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Chat met je team in een Feature Release-kanaal dat gemakkelijk verbinding maakt met je boards, playbooks en app bots." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Gebruik ons vergaderagenda-bord voor terugkerende vergaderingen zoals stand-up en ons Projecttakenbord om de voortgang van taken onderweg te beheren." - }, { "id": "worktemplate.category.product_teams", "translation": "Productteams" @@ -9630,10 +9562,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Kon geen berichtprioriteit ophalen voor bericht" }, - { - "id": "app.draft.update.app_error", - "translation": "Kan het concept niet bijwerken." - }, { "id": "app.draft.save.app_error", "translation": "Kan het concept niet opslaan." @@ -9774,73 +9702,13 @@ "id": "api.config.update_config.translations.app_error", "translation": "Fout bij het bijwerken van de serververtalingen." }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Organiseer en versla alle bugs met dit project! Bouw momentum op en meet de voortgang met behulp van het meegeleverde Playbook, Board en Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Organiseer en versla alle bugs met dit project! Bouw momentum op en meet de voortgang met behulp van het meegeleverde Playbook, Board en Channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Mis geen stap tijdens een productrelease met dit Project. Wijs taken toe uit de Playbook-checklist en bereik mijlpalen met het Board. Gebruik Channels om iedereen op één lijn te houden." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Mis geen stap tijdens een productrelease met dit Project. Wijs taken toe uit de Playbook-checklist en bereik mijlpalen met het Board. Gebruik Channels om iedereen op één lijn te houden." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Mis geen stap tijdens een productrelease met dit Project. Wijs taken toe uit de Playbook-checklist en bereik mijlpalen met het Board. Gebruik Channels om iedereen op dezelfde lijn te houden." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "Wanneer alles fout gaat, is een herhaalbaar proces de sleutel om ervoor te zorgen dat alles zo snel mogelijk in orde komt. Dit project combineert alles wat Mattermost biedt om ervoor te zorgen dat de brandjes worden geblust en de belanghebbenden onderweg worden geïnformeerd." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "Wanneer alles fout gaat, is een herhaalbaar proces de sleutel om ervoor te zorgen dat alles zo snel mogelijk in orde komt. Dit project combineert alles wat Mattermost biedt om ervoor te zorgen dat de brandjes worden geblust en de belanghebbenden onderweg worden geïnformeerd." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Plan een Roadmap met behulp van dit Project Board en werk op dit onderwerp samen in het kanaal dat met dit sjabloon is aangemaakt." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Plan een Roadmap met behulp van dit Project Board en werk op dit onderwerp samen in het kanaal dat met dit sjabloon is aangemaakt." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Plan een Roadmap met behulp van dit Project Board en werk op dit onderwerp samen in het kanaal dat met dit sjabloon is aangemaakt." - }, { "id": "worktemplate.category.leadership", "translation": "Leiderschap" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", @@ -9906,58 +9774,6 @@ "id": "api.work_templates.disabled", "translation": "Werksjablonen zijn uitgeschakeld." }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Organiseer en versla alle bugs met dit project! Bouw momentum op en meet de voortgang met behulp van het meegeleverde Playbook, Board en Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Organiseer en versla alle bugs met dit project! Bouw momentum op en meet de voortgang met behulp van het meegeleverde Playbook, Board en Channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "Wanneer alles fout gaat, is een herhaalbaar proces de sleutel om ervoor te zorgen dat alles zo snel mogelijk in orde komt. Dit project combineert alles wat Mattermost biedt om ervoor te zorgen dat de brandjes worden geblust en de belanghebbenden onderweg worden geïnformeerd." - }, - { - "id": "api.server.cws.needs_enterprise_edition", - "translation": "Alleen beschikbaar in Mattermost Enterprise editie" - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Gebruik een Project om sprintplanning een makkie te maken. Het kanaal houdt het gesprek en de vragen gefocust. Het sprintplan houdt iedereen op zijn taak voor de week en het Terugblikboard brengt het team samen om voortdurend te verbeteren." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Gebruik een Project om sprintplanning een makkie te maken. Het kanaal houdt het gesprek en de vragen gefocust. Het sprintplan houdt iedereen op zijn taak voor de week en het Terugblikboard brengt het team samen om voortdurend te verbeteren." - }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Gebruik een Project om sprintplanning een makkie te maken. Het kanaal houdt het gesprek en de vragen gefocust. Het sprintplan houdt iedereen op zijn taak voor de week en het Terugblikboard brengt het team samen om voortdurend te verbeteren." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Beschrijving van waarom het kanaal of de kanalen nodig zijn" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Beschrijving van waarom het bord of de borden nodig zijn" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit Project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Duidelijke focus is essentieel voor teamsucces en met dit Project kan je de doelstellingen en OKR's van het team documenteren en updates plaatsen in het toegewezen kanaal." - }, { "id": "api.command_templates.unsupported.app_error", "translation": "De sjablonenopdracht wordt niet ondersteund op jouw toestel." diff --git a/server/i18n/pl.json b/server/i18n/pl.json index 9049ed5e57..339c00b48b 100644 --- a/server/i18n/pl.json +++ b/server/i18n/pl.json @@ -9023,50 +9023,6 @@ "id": "api.custom_groups.count_err", "translation": "błąd liczenia grup" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Odblokuj zwiększoną produktywność dzięki tym wspaniałym funkcjom" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hej {{.Name}}, zauważyliśmy, że twój serwer Mattermost zbiera trochę kurzu. Zapoznaj się z kilkoma funkcjami, które pomogą odciążyć Twój zespół." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Otwórz Mattermost, aby zwiększyć produktywność swojego zespołu!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Zarządzaj zadaniami za pomocą " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Zarządzanie przepływem pracy z " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Dostęp gości do określenia " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Przyjdź i sprawdź to!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Otwórz Mattermost" - }, - { - "id": "Playbooks", - "translation": "Playbooki" - }, - { - "id": "Channels", - "translation": "Kanały" - }, - { - "id": "Boards", - "translation": "Tablice" - }, { "id": "model.oauth.is_valid.mattermost_app_id.app_error", "translation": "Maksymalna długość identyfikatora MattermostAppID wynosi 32 znaki." @@ -9171,10 +9127,6 @@ "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Ustawienia Elasticsearch mają nieustawione wartości." }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Otrzymałeś tę jednorazową wiadomość e-mail, ponieważ Twój serwer Mattermost był nieaktywny przez ponad {{.Hours}} godzin. Ta wiadomość e-mail została automatycznie wygenerowana przez serwer Mattermost." - }, { "id": "api.file.cloud_upload.app_error", "translation": "Przesyłanie danych do instancji Chmury za pomocą mmctl nie jest obsługiwane. Proszę sprawdzić dokumentację tutaj: https://docs.mattermost.com/manage/cloud-data-export.html." @@ -9511,10 +9463,6 @@ "id": "model.group.name.reserved_name.app_error", "translation": "nazwa grupy już istnieje jako nazwa zastrzeżona" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Wtyczka {{.Name}} nie może być włączona w trybie produktu." - }, { "id": "api.team.invite_guests_to_channels.license.error", "translation": "Twoja licencja nie wspiera kont gości" @@ -9591,10 +9539,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Nie można uzyskać priorytetu dla posta" }, - { - "id": "app.draft.update.app_error", - "translation": "Nie można zaktualizować szkicu." - }, { "id": "app.draft.save.app_error", "translation": "Nie można zapisać Szkicu." @@ -9663,22 +9607,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Nie można usunąć potwierdzenia w zarchiwizowanym kanale." }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Twórz przejrzyste przepływy pracy pomiędzy zespołami programistów, aby zapewnić płynny proces rozwoju funkcji." - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Zwiększ wydajność na swoim kanale, integrując bota Jira i bota Github. Zostaną one pobrane za Ciebie." - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Czatuj ze swoim zespołem na kanale Feature Release, który łatwo łączy się z tablicami, playbookami i botami aplikacji." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Użyj naszego szablonu tablicy Meeting Agenda do powtarzających się spotkań, takich jak standup, oraz naszej tablicy Project Tasks do zarządzania postępem zadań w trakcie." - }, { "id": "worktemplate.category.product_teams", "translation": "Zespoły Produkcyjne" @@ -9775,81 +9703,13 @@ "id": "app.group.username_conflict", "translation": "użytkownik o nazwie \"{{.Username}}\" już istnieje." }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Zorganizuj się i pokonaj wszystkie błędy dzięki temu projektowi! Zbuduj tempo i mierz postępy dzięki dołączonemu Playbookowi, tablicy i kanałowi." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Zorganizuj się i pokonaj wszystkie błędy dzięki temu projektowi! Zbuduj tempo i mierz postępy dzięki dołączonemu Playbookowi, tablicy i kanałowi." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Nie przegap żadnego kroku podczas wydania produktu dzięki temu projektowi. Przydziel zadania z listy kontrolnej Playbooka i uderzaj w kamienie milowe z tablicą. Użyj kanałów, aby wszyscy byli na tej samej stronie." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Nie przegap żadnego kroku podczas wydania produktu dzięki temu projektowi. Przydziel zadania z listy kontrolnej Playbooka i uderzaj w kamienie milowe z tablicą. Użyj kanałów, aby wszyscy byli na tej samej stronie." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Nie przegap żadnego kroku podczas wydania produktu dzięki temu projektowi. Przydziel zadania z listy kontrolnej Playbooka i uderzaj w kamienie milowe z tablicą. Użyj kanałów, aby wszyscy byli na tej samej stronie." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "Kiedy wszystko idzie nie tak, posiadanie powtarzalnego procesu jest kluczem do zapewnienia, że wszystko zostanie naprawione tak szybko, jak to możliwe. Ten projekt łączy w sobie wszystko, co oferuje Mattermost, aby zapewnić gaszenie pożarów i informowanie zainteresowanych stron po drodze." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "Kiedy wszystko idzie nie tak, posiadanie powtarzalnego procesu jest kluczem do zapewnienia, że wszystko zostanie naprawione tak szybko, jak to możliwe. Ten projekt łączy w sobie wszystko, co oferuje Mattermost, aby zapewnić gaszenie pożarów i informowanie zainteresowanych stron po drodze." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "Kiedy wszystko idzie nie tak, posiadanie powtarzalnego procesu jest kluczem do zapewnienia, że wszystko zostanie naprawione tak szybko, jak to możliwe. Ten projekt łączy w sobie wszystko, co oferuje Mattermost, aby zapewnić gaszenie pożarów i informowanie zainteresowanych stron po drodze." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Zaplanuj mapę drogową za pomocą tej tablicy projektów i współpracuj na temat w kanale utworzonym za pomocą tego szablonu." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Zaplanuj mapę drogową za pomocą tej tablicy projektów i współpracuj na temat w kanale utworzonym za pomocą tego szablonu." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Zaplanuj mapę drogową za pomocą tej tablicy projektów i współpracuj na temat w kanale utworzonym za pomocą tego szablonu." - }, { "id": "worktemplate.category.leadership", "translation": "Przywództwo" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", @@ -9911,46 +9771,6 @@ "id": "api.config.update_config.translations.app_error", "translation": "Nie udało się zaktualizować tłumaczeń serwera." }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Użyj Projektu, aby planowanie sprintu było proste. Kanał utrzymuje rozmowę i pytania w centrum uwagi. Plan sprintu utrzymuje wszystkich na zadaniach na dany tydzień, a tablica retrospektywna łączy zespół w celu ciągłego doskonalenia." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Użyj Projektu, aby planowanie sprintu było proste. Kanał utrzymuje rozmowę i pytania w centrum uwagi. Plan sprintu utrzymuje wszystkich na zadaniach na dany tydzień, a tablica retrospektywna łączy zespół w celu ciągłego doskonalenia." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Użyj Projektu, aby planowanie sprintu było proste. Kanał utrzymuje rozmowę i pytania w centrum uwagi. Plan sprintu utrzymuje wszystkich na zadaniach na dany tydzień, a tablica retrospektywna łączy zespół w celu ciągłego doskonalenia." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Opis, dlaczego kanał(y) jest(są) potrzebny(e)" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Opis powodów, dla których tablica(e) jest(są) potrzebna(e)" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Jasna koncentracja jest niezbędna dla sukcesu zespołu, a dzięki temu projektowi możesz udokumentować cele zespołu i OKR, a także zamieszczać aktualizacje w dedykowanym kanale." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Zorganizuj się i pokonaj wszystkie błędy dzięki temu projektowi! Zbuduj tempo i mierz postępy dzięki dołączonemu Playbookowi, tablicy i kanałowi." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Zorganizuj się i pokonaj wszystkie błędy dzięki temu projektowi! Zbuduj tempo i mierz postępy dzięki dołączonemu Playbookowi, tablicy i kanałowi." - }, { "id": "app.import.validate_user_teams_import_data.invalid_auth_service.error", "translation": "Nieprawidłowy serwis autentykacji: {{.AuthService}}" @@ -10038,5 +9858,197 @@ { "id": "app.command.execute.error", "translation": "Nie można wykonać polecenia." + }, + { + "id": "app.user.digest.runs_in_progress.zero_in_progress", + "translation": "Obecnie masz 0 uruchomień w trakcie." + }, + { + "id": "app.user.digest.tasks.all_tasks_command", + "translation": "Użyj `/playbook todo`, aby zobaczyć wszystkie swoje zadania." + }, + { + "id": "app.user.digest.tasks.heading", + "translation": "Twoje przydzielone zadania" + }, + { + "id": "app.user.digest.tasks.zero_assigned", + "translation": "Masz 0 przydzielonych zadań." + }, + { + "id": "app.user.new_run.run_name", + "translation": "Nazwa uruchomienia" + }, + { + "id": "app.user.new_run.title", + "translation": "Uruchom playbook" + }, + { + "id": "app.user.run.add_checklist_item.description", + "translation": "Opis" + }, + { + "id": "app.user.run.add_checklist_item.name", + "translation": "Nazwa" + }, + { + "id": "app.user.run.add_checklist_item.submit_label", + "translation": "Dodaj zadanie" + }, + { + "id": "app.user.run.add_checklist_item.title", + "translation": "Dodaj nowe zadanie" + }, + { + "id": "app.user.run.add_to_timeline.playbook_run", + "translation": "Uruchomienie Playbooka" + }, + { + "id": "app.user.run.add_to_timeline.submit_label", + "translation": "Dodaj do osi czasu uruchomienia" + }, + { + "id": "app.user.run.add_to_timeline.summary", + "translation": "Podsumowanie" + }, + { + "id": "app.user.run.add_to_timeline.summary.help", + "translation": "Maksymalnie 64 znaki" + }, + { + "id": "app.user.run.add_to_timeline.summary.placeholder", + "translation": "Krótkie podsumowanie widoczne na osi czasu" + }, + { + "id": "app.user.run.update_status.finish_run", + "translation": "Zakończ uruchomienie" + }, + { + "id": "app.user.run.update_status.finish_run.placeholder", + "translation": "Oznacz również uruchomienie jako zakończone" + }, + { + "id": "app.user.run.update_status.reminder_for_next_update", + "translation": "Przypomnienie o następnej aktualizacji" + }, + { + "id": "app.user.run.update_status.submit_label", + "translation": "Status aktualizacji" + }, + { + "id": "app.user.digest.runs_in_progress.num_in_progress", + "translation": { + "few": "Masz {{.Count}} uruchomienia w toku:", + "many": "Masz {{.Count}} uruchomień w toku:", + "one": "Masz {{.Count}} uruchomienie w toku:" + } + }, + { + "id": "app.user.digest.tasks.due_in_x_days", + "translation": { + "few": "Termin płatności za {{.Count}} dni", + "many": "Termin płatności za {{.Count}} dni", + "one": "Termin płatności za {{.Count}} dzień" + } + }, + { + "id": "app.user.digest.tasks.due_after_today", + "translation": { + "few": "Masz **{{.Count}} przydzielone zadania, których termin wykonania wypada po dzisiejszym dniu**.", + "many": "Masz **{{.Count}} przydzielonych zadań, których termin wykonania wypada po dzisiejszym dniu**.", + "one": "Masz **{{.Count}} przydzielone zadanie, którego termin wykonania wypada po dzisiejszym dniu**." + } + }, + { + "id": "app.user.digest.tasks.due_today", + "translation": "Do zapłaty dzisiaj" + }, + { + "id": "app.user.digest.tasks.due_x_days_ago", + "translation": "Termin {{.Count}} dni temu" + }, + { + "id": "app.user.digest.tasks.num_assigned", + "translation": { + "few": "Masz {{.Count}} przydzielone zadania:", + "many": "Masz {{.Count}} przydzielonych zadań:", + "one": "Masz {{.Count}} przydzielone zadanie:" + } + }, + { + "id": "app.user.digest.tasks.num_assigned_due_until_today", + "translation": { + "few": "Masz {{.Count}} przydzielone zadania, których termin wykonania właśnie upływa:", + "many": "Masz {{.Count}} przydzielonych zadań, których termin wykonania właśnie upływa:", + "one": "Masz {{.Count}} przydzielone zadanie, którego termin wykonania właśnie upływa:" + } + }, + { + "id": "app.user.new_run.intro", + "translation": "**Właściciel** {{.Username}}" + }, + { + "id": "app.user.new_run.playbook", + "translation": "Playbook" + }, + { + "id": "app.user.new_run.submit_label", + "translation": "Rozpocznij uruchomienie" + }, + { + "id": "app.user.run.confirm_finish.num_outstanding", + "translation": { + "few": "Są **{.Count}} zaległe zadania**. Czy na pewno chcesz zakończyć uruchomienie *{.RunName}}* dla wszystkich uczestników?", + "many": "Jest **{.Count}} zaległych zadań**. Czy na pewno chcesz zakończyć uruchomienie *{.RunName}}* dla wszystkich uczestników?", + "one": "Jest **{.Count}} zaległe zadanie**. Czy na pewno chcesz zakończyć uruchomienie *{.RunName}}* dla wszystkich uczestników?" + } + }, + { + "id": "app.user.run.update_status.num_channel", + "translation": { + "few": "Przedstaw aktualizację dla interesariuszy. Ten post będzie transmitowany na {{.Count}} kanałach.", + "many": "Przedstaw aktualizację dla interesariuszy. Ten post będzie transmitowany na {{.Count}} kanałach.", + "one": "Przedstaw aktualizację dla interesariuszy. Ten post będzie transmitowany na {{.Count}} kanale." + } + }, + { + "id": "app.user.run.update_status.title", + "translation": "Aktualizacje statusu" + }, + { + "id": "app.user.digest.tasks.due_yesterday", + "translation": "Termin na wczoraj" + }, + { + "id": "app.user.run.status_disable", + "translation": "@{.Username}} wyłączył aktualizacje statusu dla [{{.RunName}}]({{.RunURL}})" + }, + { + "id": "app.user.run.status_enable", + "translation": "@{.Username}} włączył aktualizacje statusu dla [{{.RunName}}]({{.RunURL}})" + }, + { + "id": "app.user.run.update_status.change_since_last_update", + "translation": "Zmiana od ostatniej aktualizacji" + }, + { + "id": "app.user.run.confirm_finish.submit_label", + "translation": "Zakończ uruchomienie" + }, + { + "id": "app.user.run.confirm_finish.title", + "translation": "Potwierdź zakończenie uruchomienia" + }, + { + "id": "app.user.run.request_join_channel", + "translation": "@{{.Name}} jest uczestnikiem uruchomienia i chce dołączyć do tego kanału. Każdy członek kanału może go zaprosić.\n" + }, + { + "id": "app.user.run.request_update", + "translation": "@here - @{.Name}} zażądał aktualizacji statusu dla [{{.RunName}}]({{.RunURL}}). \n" + }, + { + "id": "app.user.run.add_to_timeline.title", + "translation": "Dodaj do osi czasu uruchomienia" } ] diff --git a/server/i18n/pt-BR.json b/server/i18n/pt-BR.json index 63dcbcc1ce..48f679a2be 100644 --- a/server/i18n/pt-BR.json +++ b/server/i18n/pt-BR.json @@ -8619,18 +8619,6 @@ "id": "api.cloud.notify_admin_to_upgrade_error.already_notified", "translation": "Administrador já notificado" }, - { - "id": "Channels", - "translation": "Canais" - }, - { - "id": "Boards", - "translation": "Quadros" - }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, { "id": "api.cloud.delinquency_email.missing_email_to_trigger", "translation": "Campos faltando para envio de email." diff --git a/server/i18n/ru.json b/server/i18n/ru.json index d64ff35cfb..452811806c 100644 --- a/server/i18n/ru.json +++ b/server/i18n/ru.json @@ -8967,18 +8967,6 @@ "id": "api.custom_groups.feature_disabled", "translation": "функция пользовательских групп отключена" }, - { - "id": "Playbooks", - "translation": "Сценарии" - }, - { - "id": "Channels", - "translation": "Каналы" - }, - { - "id": "Boards", - "translation": "Доски" - }, { "id": "api.error_get_first_admin_complete_setup", "translation": "Ошибка при попытке получить первую завершенную настройку администратора из магазина." @@ -9035,34 +9023,6 @@ "id": "api.user.authorize_oauth_user.saml_response_too_long.app_error", "translation": "Ответ SAML слишком длинный" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Откройте для себя повышенную производительность с помощью этих замечательных функций" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Привет, {{.Name}}, мы заметили, что Ваш сервер Mattermost собирает немного пыли. Взгляните на некоторые функции, которые могут облегчить рабочую нагрузку в Вашей команде." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Откройте все возможности Mattermost, чтобы повысить производительность вашей команды!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Управляйте задачами с помощью " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Управление рабочим процессом с " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Приходите и проверьте это!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Открыть Mattermost" - }, { "id": "api.team.invite_members.unable_to_send_email_with_defaults.app_error", "translation": "SMTP не настроен в Системной Консоли" @@ -9079,10 +9039,6 @@ "id": "api.error_set_first_admin_complete_setup", "translation": "Ошибка при попытке сохранить первую полную настройку администратора в магазине." }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Гостевой доступ к указанному " - }, { "id": "model.oauth.is_valid.mattermost_app_id.app_error", "translation": "Максимальная длина MattermostAppID — 32 символа." @@ -9307,10 +9263,6 @@ "id": "app.post.analytics_teams_count.app_error", "translation": "Не удалось получить сведения об использовании команд" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Плагин {{.Name}} не может быть включен в продуктовом режиме." - }, { "id": "app.notify_admin.send_notification_post.app_error", "translation": "Невозможно отправить сообщение с уведомлением." @@ -9371,10 +9323,6 @@ "id": "app.cloud.get_cloud_products.app_error", "translation": "Не удалось получить облачные продукты" }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Вы получили это одноразовое письмо, потому что ваш сервер Mattermost был неактивен более {{.Hours}} часов. Это письмо было автоматически сгенерировано вашим сервером Mattermost." - }, { "id": "api.templates.delinquency_90.title", "translation": "Ваше рабочее пространство Mattermost было понижено в статусе" @@ -9591,10 +9539,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Невозможно получить приоритет для сообщения" }, - { - "id": "app.draft.update.app_error", - "translation": "Невозможно обновить черновик." - }, { "id": "app.draft.save.app_error", "translation": "Невозможно сохранить черновик." @@ -9663,22 +9607,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Вы не можете удалить подтверждение в архивированном канале." }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Создайте прозрачные рабочие процессы между командами разработчиков, чтобы обеспечить бесперебойный процесс разработки функций." - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Повысьте производительность вашего канала, интегрировав бота для Jira и бота для Github. Они будут загружены для вас." - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Общайтесь со своей командой в канале Feature Release, который легко соединяется с вашими досками, сценариями и ботами приложений." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Используйте наш шаблон доски \"Повестка дня совещания\" для повторяющихся совещаний, например, совещаний по подготовке к работе, и доску \"Задачи проекта\" для управления ходом выполнения задач." - }, { "id": "worktemplate.category.product_teams", "translation": "Продуктовые команды" @@ -9839,121 +9767,13 @@ "id": "app.import.validate_user_teams_import_data.invalid_auth_service.error", "translation": "Неверная служба авторизации: {{.AuthService}}" }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Используйте проект, чтобы сделать планирование спринта легким. Канал позволяет сфокусировать разговор и вопросы. План спринта помогает всем выполнить задачи на неделю, а доска ретроспектив объединяет команду для постоянного совершенствования." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Используйте проект, чтобы сделать планирование спринта легким. Канал позволяет сфокусировать разговор и вопросы. План спринта помогает всем выполнить задачи на неделю, а доска ретроспектив объединяет команду для постоянного совершенствования." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Используйте проект, чтобы сделать планирование спринта легким. Канал позволяет сфокусировать разговор и вопросы. План спринта помогает всем выполнить задачи на неделю, а доска ретроспектив объединяет команду для постоянного совершенствования." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Описание того, зачем нужен канал(ы)" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Описание того, зачем нужна(ы) доска(и)" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Организуйтесь и уничтожьте все ошибки с помощью этого проекта! Создайте импульс и измерьте прогресс с помощью включенных в комплект Playbook, Board и Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Организуйтесь и уничтожьте все ошибки с помощью этого проекта! Создайте импульс и измерьте прогресс с помощью включенных в комплект Playbook, Board и Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Организуйтесь и уничтожьте все ошибки с помощью этого проекта! Создайте импульс и измерьте прогресс с помощью включенных в комплект Playbook, Board и Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Организуйтесь и уничтожьте все ошибки с помощью этого проекта! Создайте импульс и измерьте прогресс с помощью включенных в комплект Playbook, Board и Channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "С этим проектом вы не пропустите ни одного шага во время выпуска продукта. Назначайте задачи из контрольного списка Playbook и устанавливайте вехи на Досках. Используйте Каналы, чтобы все были вовлечены в процесс." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "С этим проектом вы не пропустите ни одного шага во время выпуска продукта. Назначайте задачи из контрольного списка Playbook и устанавливайте вехи на Досках. Используйте Каналы, чтобы все были вовлечены в процесс." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "С этим проектом вы не пропустите ни одного шага во время выпуска продукта. Назначайте задачи из контрольного списка Playbook и устанавливайте вехи на Досках. Используйте Каналы, чтобы все были вовлечены в процесс." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "Когда все идет не так, как надо, наличие повторяющегося процесса является ключом к тому, чтобы все было исправлено как можно быстрее. Этот проект сочетает в себе все, что предлагает Mattermost, чтобы обеспечить разрешение трудностей и информирование заинтересованных сторон на этом пути." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "Когда все идет не так, как надо, наличие повторяющегося процесса является ключом к тому, чтобы все было исправлено как можно быстрее. Этот проект сочетает в себе все, что предлагает Mattermost, чтобы обеспечить разрешение трудностей и информирование заинтересованных сторон на этом пути." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "Когда все идет не так, как надо, наличие повторяющегося процесса является ключом к тому, чтобы все было исправлено как можно быстрее. Этот проект сочетает в себе все, что предлагает Mattermost, чтобы обеспечить разрешение трудностей и информирование заинтересованных сторон на этом пути." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Фокусировка необходима для успеха команды, и с помощью этого проекта вы можете документировать цели и OKR команды, а также публиковать обновления в специальном канале." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Планируйте дорожную карту с помощью этой проектной доски и сотрудничайте по теме в канале, созданном с помощью этого шаблона." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Планируйте дорожную карту с помощью этой проектной доски и сотрудничайте по теме в канале, созданном с помощью этого шаблона." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Планируйте дорожную карту с помощью этой проектной доски и сотрудничайте по теме в канале, созданном с помощью этого шаблона." - }, { "id": "worktemplate.category.leadership", "translation": "Лидерство" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "api.server.cws.needs_enterprise_edition", diff --git a/server/i18n/sv.json b/server/i18n/sv.json index e831a10a09..f63afba27a 100644 --- a/server/i18n/sv.json +++ b/server/i18n/sv.json @@ -8970,18 +8970,6 @@ "id": "app.system.complete_onboarding_request.app_error", "translation": "Misslyckades att tolka onboarding-anropet." }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, - { - "id": "Channels", - "translation": "Kanaler" - }, - { - "id": "Boards", - "translation": "Boards" - }, { "id": "api.custom_groups.no_remote_id", "translation": "remote_id måste vara tomt för anpassade grupper" @@ -9070,42 +9058,6 @@ "id": "app.channel.get_file_count.app_error", "translation": "Det går inte att få fram antalet filer i kanalen" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Öka produktiviteten med dessa fantastiska funktioner" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hej {{.Name}}, vi ser att din Mattermost-server samlat lite damm. Ta en titt på några funktioner som kan hjälpa till att lätta på arbetsbördan för ditt team." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Öppna Mattermost för att öka teamets produktivitet!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Hantera uppgifter med hjälp av " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Hantera arbetsflöden med " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Gäståtkomst till specificerade " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Kom och kolla in det!" - }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Du fick det här engångsmejlet eftersom din Mattermost-server har varit inaktiv i mer än {{.Hours}} timmar. Det här e-postmeddelandet genererades automatiskt av din Mattermost-server." - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Öppna Mattermost" - }, { "id": "api.templates.invite_team_and_channels_subject", "translation": "[{{ .SiteName }}] {{ .SenderName }} bjöd in dig att ansluta till {{ .ChannelsLen }} kanaler i teamet {{ .TeamDisplayName }}" @@ -9522,10 +9474,6 @@ "id": "model.insights.get_start_of_day_for_time_range.time_range.app_error", "translation": "Ogiltigt tidsintervall." }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Plugin {{.Name}} kan inte aktiveras i produktionsläge." - }, { "id": "app.collection.add_collection.exists.app_error", "translation": "Samlingstypen finns redan." @@ -9582,22 +9530,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Du kan inte ta bort en bekräftelse i en arkiverad kanal." }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Skapa transparenta arbetsflöden mellan utvecklingsteamen för att säkerställa att utvecklingsprocessen för funktioner är smidig." - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Öka produktiviteten i kanalen genom att integrera en Jira-bot och en Github-bot. Dessa kommer att laddas ner åt dig." - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Chatta med ditt team i kanalen för kommande leveranser, som enkelt kan anslutas till dina tavlor, playbooks och app-bottar." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Använd vår mall för mötesagenda för återkommande möten exempelvis standup och vår Projekt-board för projektuppgifter och att hantera uppgifternas framskridande." - }, { "id": "worktemplate.category.product_teams", "translation": "Produkt-team" @@ -9654,10 +9586,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "Det går inte att få fram inläggets prioritet" }, - { - "id": "app.draft.update.app_error", - "translation": "Kunde inte uppdatera utkastet." - }, { "id": "app.draft.save.app_error", "translation": "Kunde inte spara utkastet." @@ -9822,121 +9750,13 @@ "id": "api.work_templates.disabled", "translation": "Arbetsmallar är inaktiverade." }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Använd ett projekt för att göra sprintplaneringen enkel. Kanalen håller konversationen och frågorna fokuserade. Sprintplanen håller alla på uppgiften för veckan och retrospektivtavlan samlar teamet för att kontinuerligt förbättra sig." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Använd ett projekt för att göra sprintplaneringen enkel. Kanalen håller konversationen och frågorna fokuserade. Sprintplanen håller alla på uppgiften för veckan och retrospektivtavlan samlar teamet för att kontinuerligt förbättra sig." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Använd ett projekt för att göra sprintplaneringen enkel. Kanalen håller konversationen och frågorna fokuserade. Sprintplanen håller alla på uppgiften för veckan och retrospektivtavlan samlar teamet för att kontinuerligt förbättra sig." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Beskrivning av varför kanalen/kanalerna behövs" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Beskrivning av varför tavlan/tavlorna behövs" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Bli organiserad och kläm åt alla buggar med det här projektet! Skapa framdrift och mät framstegen med hjälp av den medföljande Playbook, Board och Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Bli organiserad och kläm åt alla buggar med det här projektet! Skapa framdrift och mät framstegen med hjälp av den medföljande Playbook, Board och Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Bli organiserad och kläm åt alla buggar med det här projektet! Skapa framdrift och mät framstegen med hjälp av den medföljande Playbook, Board och Channel." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Bli organiserad och kläm åt alla buggar med det här projektet! Skapa framdrift och mät framstegen med hjälp av den medföljande Playbook, Board och Channel." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Med det här projektet kan du inte missa något steg under en produktlansering. Tilldela uppgifter från checklistan i Playbook och uppnå milstolpar med Board. Använd Channel för att se till att alla har samma information." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Med det här projektet kan du inte missa något steg under en produktlansering. Tilldela uppgifter från checklistan i Playbook och uppnå milstolpar med Board. Använd Channel för att se till att alla har samma information." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Med det här projektet kan du inte missa något steg under en produktlansering. Tilldela uppgifter från checklistan i Playbook och uppnå milstolpar med Board. Använd Channel för att se till att alla har samma information." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "När saker är på väg att gå fel är en återupprepningsbar process en nyckel för att kunna rätta till så snabbt som möjligt. Det här projektet kombinerar allt som Mattermost erbjuder för att se till att bränderna släcks och att intressenterna informeras på vägen." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "När saker är på väg att gå fel är en återupprepningsbar process en nyckel för att kunna rätta till så snabbt som möjligt. Det här projektet kombinerar allt som Mattermost erbjuder för att se till att bränderna släcks och att intressenterna informeras på vägen." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "När saker är på väg att gå fel är en återupprepningsbar process en nyckel för att kunna rätta till så snabbt som möjligt. Det här projektet kombinerar allt som Mattermost erbjuder för att se till att bränderna släcks och att intressenterna informeras på vägen." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Tydligt fokus är viktigt för att teamet ska lyckas och med det här projektet kan du dokumentera teamets mål och OKR:er samt lägga upp uppdateringar i den särskilda kanalen." - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Planera en roadmap med hjälp av projekttavlan och samarbeta i ämnet i kanalen som skapats från den här mallen." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Planera en roadmap med hjälp av projekttavlan och samarbeta i ämnet i kanalen som skapats från den här mallen." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Planera en roadmap med hjälp av projekttavlan och samarbeta i ämnet i kanalen som skapats från den här mallen." - }, { "id": "worktemplate.category.leadership", "translation": "Ledarskap" }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", @@ -10013,5 +9833,213 @@ { "id": "app.oauth.remove_auth_data_by_client_id.app_error", "translation": "Kunde inte rensa oauth-information." + }, + { + "id": "app.user.run.update_status.title", + "translation": "Statusuppdatering" + }, + { + "id": "app.user.run.update_status.submit_label", + "translation": "Uppdatera status" + }, + { + "id": "app.user.run.update_status.reminder_for_next_update", + "translation": "Påminnelse om nästa uppdatering" + }, + { + "id": "app.user.run.update_status.num_channel", + "translation": { + "one": "Ge en uppdatering till intressenterna. Detta inlägg kommer att publiceras i {{.Count}} kanal.", + "other": "Ge en uppdatering till intressenterna. Detta inlägg kommer att publiceras i {{.Count}} kanaler." + } + }, + { + "id": "app.user.run.update_status.finish_run.placeholder", + "translation": "Markera även körningen som avslutad" + }, + { + "id": "app.user.run.update_status.finish_run", + "translation": "Slutför körningen" + }, + { + "id": "app.user.run.update_status.change_since_last_update", + "translation": "Förändring sedan den senaste uppdateringen" + }, + { + "id": "app.user.run.status_enable", + "translation": "@{{.Username}} aktiverade statusuppdateringar för [{{.RunName}}]({{.RunURL}})" + }, + { + "id": "app.user.run.status_disable", + "translation": "@{{.Username}} inaktiverade statusuppdateringarna för [{{.RunName}}]({{.RunURL}})" + }, + { + "id": "app.user.run.request_update", + "translation": "@here - @{{.Name}} begärde en statusuppdatering för [{{.RunName}}]({{.RunURL}}). \n" + }, + { + "id": "app.user.run.request_join_channel", + "translation": "@{{.Name}} är en deltagare i en körning och vill gå med i den här kanalen. Alla medlemmar i kanalen kan bjuda in dem.\n" + }, + { + "id": "app.user.run.confirm_finish.title", + "translation": "Bekräfta att avsluta körningen" + }, + { + "id": "app.user.run.confirm_finish.submit_label", + "translation": "Slutför körningen" + }, + { + "id": "app.user.run.confirm_finish.num_outstanding", + "translation": { + "one": "Det finns **{{.Count}} utestående uppgift**. Är du säker på att du vill avsluta körningen *{{.RunName}}* för alla deltagare?", + "other": "Det finns **{{.Count}} utestående uppgifter**. Är du säker på att du vill avsluta körningen *{{.RunName}}* för alla deltagare?" + } + }, + { + "id": "app.user.run.add_to_timeline.title", + "translation": "Lägg till i tidslinjen för körning" + }, + { + "id": "app.user.run.add_to_timeline.summary.placeholder", + "translation": "Kort sammanfattning som visas i tidslinjen" + }, + { + "id": "app.user.run.add_to_timeline.summary.help", + "translation": "Max 64 tecken" + }, + { + "id": "app.user.run.add_to_timeline.summary", + "translation": "Sammanfattning" + }, + { + "id": "app.user.run.add_to_timeline.submit_label", + "translation": "Lägg till i tidslinjen för körning" + }, + { + "id": "app.user.run.add_to_timeline.playbook_run", + "translation": "Kör Playbook" + }, + { + "id": "app.user.run.add_checklist_item.title", + "translation": "Lägg till en ny uppgift" + }, + { + "id": "app.user.run.add_checklist_item.submit_label", + "translation": "Lägg till en uppgift" + }, + { + "id": "app.user.run.add_checklist_item.name", + "translation": "Namn" + }, + { + "id": "app.user.run.add_checklist_item.description", + "translation": "Beskrivning" + }, + { + "id": "app.user.new_run.title", + "translation": "Kör playbook" + }, + { + "id": "app.user.new_run.submit_label", + "translation": "Starta körning" + }, + { + "id": "app.user.new_run.run_name", + "translation": "Namn på körning" + }, + { + "id": "app.user.new_run.playbook", + "translation": "Playbook" + }, + { + "id": "app.user.new_run.intro", + "translation": "**Ägare** {{.Username}}" + }, + { + "id": "app.user.digest.tasks.zero_assigned", + "translation": "Du har 0 tilldelade uppgifter." + }, + { + "id": "app.user.digest.tasks.num_assigned_due_until_today", + "translation": { + "one": "Du har {{.Count}} tilldelad uppgift som nu är förfallen:", + "other": "Du har {{.Count}} tilldelade uppgifter som nu är förfallna:" + } + }, + { + "id": "app.user.digest.tasks.num_assigned", + "translation": { + "one": "Du har {{.Count}} tilldelad uppgift:", + "other": "Du har {{.Count}} tilldelade uppgifter:" + } + }, + { + "id": "app.user.digest.tasks.heading", + "translation": "Dina tilldelade uppgifter" + }, + { + "id": "app.user.digest.tasks.due_yesterday", + "translation": "Skulle utförts igår" + }, + { + "id": "app.user.digest.tasks.due_x_days_ago", + "translation": "Försenad {{.Count}} dagar" + }, + { + "id": "app.user.digest.tasks.due_in_x_days", + "translation": { + "one": "Ska utföras inom {{.Count}} dag", + "other": "Ska utföras inom {{.Count}} dagar" + } + }, + { + "id": "app.user.digest.tasks.due_today", + "translation": "Ska utföras idag" + }, + { + "id": "app.user.digest.tasks.due_after_today", + "translation": { + "one": "Du har **{{.Count}} tilldelad uppgift som ska utföras idag**.", + "other": "Du har **{{.Count}} tilldelade uppgifter som ska utföras idag**." + } + }, + { + "id": "app.user.digest.tasks.all_tasks_command", + "translation": "Använd `/playbook todo` för att se alla dina uppgifter." + }, + { + "id": "app.user.digest.runs_in_progress.zero_in_progress", + "translation": "Du har 0 pågående körningar." + }, + { + "id": "app.user.digest.runs_in_progress.num_in_progress", + "translation": { + "one": "Du har {{.Count}} körning som för närvarande pågår:", + "other": "Du har {{.Count}} körningar som för närvarande pågår:" + } + }, + { + "id": "app.user.digest.runs_in_progress.heading", + "translation": "Körningar som pågår" + }, + { + "id": "app.user.digest.overdue_status_updates.zero_overdue", + "translation": "Du har 0 försenade körningar." + }, + { + "id": "app.user.digest.overdue_status_updates.num_overdue", + "translation": { + "one": "Du har {{.Count}} körning som borde ha fått en statusuppdatering:", + "other": "Du har {{.Count}} körningar som borde ha fått en statusuppdatering:" + } + }, + { + "id": "app.user.digest.overdue_status_updates.heading", + "translation": "Status om förseningar" + }, + { + "id": "app.command.execute.error", + "translation": "Kunde inte utföra kommandot." } ] diff --git a/server/i18n/tr.json b/server/i18n/tr.json index 2f9c116dc4..218846ffc4 100644 --- a/server/i18n/tr.json +++ b/server/i18n/tr.json @@ -9022,50 +9022,6 @@ "id": "api.custom_groups.count_err", "translation": "gruplar sayılırken sorun çıktı" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Bu harika özelliklerle üretkenliğinizi artırın" - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Ekibinizin üretkenliğini arttırmak için Mattermost açın!" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Merhaba {{.Name}}, Mattermost sunucunuzun biraz toz tuttuğunu fark ettik. Ekibinizin iş yükünü hafifletmeye yardımcı olabilecek bazı özelliklere göz atın." - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Belirtilen konuk erişimi " - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Görev yönetimi " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "İş akışı yönetimi " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Gelin ve inceleyin!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Mattermost uygulamasını aç" - }, - { - "id": "Playbooks", - "translation": "Senaryolar" - }, - { - "id": "Channels", - "translation": "Kanallar" - }, - { - "id": "Boards", - "translation": "Panolar" - }, { "id": "app.job.get_all_jobs_by_type_and_status.app_error", "translation": "Türe ve duruma göre tüm görevler alınamadı." @@ -9166,10 +9122,6 @@ "id": "api.templates.cloud_upgrade_confirmation.subject", "translation": "Mattermost üst tarifeye geçme onayı" }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "Bu bir kerelik e-posta Mattermost sunucunuz {{.Hours}} saatten uzun süredir etkin olmadığı için gönderildi. Bu e-posta Mattermost sunucunuz tarafından otomatik olarak oluşturuldu." - }, { "id": "api.elasticsearch.test_elasticsearch_settings_nil.app_error", "translation": "Elasticsearch yapılandırmasında ayarlanmamış değerler var." @@ -9510,10 +9462,6 @@ "id": "model.group.name.reserved_name.app_error", "translation": "aynı adlı bir grup zaten sistem kullanımına ayrılmış bir ad olarak var" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "{{.Name}} uygulama eki ürün kipinde etkinleştirilemez." - }, { "id": "api.team.invite_guests_to_channels.license.error", "translation": "Lisansınız konuk hesaplarının kullanılmasını desteklemiyor" @@ -9558,22 +9506,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Arşivlenmiş bir kanaldaki bir onayı kaldıramazsınız." }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "Özellik geliştirme sürecinizin sorunsuz olmasını sağlamak için geliştirme ekipleri arasında şeffaf iş akışları oluşturun." - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "Bir Jira botu ve Github botu ile bütünleştirerek kanalınızdaki üretkenliği artırın. Bu botlar sizin için indirilir." - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Panolarınıza, senaryolarınıza ve uygulama botlarınıza kolayca bağlanan bir özellik yayını kanalında ekibinizle sohbet edin." - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "Ayaküstü gibi yinelenen toplantılar için toplantı gündemi panosu kalıbımızı ve yol boyunca görevlerin ilerleyişini yönetmek için proje görevleri panomuzu kullanın." - }, { "id": "worktemplate.category.product_teams", "translation": "Ürün takımları" @@ -9634,10 +9566,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "İletinin önceliği alınamadı" }, - { - "id": "app.draft.update.app_error", - "translation": "Taslak güncellenemedi." - }, { "id": "app.draft.get_drafts.app_error", "translation": "Kullanıcının taslakları alınamadı." @@ -9842,30 +9770,6 @@ "id": "worktemplate.category.devops", "translation": "Geliştirme işlemleri" }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "Bu proje panosunu kullanarak bir yol haritası planlayın ve bu kalıpla oluşturulan kanalda konu üzerine işbirliği yapın." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "Bu proje panosunu kullanarak bir yol haritası planlayın ve bu kalıpla oluşturulan kanalda konu üzerine işbirliği yapın." - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "Bu proje panosunu kullanarak bir yol haritası planlayın ve bu kalıpla oluşturulan kanalda konu üzerine işbirliği yapın." - }, { "id": "app.import.validate_user_teams_import_data.invalid_auth_service.error", "translation": "Kimlik doğrulama hizmeti geçersiz: {{.AuthService}}" @@ -9874,90 +9778,6 @@ "id": "api.server.cws.needs_enterprise_edition", "translation": "Bu hizmet yalnızca Mattermost Enterprise sürümüyle kullanılabilir" }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "Acil işlerin planlamasını kolaylaştırmak için bir proje kullanın. Kanal, konuşmanın ve soruların odaklanmasını sağlar. Acil iş planı herkesin hafta boyunca görevler üzerinde kalmasını sağlar ve geçmiş değerlendirmesi panosu takımı sürekli geliştirme için bir araya getirir." - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "Acil işlerin planlamasını kolaylaştırmak için bir proje kullanın. Kanal, konuşmanın ve soruların odaklanmasını sağlar. Acil iş planı herkesin hafta boyunca görevler üzerinde kalmasını sağlar ve geçmiş değerlendirmesi panosu takımı sürekli geliştirme için bir araya getirir." - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "Acil işlerin planlamasını kolaylaştırmak için bir proje kullanın. Kanal, konuşmanın ve soruların odaklanmasını sağlar. Acil iş planı herkesin hafta boyunca görevler üzerinde kalmasını sağlar ve geçmiş değerlendirmesi panosu takımı sürekli geliştirme için bir araya getirir." - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "Kanallara neden gerek duyulduğunun açıklaması" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "Panolara neden gerek duyulduğunun açıklaması" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "Bu proje ile organize olun ve tüm hatalardan kurtulun! Senaryo, Pano ve Kanal özelliklerini kullanarak çalışmaya başlayın ve ilerlemeyi ölçün." - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "Bu proje ile organize olun ve tüm hatalardan kurtulun! Senaryo, Pano ve Kanal özelliklerini kullanarak çalışmaya başlayın ve ilerlemeyi ölçün." - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "Bu proje ile organize olun ve tüm hatalardan kurtulun! Senaryo, Pano ve Kanal özelliklerini kullanarak çalışmaya başlayın ve ilerlemeyi ölçün." - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "Bu proje ile organize olun ve tüm hatalardan kurtulun! Senaryo, Pano ve Kanal özelliklerini kullanarak çalışmaya başlayın ve ilerlemeyi ölçün." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "Takım başarısı için net odaklanma şarttır ve bu proje ile ekibin hedefleri ile OKR kriterlerini belgeleyebilir ve güncellemeleri özel bir kanalda yayınlayabilirsiniz." - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "Bu proje ile bir ürün sürümü sırasında hiçbir adımı atlamayın. Senaryo kontrol listesinden görevler atayın ve Pano ile kilometre taşlarına ulaşın. Herkesin aynı şeyleri bilmesi için Kanalları kullanın." - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "Bu proje ile bir ürün sürümü sırasında hiçbir adımı atlamayın. Senaryo kontrol listesinden görevler atayın ve Pano ile kilometre taşlarına ulaşın. Herkesin aynı şeyleri bilmesi için Kanalları kullanın." - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "Bu proje ile bir ürün sürümü sırasında hiçbir adımı atlamayın. Senaryo kontrol listesinden görevler atayın ve Pano ile kilometre taşlarına ulaşın. Herkesin aynı şeyleri bilmesi için Kanalları kullanın." - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "İşler ters gittiğinde, yinelenebilir bir sürecinizin olması, her şeyin olabilecek en kısa sürede doğru olarak yapılmasını sağlar. Bu özellik projelerdeki yangınların söndürülmesini ve paydaşların yol boyunca bilgilendirilmesini sağlamak için Mattermost tarafından sunulan her şeyi bir araya getirir." - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "İşler ters gittiğinde, yinelenebilir bir sürecinizin olması, her şeyin olabilecek en kısa sürede doğru olarak yapılmasını sağlar. Bu özellik projelerdeki yangınların söndürülmesini ve paydaşların yol boyunca bilgilendirilmesini sağlamak için Mattermost tarafından sunulan her şeyi bir araya getirir." - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "İşler ters gittiğinde, yinelenebilir bir sürecinizin olması, her şeyin olabilecek en kısa sürede doğru olarak yapılmasını sağlar. Bu özellik projelerdeki yangınların söndürülmesini ve paydaşların yol boyunca bilgilendirilmesini sağlamak için Mattermost tarafından sunulan her şeyi bir araya getirir." - }, { "id": "app.worktemplates.execute_work_template.name_too_long", "translation": "Ad alanına en fazla 64 karakter yazılabilir." diff --git a/server/i18n/uk.json b/server/i18n/uk.json index bce734f746..b63779f26f 100644 --- a/server/i18n/uk.json +++ b/server/i18n/uk.json @@ -6847,10 +6847,6 @@ "id": "api.back_to_app", "translation": "Повернутися до {{.SiteName}}" }, - { - "id": "Channels", - "translation": "Канали" - }, { "id": "api.cloud.cws_webhook_event_missing_error", "translation": "Подія Webhook не оброблена. Або вона відсутня, або недійсна." @@ -6879,14 +6875,6 @@ "id": "api.acknowledgement.delete.archived_channel.app_error", "translation": "Ви не можете видалити підтвердження в заархівованому каналі." }, - { - "id": "Playbooks", - "translation": "Сценарії" - }, - { - "id": "Boards", - "translation": "Дошки" - }, { "id": "api.command_remote.invite.help", "translation": "Запросіть безпечне з'єднання" diff --git a/server/i18n/zh-CN.json b/server/i18n/zh-CN.json index 3cc21656bd..bbf95c2889 100644 --- a/server/i18n/zh-CN.json +++ b/server/i18n/zh-CN.json @@ -8999,38 +8999,6 @@ "id": "api.user.authorize_oauth_user.saml_response_too_long.app_error", "translation": "SAML的请求信息太长" }, - { - "id": "api.templates.server_inactivity_title", - "translation": "解锁这些令人敬佩的、提高生产力的功能" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "嗨, {{.Name}}, 我们注意到您的 Mattermost 服务器集了一些“灰尘”(有一段时间没有维护了),快来看看可以帮助减轻团队工作量的一些功能." - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "快来打开 Mattermost 以提高您团队的生产力!" - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "管理任务由 " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "工作流管理于 " - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "指定客户专访 " - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "快来看看吧!" - }, - { - "id": "api.templates.server_inactivity_button", - "translation": "打开 Mattermost" - }, { "id": "api.templates.invite_team_and_channels_subject", "translation": "[{{ .SiteName }}] {{ .SenderName }} 邀请您加入 {{ .TeamDisplayName }} 团队的 {{ .ChannelsLen }} 频道组" @@ -9127,18 +9095,6 @@ "id": "api.custom_groups.count_err", "translation": "统计“组”时出现错误" }, - { - "id": "Playbooks", - "translation": "规划书" - }, - { - "id": "Channels", - "translation": "频道" - }, - { - "id": "Boards", - "translation": "面板" - }, { "id": "model.oauth.is_valid.mattermost_app_id.app_error", "translation": "MattermostAppID 的最大长度为 32 个字符。" @@ -9171,10 +9127,6 @@ "id": "app.insights.feature_disabled", "translation": "Insights 功能已禁用。" }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "您收到这封一次性电子邮件是因为您的 Mattermost 服务器处于非活动状态超过 {{.Hours}} 小时。 本电子邮件是由您的 Mattermost 服务器自动生成。" - }, { "id": "api.file.cloud_upload.app_error", "translation": "不支持通过 mmctl 上传到 Cloud 实例。 请在此处查看文档:https://docs.mattermost.com/manage/cloud-data-export.html。" @@ -9505,7 +9457,7 @@ }, { "id": "worktemplate.category.product_teams", - "translation": "产品团队" + "translation": "产品" }, { "id": "worktemplate.category.leadership", @@ -9513,7 +9465,7 @@ }, { "id": "worktemplate.category.devops", - "translation": "Dev Ops" + "translation": "DevOps" }, { "id": "worktemplate.category.companywide", @@ -9687,10 +9639,6 @@ "id": "app.post_prority.get_for_post.app_error", "translation": "无法取得消息的优先级" }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "在生产模式中无法启用 {{.Name}} 插件。" - }, { "id": "app.notify_admin.send_notification_post.app_error", "translation": "无法发送通知消息。" @@ -9719,10 +9667,6 @@ "id": "app.file.cloud.get.app_error", "translation": "由于云订阅的限制,无法取得文件。" }, - { - "id": "app.draft.update.app_error", - "translation": "无法更新草稿。" - }, { "id": "app.draft.save.app_error", "translation": "无法保存草稿。" @@ -9859,130 +9803,6 @@ "id": "api.command_templates.unsupported.app_error", "translation": "您的设备不支持模板命令。" }, - { - "id": "worktemplate.product_teams.sprint_planning.integration", - "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" - }, - { - "id": "worktemplate.product_teams.sprint_planning.channel", - "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" - }, - { - "id": "worktemplate.product_teams.sprint_planning.board", - "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" - }, - { - "id": "worktemplate.product_teams.product_roadmap.channel", - "translation": "这里描述了为什么需要面板" - }, - { - "id": "worktemplate.product_teams.product_roadmap.board", - "translation": "这里描述了为什么需要面板" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.integration", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.channel", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.product_teams.goals_and_okrs.board", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.playbook", - "translation": "通过建立透明的跨越整个研发团队的工作流程确保你的功能开发过程完美流畅。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.integration", - "translation": "在你的频道通过集成Jira和Gtihub机器人提高效率。这些会自动下载安装。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.channel", - "translation": "Boards,Playbooks和应用Bot可以很容易地接入功能发布频道并且和你的团队进行相关互动和讨论。" - }, - { - "id": "worktemplate.product_teams.feature_release.description.board", - "translation": "使用我们的会议日程模板安排像站立会议这样的定期会议,使用我们的项目任务面板在一路上管理任务的进度。" - }, - { - "id": "worktemplate.product_teams.bug_bash.playbook", - "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" - }, - { - "id": "worktemplate.product_teams.bug_bash.integration", - "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" - }, - { - "id": "worktemplate.product_teams.bug_bash.channel", - "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" - }, - { - "id": "worktemplate.product_teams.bug_bash.board", - "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.integration", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.channel", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.leadership.goals_and_okrs.board", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.devops.product_release.playbook", - "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" - }, - { - "id": "worktemplate.devops.product_release.channel", - "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" - }, - { - "id": "worktemplate.devops.product_release.board", - "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.playbook", - "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.channel", - "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" - }, - { - "id": "worktemplate.devops.incident_resolution.description.board", - "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.integration", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.channel", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.companywide.goals_and_okrs.board", - "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" - }, - { - "id": "worktemplate.companywide.create_project.integration", - "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" - }, - { - "id": "worktemplate.companywide.create_project.channel", - "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" - }, - { - "id": "worktemplate.companywide.create_project.board", - "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" - }, { "id": "app.user.run.update_status.title", "translation": "状态更新" @@ -10206,5 +10026,69 @@ { "id": "api.license.true_up_review.create_error", "translation": "无法创建真实的状态记录" + }, + { + "id": "api.license.request-trial.bad-request.business-email", + "translation": "无效的商务试用邮箱" + }, + { + "id": "worktemplate.product_teams.feature_release.description.integration", + "translation": "通过集成大多您使用过的工具(比如 GitHub)在您的频道里提高生产力,实现你的功能发布。这些工具将为你下载。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.channel", + "translation": "在一个频道与你的团队讨论任何的发布障碍和变动,并很容易的与你的面板,Playbook或者其他的集成功能连接。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.board", + "translation": "使用会议安排面板保持会议一起正常。使用项目任务面板管理你的工作量。" + }, + { + "id": "worktemplate.product_teams.bug_bash.integration", + "translation": "通过集成大多您使用过的工具(比如Jira)在您的频道里提高生产力,跟踪你的Bug解决过程。这些工具将为你下载。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.integration", + "translation": "通过集成大多您使用过的工具(比如 Zoom)在您的频道里提高生产力,实行更容易的协作。这些工具将为你下载。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.channel", + "translation": "和您的团队讨论目标和进度,以异步或者同步的方式,在同一个频道中保持跟上任何发生的变化。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.board", + "translation": "使用目标和OKR面板跟踪您的团队进度向组织目标推进。使用会议安排面板保持会议一起正常。" + }, + { + "id": "worktemplate.devops.incident_resolution.description.channel", + "translation": "在一单独频道与您的团队讨论优先级、添加利益相关者,提供更新,向解决的方向努力。" + }, + { + "id": "worktemplate.devops.incident_resolution.description.board", + "translation": "使用事故解决面板来实现重复性的流程和分配跨越整个团队的任务。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.integration", + "translation": "通过集成大多您使用过的工具(比如 Zoom)在您的频道里提高生产力,实行更容易的协作。这些工具将为你下载。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.channel", + "translation": "和您的团队讨论目标和进度,以异步或者同步的方式,在同一个频道中保持跟上任何发生的变化。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.board", + "translation": "使用目标和OKR面板跟踪您的团队进度向组织目标推进。使用会议安排面板保持会议一起正常。" + }, + { + "id": "worktemplate.companywide.create_project.integration", + "translation": "通过集成大多您使用过的工具在您的频道里提高生产力。这些工具将为你下载。" + }, + { + "id": "worktemplate.companywide.create_project.channel", + "translation": "与您的团队在一个协作频道里讨论新的项目并且决定如何你们将如此组织。" + }, + { + "id": "worktemplate.companywide.create_project.board", + "translation": "使用看板面板定义和跟踪您的项目任务列表和进度。" } ] diff --git a/server/i18n/zh-TW.json b/server/i18n/zh-TW.json index 780ee87973..e677cec709 100644 --- a/server/i18n/zh-TW.json +++ b/server/i18n/zh-TW.json @@ -7247,10 +7247,6 @@ "id": "api.back_to_app", "translation": "返回至 {{.SiteName}}" }, - { - "id": "Channels", - "translation": "頻道" - }, { "id": "api.cloud.app_error", "translation": "雲端 API 請求時發生內部錯誤。" diff --git a/webapp/channels/.eslintignore b/webapp/channels/.eslintignore index 9c3001349d..468bb89127 100644 --- a/webapp/channels/.eslintignore +++ b/webapp/channels/.eslintignore @@ -1,4 +1,3 @@ -e2e/results node_modules dist lib diff --git a/webapp/channels/.eslintrc.json b/webapp/channels/.eslintrc.json index 048bb4b85e..7a3865a6db 100644 --- a/webapp/channels/.eslintrc.json +++ b/webapp/channels/.eslintrc.json @@ -2,22 +2,19 @@ "root": true, "extends": [ "plugin:mattermost/react", - "plugin:cypress/recommended", "plugin:react-hooks/recommended" ], "plugins": [ "@babel/eslint-plugin", "mattermost", "import", - "cypress", "no-only-tests", "@typescript-eslint", "formatjs" ], "parser": "@typescript-eslint/parser", "env": { - "jest": true, - "cypress/globals": true + "jest": true }, "settings": { "import/resolver": "webpack", @@ -166,17 +163,6 @@ "no-process-env": 0, "prefer-arrow-callback": 0 } - }, - { - "files": ["e2e/**"], - "rules": { - "@babel/no-unused-expressions": 0, - "func-names": 0, - "import/no-unresolved": 0, - "max-nested-callbacks": 0, - "no-process-env": 0, - "no-unused-expressions": 0 - } } ] } diff --git a/webapp/channels/.gobom.json b/webapp/channels/.gobom.json index 3279174525..4ec47b22c6 100644 --- a/webapp/channels/.gobom.json +++ b/webapp/channels/.gobom.json @@ -3,7 +3,6 @@ "properties": { "GomodMainOnly": true, "GomodExcludes": "_tests/|[-_]generators?$|^plugin/checker$", - "NpmExcludes": "/e2e$", "GradlePath": "./gradlew:../gradlew" }, "filters": [ diff --git a/webapp/channels/Makefile b/webapp/channels/Makefile index 889907e624..aa20ad2ca2 100644 --- a/webapp/channels/Makefile +++ b/webapp/channels/Makefile @@ -6,58 +6,6 @@ export NODE_OPTIONS=--max-old-space-size=4096 i18n-extract: ## Extract strings for translation from the source code npm run i18n-extract -e2e/playwright/node_modules: - @echo Install Playwright and its dependencies - cd e2e/playwright && npm install - -.PHONY: e2e-test -e2e-test: - @echo E2E: Running mattermost-mysql-e2e - @if [ $(shell docker ps -a | grep -ci mattermost-mysql-e2e) -eq 0 ]; then \ - echo starting mattermost-mysql-e2e; \ - docker run --name mattermost-mysql-e2e -p 35476:3306 -e MYSQL_ROOT_PASSWORD=mostest \ - -e MYSQL_USER=mmuser -e MYSQL_PASSWORD=mostest -e MYSQL_DATABASE=mattermost_test -d mysql:5.7 > /dev/null; \ - elif [ $(shell docker ps | grep -ci mattermost-mysql-e2e) -eq 0 ]; then \ - echo restarting mattermost-mysql-e2e; \ - docker start mattermost-mysql-e2e > /dev/null; \ - fi - - cd $(BUILD_SERVER_DIR) && [[ -f config/config.json ]] && \ - cp config/config.json config/config-backup.json && make config-reset || \ - echo "config.json not found" && make config-reset - - @echo E2E: Starting the server - cd $(BUILD_SERVER_DIR) && $(MAKE) run - - @echo E2E: Generating test data - cd $(BUILD_SERVER_DIR) && $(MAKE) test-data - - @echo E2E: Running end-to-end testing - cd e2e && npm install && npm run cypress:run - - @echo E2E: Stoppping the server - cd $(BUILD_SERVER_DIR) && $(MAKE) stop - - @echo E2E: stopping mattermost-mysql-e2e - docker stop mattermost-mysql-e2e > /dev/null - - cd $(BUILD_SERVER_DIR) && [[ -f config/config-backup.json ]] && \ - cp config/config-backup.json config/config.json && echo "revert local config.json" || \ - echo "config-backup.json not found" && sed -i'' -e 's|"DataSource": ".*"|"DataSource": "mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s"|g' config/config.json - - @echo E2E: Tests completed - -.PHONY: clean-e2e -clean-e2e: - @if [ $(shell docker ps -a | grep -ci mattermost-mysql-e2e) -eq 1 ]; then \ - echo stopping mattermost-mysql-e2e; \ - docker stop mattermost-mysql-e2e > /dev/null; \ - fi - - cd $(BUILD_SERVER_DIR) && [[ -f config/config-backup.json ]] && \ - cp config/config-backup.json config/config.json && echo "revert local config.json" || \ - echo "config-backup.json not found" && sed -i'' -e 's|"DataSource": ".*"|"DataSource": "mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s"|g' config/config.json - .PHONY: emojis emojis: ## Creates emoji JSON, JSX and Go files and extracts emoji images from the system font SERVER_DIR=$(BUILD_SERVER_DIR) npm run make-emojis diff --git a/webapp/channels/jest.config.js b/webapp/channels/jest.config.js index 123f6d7e57..01d80ffe8d 100644 --- a/webapp/channels/jest.config.js +++ b/webapp/channels/jest.config.js @@ -5,7 +5,7 @@ const config = { snapshotSerializers: ['enzyme-to-json/serializer'], - testPathIgnorePatterns: ['/node_modules/', '/e2e/'], + testPathIgnorePatterns: ['/node_modules/'], clearMocks: true, collectCoverageFrom: [ 'actions/src/**/*.{js,jsx,ts,tsx}', @@ -17,7 +17,6 @@ const config = { 'selectors/src/**/*.{js,jsx,ts,tsx}', 'stores/src/**/*.{js,jsx,ts,tsx}', 'utils/src/**/*.{js,jsx,ts,tsx}', - '!e2e/**', ], coverageReporters: ['lcov', 'text-summary'], moduleNameMapper: { diff --git a/webapp/channels/package.json b/webapp/channels/package.json index 7f33c6b05f..830cbfae08 100644 --- a/webapp/channels/package.json +++ b/webapp/channels/package.json @@ -169,7 +169,6 @@ "enzyme-to-json": "3.6.2", "eslint": "7.32.0", "eslint-import-resolver-webpack": "0.13.2", - "eslint-plugin-cypress": "2.11.3", "eslint-plugin-formatjs": "4.3.4", "eslint-plugin-header": "3.1.1", "eslint-plugin-import": "2.23.4", diff --git a/webapp/channels/src/actions/command.ts b/webapp/channels/src/actions/command.ts index 2b89fae193..62195ac6dc 100644 --- a/webapp/channels/src/actions/command.ts +++ b/webapp/channels/src/actions/command.ts @@ -35,7 +35,7 @@ import KeyboardShortcutsModal from 'components/keyboard_shortcuts/keyboard_short import {GlobalState} from 'types/store'; import {t} from 'utils/i18n'; -import MarketplaceModal from 'components/plugin_marketplace'; +import MarketplaceModal from 'components/plugin_marketplace/marketplace_modal'; import WorkTemplateModal from 'components/work_templates'; import {haveICurrentTeamPermission} from 'mattermost-redux/selectors/entities/roles'; import {Permissions} from 'mattermost-redux/constants'; diff --git a/webapp/channels/src/components/__snapshots__/generic_modal.test.tsx.snap b/webapp/channels/src/components/__snapshots__/generic_modal.test.tsx.snap index 95b80cb2da..cf1462ee4a 100644 --- a/webapp/channels/src/components/__snapshots__/generic_modal.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/generic_modal.test.tsx.snap @@ -59,7 +59,7 @@ exports[`components/GenericModal should match snapshot for base case 1`] = `
@@ -126,11 +126,12 @@ exports[`components/GenericModal should match snapshot with both buttons 1`] = `