summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore12
-rw-r--r--.travis.yml56
-rw-r--r--Makefile325
-rw-r--r--api/webhook.go113
-rw-r--r--config/config.json6
-rw-r--r--i18n/pt.json108
-rw-r--r--model/version.go8
-rw-r--r--webapp/components/about_build_modal.jsx6
-rw-r--r--webapp/components/admin_console/license_settings.jsx64
-rw-r--r--webapp/components/navbar.jsx11
-rw-r--r--webapp/i18n/en.json16
-rw-r--r--webapp/i18n/es.json8
-rw-r--r--webapp/i18n/pt.json56
-rw-r--r--webapp/package.json1
-rw-r--r--webapp/root.jsx27
-rw-r--r--webapp/utils/constants.jsx30
16 files changed, 482 insertions, 365 deletions
diff --git a/.gitignore b/.gitignore
index 4c343021e..422c6d5f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,14 +9,15 @@ npm-debug.log
web/static/js/bundle*.js
web/static/js/bundle*.js.map
web/static/js/libs*.js
-.npminstall
config/active.dat
+# Enteprise imports file
+imports.go
+
# Build Targets
-.prepare
-.prepare-go
-.prepare-jsx
+.prebuild
+.npminstall
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
@@ -69,6 +70,3 @@ api/data/*
.agignore
.ctags
tags
-
-model/version.go
-model/version.go.bak
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 71dcbefbc..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-language: generic
-sudo: required
-services:
-- docker
-env:
-- TRAVIS_DB=mysql
-- TRAVIS_DB=postgres
-before_install:
- - docker run --name mattermost-mysql -e MYSQL_ROOT_PASSWORD=mostest -e MYSQL_USER=mmuser -e MYSQL_PASSWORD=mostest -e MYSQL_DATABASE=mattermost_test -d mysql:5.7
- - docker run --name mattermost-postgres -e POSTGRES_USER=mmuser -e POSTGRES_PASSWORD=mostest -d postgres:9.4
- - sleep 10
- - docker exec mattermost-postgres psql -c 'create database mattermost_test ;' -U postgres
- - docker exec mattermost-postgres psql -c 'grant all privileges on database "mattermost_test" to mmuser ;' -U postgres
-script: make dist-travis
-addons:
- hosts:
- - 127.0.0.1 dockerhost
-after_success:
- - sudo chown -R `whoami` dist
- - sudo chmod -R 777 dist
- - cd dist && curl -F "pr_number=$TRAVIS_PULL_REQUEST" -F "file=@mattermost.tar.gz" mattermod.mattermost.com:8087/upload_pr_build
- - md5sum mattermost.tar.gz > mm.md5
- - sha1sum mattermost.tar.gz > mm.sha1
- - sha256sum mattermost.tar.gz > mm.sha256
- - cat mm.md5 mm.sha1 mm.sha256
- - cd ..
-before_deploy:
- - sudo rm -rf dist/mattermost
- - rvm 1.9.3 do gem install mime-types -v 2.6.2
-deploy:
-# Github releases, builds only on tags
- - provider: releases
- api_key:
- secure: ma8Y0oimU+LB6LTAh8to2E1/ghaDPhcsAFXBrODsHpd4JgxA6HYoEwSEBCJFHSpu/JteclsxSTfp9hcuzw/IOtlwlSAiVoBZ60s24MRKTIAQNtrJ4QrX5wyfAZi+Bcuk/E8NynmoIW5qpaElSAdjgocyjAJIQ5ChMEztglL0cAEBXQRWbWMqSZ0hVLPrKDCIkWIyv3pFxqdLOxktkzxW07r2dlT0hppXR3dCaPJo0nelArS2H3LdN/3Iv6cAddfS27RaZkqDj/PDh6OZr4EguC99TxlVNChIr7nPr3/OiAssbkvEnhlSLeABFO9+7KfutL2WhAjpFXTjtPVq6Qalc8UW0K0gxq//sVfhb1MzjenmdOf06uB2bilQ8kgwHo7dDdRZBqqAtxQ6Q0Ht3SFMj6v/1zVD3s+YX/kWCEbUTHm6r2G/eF794ozcJyU+6j1L8hm6mvf8Mr9XCqBfgpZy6FCLX+9OKdMvX2jY8reo3Xz1PA9R6yzhN08vjku+jW+fsoYrBLd0fY1UGK2uOuvBByCeJzXupd3YpBMjEyRupVxqEj7K0GWOJeml65mkqKSNsHdDSeSjMpb8mwneZyTbdjsxCFQRLcLgpAajFrkk4G2Yz3KfhXSo29XKEGX+EbY5NuP8KmDsBsguPI0zfwv/co0hAY8PIIcehxcdoR9Vb2c=
- file: dist/mattermost.tar.gz
- skip_cleanup: true
- on:
- repo: mattermost/platform
- tags: true
- condition: $TRAVIS_DB = mysql
-
-# S3 deploy for latest master
- - provider: s3
- access_key_id: AKIAJCO3KJYEGWJIKDIQ
- secret_access_key:
- secure: p66X2tJBmKgtcVyPtGgkAwW29IiRojqGA39RjCJkIWNTJ0e/9JvBOiMS2c4a7I4aOads38rsthwdaigBWagDWNH7bGsEZN7B0TszZuFAuU+XGjU5A66MIOfFfzbUg8AnByysr+XG5/bknFIrP/XhM2fbRr6gbYrFUK7TNkpgjFs5u3BzUrz2iTAV8uOpSJqKSnaf0pTZk1EywOK/X8W8ViIjc7Di3FzQcqIW9K3D27N+3rVsv8SRT1hWASVlnG6aThqqebiM8FCGCzAYVgQb3h3Wu8JT5fIz7Qo7A6siVRwNBwWwzP8HkGoinEK32Wsj/fDXk27vjpFQO/+9sV0xfcTbIZA6MnuYWF4rHOT59KcshCWCD3V0FopX57p/dtOzM9+6lxIctAT++izxWoZit/5c5A4633iY1d+RMeTko1POix6MSlxPMRHZUFwSXROgFuWWRpyD6TlUTCST9/wTTd0WDPklAAiYcnuEPW3qCnw0r0xkrA4AwWUXqXdAIwDt5bA27KcjRyY4Fofv9NxH09BNuBTXNPrvnYPZMmaKrv+HOX3NFTreuV6+5LJdhYUxYSBvSWo1jeWIQ5Q9RUdTU0PqmKpMhJKbKey/S4gxCXHg2HR8DwLCcbIZcvneF9yPEAT71YA6zpLKoPVSwWwH97huKSzjpic/RUfFXQOcgCQ=
- bucket: mattermost-travis-master
- local_dir: dist
- acl: public_read
- region: us-east-1
- skip_cleanup: true
- detect_encoding: true
- on:
- repo: mattermost/platform
- branch: master
- condition: $TRAVIS_DB = mysql
diff --git a/Makefile b/Makefile
index eb0bdc06f..5bb64638a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,47 +1,47 @@
-.PHONY: all dist dist-local dist-travis start-docker build-server package build-client test travis-init build-container stop-docker clean-docker clean nuke run run-client run-server stop stop-client stop-server setup-mac cleandb docker-build docker-run restart-server
+.PHONY: build package run stop run-client run-server stop-client stop-server restart-server restart-client start-docker clean-dist clean nuke check-style check-unit-tests test dist setup-mac prepare-enteprise
-GOPATH ?= $(GOPATH:)
-GOFLAGS ?= $(GOFLAGS:)
+# Build Flags
BUILD_NUMBER ?= $(BUILD_NUMBER:)
BUILD_DATE = $(shell date -u)
BUILD_HASH = $(shell git rev-parse HEAD)
-
-ENTERPRISE_DIR ?= ../enterprise
-BUILD_ENTERPRISE ?= true
-
-GO=$(GOPATH)/bin/godep go
-ESLINT=node_modules/eslint/bin/eslint.js
-
+# If we don't set the build number it defaults to dev
ifeq ($(BUILD_NUMBER),)
BUILD_NUMBER := dev
endif
-
-ifeq ($(TRAVIS_BUILD_NUMBER),)
- BUILD_NUMBER := dev
+BUILD_ENTERPRISE_DIR ?= ../enterprise
+BUILD_ENTERPRISE ?= true
+BUILD_ENTERPRISE_READY = false
+ifneq ($(wildcard $(BUILD_ENTERPRISE_DIR)/.),)
+ ifeq ($(BUILD_ENTERPRISE),true)
+ BUILD_ENTERPRISE_READY = true
+ else
+ BUILD_ENTERPRISE_READY = false
+ endif
else
- BUILD_NUMBER := $(TRAVIS_BUILD_NUMBER)
+ BUILD_ENTERPRISE_READY = false
endif
+BUILD_WEBAPP_DIR = ./webapp
+# Golang Flags
+GOPATH ?= $(GOPATH:)
+GOFLAGS ?= $(GOFLAGS:)
+GO=$(GOPATH)/bin/godep go
+GO_LINKER_FLAGS ?= -ldflags \
+ "-X github.com/mattermost/platform/model.BuildNumber=$(BUILD_NUMBER)\
+ -X 'github.com/mattermost/platform/model.BuildDate=$(BUILD_DATE)'\
+ -X github.com/mattermost/platform/model.BuildHash=$(BUILD_HASH)\
+ -X github.com/mattermost/platform/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)"
+
+# Output paths
DIST_ROOT=dist
DIST_PATH=$(DIST_ROOT)/mattermost
+# Tests
TESTS=.
-DOCKERNAME ?= mm-dev
-DOCKER_CONTAINER_NAME ?= mm-test
-
-all: dist-local
-
-dist: | build-server build-client go-test package
- mv ./model/version.go.bak ./model/version.go
- @if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
- mv ./mattermost.go.bak ./mattermost.go; \
- mv ./config/config.json.bak ./config/config.json 2> /dev/null || true; \
- fi
-
-dist-local: | start-docker dist
+all: dist
-dist-travis: | travis-init build-container
+dist: | check-style test package
start-docker:
@echo Starting docker containers
@@ -66,107 +66,6 @@ start-docker:
sleep 10; \
fi
-build-server:
- @echo Building mattermost server
-
- rm -Rf $(DIST_ROOT)
- $(GO) clean $(GOFLAGS) -i ./...
-
- @echo GOFMT
- $(eval GOFMT_OUTPUT := $(shell gofmt -d -s api/ model/ store/ utils/ manualtesting/ mattermost.go 2>&1))
- @echo "$(GOFMT_OUTPUT)"
- @if [ ! "$(GOFMT_OUTPUT)" ]; then \
- echo "gofmt sucess"; \
- else \
- echo "gofmt failure"; \
- exit 1; \
- fi
-
- cp ./model/version.go ./model/version.go.bak
- sed -i'.make_mac_work' 's|_BUILD_NUMBER_|$(BUILD_NUMBER)|g' ./model/version.go
- sed -i'.make_mac_work' 's|_BUILD_DATE_|$(BUILD_DATE)|g' ./model/version.go
- sed -i'.make_mac_work' 's|_BUILD_HASH_|$(BUILD_HASH)|g' ./model/version.go
-
- @if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
- cp ./config/config.json ./config/config.json.bak; \
- jq -s '.[0] * .[1]' ./config/config.json $(ENTERPRISE_DIR)/config/enterprise-config-additions.json > config.json.tmp; \
- mv config.json.tmp ./config/config.json; \
- sed -e '/\/\/ENTERPRISE_IMPORTS/ {' -e 'r $(ENTERPRISE_DIR)/imports' -e 'd' -e '}' -i'.bak' mattermost.go; \
- sed -i'.make_mac_work' 's|_BUILD_ENTERPRISE_READY_|true|g' ./model/version.go; \
- else \
- sed -i'.make_mac_work' 's|_BUILD_ENTERPRISE_READY_|false|g' ./model/version.go; \
- fi
-
- rm ./model/version.go.make_mac_work
-
- $(GO) build $(GOFLAGS) ./...
- $(GO) generate $(GOFLAGS) ./...
- $(GO) install $(GOFLAGS) ./...
-
-package:
- @ echo Packaging mattermost
-
- mkdir -p $(DIST_PATH)/bin
- cp $(GOPATH)/bin/platform $(DIST_PATH)/bin
-
- cp -RL config $(DIST_PATH)/config
- cp -RL fonts $(DIST_PATH)/fonts
- touch $(DIST_PATH)/config/build.txt
- echo $(BUILD_NUMBER) | tee -a $(DIST_PATH)/config/build.txt
-
- mkdir -p $(DIST_PATH)/logs
-
- mkdir -p $(DIST_PATH)/webapp/dist
- cp -RL webapp/dist $(DIST_PATH)/webapp
-
- cp -RL templates $(DIST_PATH)
-
- cp -RL i18n $(DIST_PATH)
-
- cp build/MIT-COMPILED-LICENSE.md $(DIST_PATH)
- cp NOTICE.txt $(DIST_PATH)
- cp README.md $(DIST_PATH)
-
- mv $(DIST_PATH)/webapp/dist/bundle.js $(DIST_PATH)/webapp/dist/bundle-$(BUILD_NUMBER).js
- sed -i'.bak' 's|bundle.js|bundle-$(BUILD_NUMBER).js|g' $(DIST_PATH)/webapp/dist/root.html
- rm $(DIST_PATH)/webapp/dist/root.html.bak
-
- @if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
- sudo mv -f $(DIST_PATH)/config/config.json.bak $(DIST_PATH)/config/config.json || echo 'nomv'; \
- fi
-
- tar -C dist -czf $(DIST_PATH).tar.gz mattermost
-
-build-client:
- mkdir -p webapp/dist/files
- cd webapp && make build
-
-go-test:
- $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1
- $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1
- $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1
- $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1
- $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1
-
-test: | start-docker .prepare-go go-test
-
-travis-init:
- @echo Setting up enviroment for travis
-
- if [ "$(TRAVIS_DB)" = "postgres" ]; then \
- sed -i'.bak' 's|mysql|postgres|g' config/config.json; \
- sed -i'.bak2' 's|mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8|postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable\&connect_timeout=10|g' config/config.json; \
- fi
-
- if [ "$(TRAVIS_DB)" = "mysql" ]; then \
- sed -i'.bak' 's|mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8|mmuser:mostest@tcp(mysql:3306)/mattermost_test?charset=utf8mb4,utf8|g' config/config.json; \
- fi
-
-build-container:
- @echo Building in container
-
- cd .. && docker run -e TRAVIS_BUILD_NUMBER=$(TRAVIS_BUILD_NUMBER) --link mattermost-mysql:mysql --link mattermost-postgres:postgres -v `pwd`:/go/src/github.com/mattermost mattermost/builder:latest
-
stop-docker:
@echo Stopping docker containers
@@ -195,92 +94,144 @@ clean-docker:
docker rm -v mattermost-postgres > /dev/null; \
fi
-clean: stop-docker
- rm -Rf $(DIST_ROOT)
- go clean $(GOFLAGS) -i ./...
+check-style:
+ @echo Running GOFMT
+ $(eval GOFMT_OUTPUT := $(shell gofmt -d -s api/ model/ store/ utils/ manualtesting/ einterfaces/ mattermost.go 2>&1))
+ @echo "$(GOFMT_OUTPUT)"
+ @if [ ! "$(GOFMT_OUTPUT)" ]; then \
+ echo "gofmt sucess"; \
+ else \
+ echo "gofmt failure"; \
+ exit 1; \
+ fi
- cd webapp && make clean
+test: start-docker
+ $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1
+ $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=12s ./model || exit 1
+ $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./store || exit 1
+ $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./utils || exit 1
+ $(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=120s ./web || exit 1
- rm -rf api/data
- rm -rf logs
+.prebuild:
+ @echo Preparation for running go code
+ go get $(GOFLAGS) github.com/tools/godep
- rm -rf Godeps/_workspace/pkg/
+ touch $@
- rm -f mattermost.log
- rm -f .prepare-go .prepare-jsx
+prepare-enterprise:
+ifeq ($(BUILD_ENTERPRISE_READY),true)
+ @echo Enterprise build selected, perparing
+ cp $(BUILD_ENTERPRISE_DIR)/imports.go .
+endif
-nuke: | clean clean-docker
- rm -rf data
+build: .prebuild prepare-enterprise
+ @echo Building mattermost server
-.prepare-go:
- @echo Preparation for running go code
- go get $(GOFLAGS) github.com/tools/godep
+ $(GO) clean $(GOFLAGS) -i ./...
+ $(GO) install $(GOFLAGS) $(GO_LINKER_FLAGS) ./...
- touch $@
+build-client:
+ @echo Building mattermost web app
-run: | start-docker run-server run-client
+ cd $(BUILD_WEBAPP_DIR) && make build
-run-server: .prepare-go
- @echo Starting go web server
- mkdir -p webapp/dist/files
- $(GO) run $(GOFLAGS) mattermost.go -config=config.json &
-run-client:
- @echo Starting client
+package: build build-client
+ @ echo Packaging mattermost
- cd webapp && make run
+ # Remove any old files
+ rm -Rf $(DIST_ROOT)
- @if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
- cp ./config/config.json ./config/config.json.bak; \
- jq -s '.[0] * .[1]' ./config/config.json $(ENTERPRISE_DIR)/config/enterprise-config-additions.json > config.json.tmp; \
- mv config.json.tmp ./config/config.json; \
- sed -e '/\/\/ENTERPRISE_IMPORTS/ {' -e 'r $(ENTERPRISE_DIR)/imports' -e 'd' -e '}' -i'.bak' mattermost.go; \
- sed -i'.bak' 's|_BUILD_ENTERPRISE_READY_|true|g' ./model/version.go; \
- else \
- sed -i'.bak' 's|_BUILD_ENTERPRISE_READY_|false|g' ./model/version.go; \
- fi
+ # Create needed directories
+ mkdir -p $(DIST_PATH)/bin
+ mkdir -p $(DIST_PATH)/logs
-stop: stop-server stop-client
- @if [ $(shell docker ps -a | grep -ci ${DOCKER_CONTAINER_NAME}) -eq 1 ]; then \
- echo removing dev docker container; \
- docker stop ${DOCKER_CONTAINER_NAME} > /dev/null; \
- docker rm -v ${DOCKER_CONTAINER_NAME} > /dev/null; \
- fi
+ # Copy binary
+ cp $(GOPATH)/bin/platform $(DIST_PATH)/bin
- @if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
- mv ./config/config.json.bak ./config/config.json 2> /dev/null || true; \
- mv ./mattermost.go.bak ./mattermost.go 2> /dev/null || true; \
- mv ./model/version.go.bak ./model/version.go 2> /dev/null || true; \
- fi
+ # Resource directories
+ cp -RL config $(DIST_PATH)
+ cp -RL fonts $(DIST_PATH)
+ cp -RL templates $(DIST_PATH)
+ cp -RL i18n $(DIST_PATH)
+
+ # Package webapp
+ mkdir -p $(DIST_PATH)/webapp/dist
+ cp -RL $(BUILD_WEBAPP_DIR)/dist $(DIST_PATH)/webapp
+ mv $(DIST_PATH)/webapp/dist/bundle.js $(DIST_PATH)/webapp/dist/bundle-$(BUILD_NUMBER).js
+ sed -i'.bak' 's|bundle.js|bundle-$(BUILD_NUMBER).js|g' $(DIST_PATH)/webapp/dist/root.html
+ rm $(DIST_PATH)/webapp/dist/root.html.bak
+
+ # Help files
+ifeq ($(BUILD_ENTERPRISE_READY),true)
+ cp $(BUILD_ENTERPRISE_DIR)/ENTERPRISE-EDITION-LICENSE.txt $(DIST_PATH)
+else
+ cp build/MIT-COMPILED-LICENSE.md $(DIST_PATH)
+endif
+ cp NOTICE.txt $(DIST_PATH)
+ cp README.md $(DIST_PATH)
+
+ # Create package
+ tar -C dist -czf $(DIST_PATH).tar.gz mattermost
+
+run-server: prepare-enterprise
+ @echo Running mattermost for development
+
+ mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
+ $(GO) run $(GOFLAGS) $(GO_LINKER_FLAGS) *.go &
+
+run-client:
+ @echo Running mattermost client for development
+
+ cd $(BUILD_WEBAPP_DIR) && make run
+
+run: run-server run-client
stop-server:
- @for PID in $$(ps -ef | grep "go run [m]attermost.go" | awk '{ print $$2 }'); do \
+ @echo Stopping mattermost
+
+ @for PID in $$(ps -ef | grep "[g]o run" | awk '{ print $$2 }'); do \
echo stopping go $$PID; \
kill $$PID; \
done
- @for PID in $$(ps -ef | grep "go-build.*/[m]attermost" | awk '{ print $$2 }'); do \
+ @for PID in $$(ps -ef | grep "[g]o-build" | awk '{ print $$2 }'); do \
echo stopping mattermost $$PID; \
kill $$PID; \
done
stop-client:
- cd webapp && make stop
+ @echo Stopping mattermost client
-restart-server: stop-server run-server
+ cd $(BUILD_WEBAPP_DIR) && make stop
-setup-mac:
- echo $$(boot2docker ip 2> /dev/null) dockerhost | sudo tee -a /etc/hosts
-cleandb:
- @if [ $(shell docker ps -a | grep -ci mattermost-mysql) -eq 1 ]; then \
- docker stop mattermost-mysql > /dev/null; \
- docker rm -v mattermost-mysql > /dev/null; \
- fi
+stop: stop-server stop-client
+
+restart-server: | stop-server run-server
+
+restart-client: | stop-client run-client
+
+clean: stop-docker
+ @echo Cleaning
+
+ rm -Rf $(DIST_ROOT)
+ go clean $(GOFLAGS) -i ./...
+
+ cd $(BUILD_WEBAPP_DIR) && make clean
-docker-build: stop
- docker build -t ${DOCKERNAME} -f docker/local/Dockerfile .
+ rm -rf api/data
+ rm -rf logs
+
+ rm -rf Godeps/_workspace/pkg/
+
+ rm -f mattermost.log
+ rm -f .prepare-go
+
+nuke: clean clean-docker
+ @echo BOOM
-docker-run: docker-build
- docker run --name ${DOCKER_CONTAINER_NAME} -d --publish 8065:80 ${DOCKERNAME}
+ rm -rf data
+setup-mac:
+ echo $$(boot2docker ip 2> /dev/null) dockerhost | sudo tee -a /etc/hosts
diff --git a/api/webhook.go b/api/webhook.go
index c0f8ea506..fe1aa1175 100644
--- a/api/webhook.go
+++ b/api/webhook.go
@@ -4,11 +4,14 @@
package api
import (
+ "net/http"
+ "strings"
+
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
- "net/http"
)
func InitWebhook(r *mux.Router) {
@@ -23,6 +26,12 @@ func InitWebhook(r *mux.Router) {
sr.Handle("/outgoing/regen_token", ApiUserRequired(regenOutgoingHookToken)).Methods("POST")
sr.Handle("/outgoing/delete", ApiUserRequired(deleteOutgoingHook)).Methods("POST")
sr.Handle("/outgoing/list", ApiUserRequired(getOutgoingHooks)).Methods("GET")
+
+ sr.Handle("/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
+
+ // Old route. Remove eventually.
+ mr := Srv.Router
+ mr.Handle("/hooks/{id:[A-Za-z0-9]+}", ApiAppHandler(incomingWebhook)).Methods("POST")
}
func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -330,3 +339,105 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
w.Write([]byte(result.Data.(*model.OutgoingWebhook).ToJson()))
}
}
+
+func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
+ if !utils.Cfg.ServiceSettings.EnableIncomingWebhooks {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.disabled.app_error", nil, "")
+ c.Err.StatusCode = http.StatusNotImplemented
+ return
+ }
+
+ params := mux.Vars(r)
+ id := params["id"]
+
+ hchan := Srv.Store.Webhook().GetIncoming(id)
+
+ r.ParseForm()
+
+ var parsedRequest *model.IncomingWebhookRequest
+ contentType := r.Header.Get("Content-Type")
+ if strings.Split(contentType, "; ")[0] == "application/json" {
+ parsedRequest = model.IncomingWebhookRequestFromJson(r.Body)
+ } else {
+ parsedRequest = model.IncomingWebhookRequestFromJson(strings.NewReader(r.FormValue("payload")))
+ }
+
+ if parsedRequest == nil {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.parse.app_error", nil, "")
+ return
+ }
+
+ text := parsedRequest.Text
+ if len(text) == 0 && parsedRequest.Attachments == nil {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.text.app_error", nil, "")
+ return
+ }
+
+ channelName := parsedRequest.ChannelName
+ webhookType := parsedRequest.Type
+
+ //attachments is in here for slack compatibility
+ if parsedRequest.Attachments != nil {
+ if len(parsedRequest.Props) == 0 {
+ parsedRequest.Props = make(model.StringInterface)
+ }
+ parsedRequest.Props["attachments"] = parsedRequest.Attachments
+ webhookType = model.POST_SLACK_ATTACHMENT
+ }
+
+ var hook *model.IncomingWebhook
+ if result := <-hchan; result.Err != nil {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.invalid.app_error", nil, "err="+result.Err.Message)
+ return
+ } else {
+ hook = result.Data.(*model.IncomingWebhook)
+ }
+
+ var channel *model.Channel
+ var cchan store.StoreChannel
+
+ if len(channelName) != 0 {
+ if channelName[0] == '@' {
+ if result := <-Srv.Store.User().GetByUsername(hook.TeamId, channelName[1:]); result.Err != nil {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.user.app_error", nil, "err="+result.Err.Message)
+ return
+ } else {
+ channelName = model.GetDMNameFromIds(result.Data.(*model.User).Id, hook.UserId)
+ }
+ } else if channelName[0] == '#' {
+ channelName = channelName[1:]
+ }
+
+ cchan = Srv.Store.Channel().GetByName(hook.TeamId, channelName)
+ } else {
+ cchan = Srv.Store.Channel().Get(hook.ChannelId)
+ }
+
+ overrideUsername := parsedRequest.Username
+ overrideIconUrl := parsedRequest.IconURL
+
+ if result := <-cchan; result.Err != nil {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message)
+ return
+ } else {
+ channel = result.Data.(*model.Channel)
+ }
+
+ pchan := Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
+
+ // create a mock session
+ c.Session = model.Session{UserId: hook.UserId, TeamId: hook.TeamId, IsOAuth: false}
+
+ if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
+ c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.permissions.app_error", nil, "")
+ return
+ }
+
+ if _, err := CreateWebhookPost(c, channel.Id, text, overrideUsername, overrideIconUrl, parsedRequest.Props, webhookType); err != nil {
+ c.Err = err
+ return
+ }
+
+ w.Header().Set("Content-Type", "text/plain")
+ w.Write([]byte("ok"))
+}
diff --git a/config/config.json b/config/config.json
index 1735ca293..65a61bb72 100644
--- a/config/config.json
+++ b/config/config.json
@@ -87,8 +87,8 @@
"InviteSalt": "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9YoS",
"PasswordResetSalt": "vZ4DcKyVVRlKHHJpexcuXzojkE5PZ5eL",
"SendPushNotifications": false,
- "PushNotificationContents": "generic",
- "PushNotificationServer": ""
+ "PushNotificationServer": "",
+ "PushNotificationContents": "generic"
},
"RateLimitSettings": {
"EnableRateLimiter": true,
@@ -146,4 +146,4 @@
"Directory": "./data/",
"EnableDaily": false
}
-}
+} \ No newline at end of file
diff --git a/i18n/pt.json b/i18n/pt.json
index c59eb896b..15bc42835 100644
--- a/i18n/pt.json
+++ b/i18n/pt.json
@@ -1016,6 +1016,10 @@
"translation": "Somente um administrador de equipe pode exportar os dados."
},
{
+ "id": "api.team.get_invite_info.not_open_team",
+ "translation": "Convite é inválido devido a este não ser de uma equipe aberta."
+ },
+ {
"id": "api.team.import_team.admin.app_error",
"translation": "Somente um administrador de equipe pode importar dados."
},
@@ -1704,6 +1708,26 @@
"translation": "Permissões inadequadas para re-gerar o token do webhook de saída"
},
{
+ "id": "ent.compliance.licence_disable.app_error",
+ "translation": "Funcionalidade Compliance desabilitada pela licença atual. Entre em contato com o administrador do sistema sobre como atualizar sua licença de empresa."
+ },
+ {
+ "id": "ent.compliance.run_failed.error",
+ "translation": "Falha na tarefa '{{.JobName}}' para exportar o compliance no '{{.FilePath}}'"
+ },
+ {
+ "id": "ent.compliance.run_finished.info",
+ "translation": "Exportação do compliance terminado para tarefa '{{.JobName}}' exportado {{.Count}} registros para '{{.FilePath}}'"
+ },
+ {
+ "id": "ent.compliance.run_limit.warning",
+ "translation": "Aviso exportação do compliance na tarefa '{{.JobName}}' retornando muitos registros truncando para 30.000 em '{{.FilePath}}'"
+ },
+ {
+ "id": "ent.compliance.run_started.info",
+ "translation": "Exportação de compliance tarefa '{{.JobName}}' iniciada no '{{.FilePath}}'"
+ },
+ {
"id": "ent.ldap.do_login.bind_admin_user.app_error",
"translation": "Não foi possível ligar ao servidor LDAP. Verifique BindUsername e BindPassword."
},
@@ -1841,7 +1865,7 @@
},
{
"id": "model.authorize.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.authorize.is_valid.expires.app_error",
@@ -1869,7 +1893,7 @@
},
{
"id": "model.channel.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.channel.is_valid.creator_id.app_error",
@@ -1901,7 +1925,7 @@
},
{
"id": "model.channel.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.channel_member.is_valid.channel_id.app_error",
@@ -1933,7 +1957,7 @@
},
{
"id": "model.command.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.command.is_valid.id.app_error",
@@ -1957,7 +1981,7 @@
},
{
"id": "model.command.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.command.is_valid.url.app_error",
@@ -1972,6 +1996,30 @@
"translation": "ID de usuário inválido"
},
{
+ "id": "model.compliance.is_valid.create_at.app_error",
+ "translation": "Create deve ser um tempo válido"
+ },
+ {
+ "id": "model.compliance.is_valid.desc.app_error",
+ "translation": "Descrição inválida"
+ },
+ {
+ "id": "model.compliance.is_valid.end_at.app_error",
+ "translation": "Para precisa ser um tempo válido"
+ },
+ {
+ "id": "model.compliance.is_valid.id.app_error",
+ "translation": "ID inválida"
+ },
+ {
+ "id": "model.compliance.is_valid.start_at.app_error",
+ "translation": "De precisa ser um tempo válido"
+ },
+ {
+ "id": "model.compliance.is_valid.start_end_at.app_error",
+ "translation": "Para precisa ser maior que De"
+ },
+ {
"id": "model.config.is_valid.email_reset_salt.app_error",
"translation": "Senha inválida redefinir salt nas configurações de email. Deve ser de 32 caracteres ou mais."
},
@@ -2065,7 +2113,7 @@
},
{
"id": "model.incoming_hook.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.incoming_hook.id.app_error",
@@ -2077,7 +2125,7 @@
},
{
"id": "model.incoming_hook.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.incoming_hook.user_id.app_error",
@@ -2097,7 +2145,7 @@
},
{
"id": "model.oauth.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.oauth.is_valid.creator_id.app_error",
@@ -2117,7 +2165,7 @@
},
{
"id": "model.oauth.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.outgoing_hook.is_valid.callback.app_error",
@@ -2129,7 +2177,7 @@
},
{
"id": "model.outgoing_hook.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.outgoing_hook.is_valid.id.app_error",
@@ -2145,7 +2193,7 @@
},
{
"id": "model.outgoing_hook.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.outgoing_hook.is_valid.url.app_error",
@@ -2165,7 +2213,7 @@
},
{
"id": "model.post.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.post.is_valid.filenames.app_error",
@@ -2209,7 +2257,7 @@
},
{
"id": "model.post.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.post.is_valid.user_id.app_error",
@@ -2241,7 +2289,7 @@
},
{
"id": "model.team.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.team.is_valid.domains.app_error",
@@ -2269,7 +2317,7 @@
},
{
"id": "model.team.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.team.is_valid.url.app_error",
@@ -2289,7 +2337,7 @@
},
{
"id": "model.user.is_valid.create_at.app_error",
- "translation": "Deve-se criar em um tempo válido"
+ "translation": "Create deve ser um tempo válido"
},
{
"id": "model.user.is_valid.email.app_error",
@@ -2325,7 +2373,7 @@
},
{
"id": "model.user.is_valid.update_at.app_error",
- "translation": "Deve-se atualizar em um tempo válido"
+ "translation": "Update deve ser um tempo válido"
},
{
"id": "model.user.is_valid.username.app_error",
@@ -2704,6 +2752,14 @@
"translation": "Não foi possível atualizar o comando"
},
{
+ "id": "store.sql_compliance.get.finding.app_error",
+ "translation": "Encontramos um erro ao obter o relatório de compliance"
+ },
+ {
+ "id": "store.sql_compliance.save.saving.app_error",
+ "translation": "Encontramos um erro ao salvar o relatório de compliance"
+ },
+ {
"id": "store.sql_license.get.app_error",
"translation": "Encontramos um erro ao obter a licença"
},
@@ -2800,6 +2856,10 @@
"translation": "Não foi possível obter o número de posts"
},
{
+ "id": "store.sql_post.compliance_export.app_error",
+ "translation": "Não foi possível obter os posts para exportação compliance"
+ },
+ {
"id": "store.sql_post.delete.app_error",
"translation": "Não foi possível deletar o post"
},
@@ -3076,6 +3136,10 @@
"translation": "Não foi possível encontrar uma conta correspondente ao seu tipo de autenticação para esta equipe. Esta equipe pode exigir um convite do dono da equipe para participar."
},
{
+ "id": "store.sql_user.get_by_auth.other.app_error",
+ "translation": "Foi encontrado um erro ao tentar encontrar a conta pelo tipo de autenticação."
+ },
+ {
"id": "store.sql_user.get_by_username.app_error",
"translation": "Não foi possível encontrar uma conta correspondente ao seu usuário para esta equipe. Esta equipe pode exigir um convite do dono da equipe para participar."
},
@@ -3100,6 +3164,10 @@
"translation": "Não foi possível contar os usuários"
},
{
+ "id": "store.sql_user.get_unread_count.app_error",
+ "translation": "Não foi possível obter o número de mensagens não lidas para o usuário"
+ },
+ {
"id": "store.sql_user.missing_account.const",
"translation": "Não foi possível encontrar uma conta correspondente ao seu endereço de email para esta equipe. Esta equipe pode exigir um convite do dono da equipe para participar."
},
@@ -3590,9 +3658,5 @@
{
"id": "web.watcher_fail.error",
"translation": "Falha ao adicionar diretório observador %v"
- },
- {
- "id": "api.team.get_invite_info.not_open_team",
- "translation": "Convite é inválido devido a este não ser de uma equipe aberta."
}
-]
+] \ No newline at end of file
diff --git a/model/version.go b/model/version.go
index 737071934..b3950dcc9 100644
--- a/model/version.go
+++ b/model/version.go
@@ -28,10 +28,10 @@ var versions = []string{
}
var CurrentVersion string = versions[0]
-var BuildNumber = "_BUILD_NUMBER_"
-var BuildDate = "_BUILD_DATE_"
-var BuildHash = "_BUILD_HASH_"
-var BuildEnterpriseReady = "_BUILD_ENTERPRISE_READY_"
+var BuildNumber string
+var BuildDate string
+var BuildHash string
+var BuildEnterpriseReady string
var versionsWithoutHotFixes []string
func init() {
diff --git a/webapp/components/about_build_modal.jsx b/webapp/components/about_build_modal.jsx
index e2fefc44e..e73d842d0 100644
--- a/webapp/components/about_build_modal.jsx
+++ b/webapp/components/about_build_modal.jsx
@@ -24,7 +24,7 @@ export default class AboutBuildModal extends React.Component {
let title = (
<FormattedMessage
id='about.teamEditiont0'
- defaultMessage='Team Edition T0'
+ defaultMessage='Team Edition'
/>
);
@@ -33,14 +33,14 @@ export default class AboutBuildModal extends React.Component {
title = (
<FormattedMessage
id='about.teamEditiont1'
- defaultMessage='Team Edition T1'
+ defaultMessage='Enterprise Edition'
/>
);
if (license.IsLicensed === 'true') {
title = (
<FormattedMessage
id='about.enterpriseEditione1'
- defaultMessage='Enterprise Edition E1'
+ defaultMessage='Enterprise Edition'
/>
);
licensee = (
diff --git a/webapp/components/admin_console/license_settings.jsx b/webapp/components/admin_console/license_settings.jsx
index 5aa0dba7e..ad310d8e0 100644
--- a/webapp/components/admin_console/license_settings.jsx
+++ b/webapp/components/admin_console/license_settings.jsx
@@ -105,36 +105,27 @@ class LicenseSettings extends React.Component {
let licenseType;
let licenseKey;
+ const issued = Utils.displayDate(parseInt(global.window.mm_license.IssuedAt, 10)) + ' ' + Utils.displayTime(parseInt(global.window.mm_license.IssuedAt, 10), true);
+ const startsAt = Utils.displayDate(parseInt(global.window.mm_license.StartsAt, 10));
+ const expiresAt = Utils.displayDate(parseInt(global.window.mm_license.ExpiresAt, 10));
+
if (global.window.mm_license.IsLicensed === 'true') {
- edition = (
- <FormattedMessage
- id='admin.license.enterpriseEdition'
- defaultMessage='Mattermost Enterprise Edition. Designed for enterprise-scale communication.'
- />
- );
+ // Note: DO NOT LOCALISE THESE STRINGS. Legally we can not since the license is in English.
+ edition = 'Mattermost Enterprise Edition. Enterprise features on this server have been unlocked with a license key and a valid subscription.';
licenseType = (
- <FormattedHTMLMessage
- id='admin.license.enterpriseType'
- values={{
- terms: global.window.mm_config.TermsOfServiceLink,
- name: global.window.mm_license.Name,
- company: global.window.mm_license.Company,
- users: global.window.mm_license.Users,
- issued: Utils.displayDate(parseInt(global.window.mm_license.IssuedAt, 10)) + ' ' + Utils.displayTime(parseInt(global.window.mm_license.IssuedAt, 10), true),
- start: Utils.displayDate(parseInt(global.window.mm_license.StartsAt, 10)),
- expires: Utils.displayDate(parseInt(global.window.mm_license.ExpiresAt, 10)),
- ldap: global.window.mm_license.LDAP
- }}
- defaultMessage='<div><p>This compiled release of Mattermost platform is provided under a <a href="http://mattermost.com" target="_blank">commercial license</a> from Mattermost, Inc. based on your subscription level and is subject to the <a href="{terms}" target="_blank">Terms of Service.</a></p>
- <p>Your subscription details are as follows:</p>
- Name: {name}<br />
- Company or organization name: {company}<br/>
- Number of users: {users}<br/>
- License issued: {issued}<br/>
- Start date of license: {start}<br/>
- Expiry date of license: {expires}<br/>
- LDAP: {ldap}<br/></div>'
- />
+ <div>
+ <p>
+ {'This software is offered under a commercial license.\n\nSee ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. See NOTICE.txt for information about open source software used in this system.\n\nYour subscription details are as follows:'}
+ </p>
+ {`Name: ${global.window.mm_license.Name}`}<br/>
+ {`Company or organization name: ${global.window.mm_license.Company}`}<br/>
+ {`Number of users: ${global.window.mm_license.Users}`}<br/>
+ {`License issued: ${issued}`}<br/>
+ {`Start date of license: ${startsAt}`}<br/>
+ {`Expiry date of license: ${expiresAt}`}<br/>
+ <br/>
+ {'See also '}<a href='https://about.mattermost.com/enterprise-edition-terms/'>{'Enterprise Edition Terms of Service'}</a>{' and '}<a href='https://about.mattermost.com/privacy/'>{'Privacy Policy.'}</a>
+ </div>
);
licenseKey = (
@@ -162,20 +153,15 @@ class LicenseSettings extends React.Component {
</div>
);
} else {
+ // Note: DO NOT LOCALISE THESE STRINGS. Legally we can not since the license is in English.
edition = (
- <FormattedMessage
- id='admin.license.teamEdition'
- defaultMessage='Mattermost Team Edition. Designed for teams from 5 to 50 users.'
- />
+ <p>
+ {'Mattermost Enterprise Edition. Unlock enterprise features in this software through the purchase of a subscription from '}
+ <a href='https://mattermost.com/'>{'https://mattermost.com/'}</a>
+ </p>
);
- licenseType = (
- <FormattedHTMLMessage
- id='admin.license.teamType'
- defaultMessage='<span><p>This compiled release of Mattermost platform is offered under an MIT license.</p>
- <p>See MIT-COMPILED-LICENSE.txt in your root install directory for details. See NOTICES.txt for information about open source software used in this system.</p></span>'
- />
- );
+ licenseType = 'This software is offered under a commercial license.\n\nSee ENTERPRISE-EDITION-LICENSE.txt in your root install directory for details. See NOTICE.txt for information about open source software used in this system.';
let fileName;
if (this.state.fileName) {
diff --git a/webapp/components/navbar.jsx b/webapp/components/navbar.jsx
index fb3b25957..520f05ed0 100644
--- a/webapp/components/navbar.jsx
+++ b/webapp/components/navbar.jsx
@@ -8,6 +8,7 @@ import MessageWrapper from './message_wrapper.jsx';
import NotifyCounts from './notify_counts.jsx';
import ChannelInfoModal from './channel_info_modal.jsx';
import ChannelInviteModal from './channel_invite_modal.jsx';
+import ChannelMembersModal from './channel_members_modal.jsx';
import ChannelNotificationsModal from './channel_notifications_modal.jsx';
import DeleteChannelModal from './delete_channel_modal.jsx';
import RenameChannelModal from './rename_channel_modal.jsx';
@@ -433,6 +434,7 @@ export default class Navbar extends React.Component {
var editChannelHeaderModal = null;
var editChannelPurposeModal = null;
let renameChannelModal = null;
+ let channelMembersModal = null;
if (channel) {
popoverContent = (
@@ -523,6 +525,14 @@ export default class Navbar extends React.Component {
channel={channel}
/>
);
+
+ channelMembersModal = (
+ <ChannelMembersModal
+ show={this.state.showMembersModal}
+ onModalDismissed={() => this.setState({showMembersModal: false})}
+ channel={channel}
+ />
+ );
}
var collapseButtons = this.createCollapseButtons(currentId);
@@ -556,6 +566,7 @@ export default class Navbar extends React.Component {
{editChannelHeaderModal}
{editChannelPurposeModal}
{renameChannelModal}
+ {channelMembersModal}
</div>
);
}
diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json
index 9b44f9abd..d9411df07 100644
--- a/webapp/i18n/en.json
+++ b/webapp/i18n/en.json
@@ -1,12 +1,12 @@
{
"about.close": "Close",
"about.date": "Build Date:",
- "about.enterpriseEditione1": "Enterprise Edition E1",
+ "about.enterpriseEditione1": "Enterprise Edition",
"about.hash": "Build Hash:",
"about.licensed": "Licensed by:",
"about.number": "Build Number:",
- "about.teamEditiont0": "Team Edition T0",
- "about.teamEditiont1": "Team Edition T1",
+ "about.teamEditiont0": "Team Edition",
+ "about.teamEditiont1": "Enterprise Edition",
"about.title": "About Mattermost",
"about.version": "Version:",
"access_history.title": "Access History",
@@ -230,15 +230,9 @@
"admin.ldap.usernameAttrTitle": "Username Attribute:",
"admin.licence.keyMigration": "If you’re migrating servers you may need to remove your license key from this server in order to install it on a new server. To start, <a href=\"http://mattermost.com\" target=\"_blank\">disable all Enterprise Edition features on this server</a>. This will enable the ability to remove the license key and downgrade this server from Enterprise Edition to Team Edition.",
"admin.license.chooseFile": "Choose File",
- "admin.license.edition": "Edition: ",
- "admin.license.enterpriseEdition": "Mattermost Enterprise Edition. Designed for enterprise-scale communication.",
- "admin.license.enterpriseType": "<div><p>This compiled release of Mattermost platform is provided under a <a href=\"http://mattermost.com\" target=\"_blank\">commercial license</a> from Mattermost, Inc. based on your subscription level and is subject to the <a href=\"{terms}\" target=\"_blank\">Terms of Service.</a></p><p>Your subscription details are as follows:</p>Name: {name}<br />Company or organization name: {company}<br/>Number of users: {users}<br/>License issued: {issued}<br/>Start date of license: {start}<br/>Expiry date of license: {expires}<br/>LDAP: {ldap}<br/></div>",
- "admin.license.key": "License Key: ",
"admin.license.keyRemove": "Remove Enterprise License and Downgrade Server",
"admin.license.noFile": "No file uploaded",
"admin.license.removing": "Removing License...",
- "admin.license.teamEdition": "Mattermost Team Edition. Designed for teams from 5 to 50 users.",
- "admin.license.teamType": "<span><p>This compiled release of Mattermost platform is offered under an MIT license.</p><p>See MIT-COMPILED-LICENSE.txt in your root install directory for details. See NOTICES.txt for information about open source software used in this system.</p></span>",
"admin.license.title": "Edition and License",
"admin.license.type": "License: ",
"admin.license.upload": "Upload",
@@ -416,6 +410,8 @@
"admin.support.emailTitle": "Support email:",
"admin.support.helpDesc": "Link to help documentation from team site main menu. Typically not changed unless your organization chooses to create custom documentation.",
"admin.support.helpTitle": "Help link:",
+ "admin.support.noteDescription": "If linking to an external site, URLs should begin with http:// or https://.",
+ "admin.support.noteTitle": "Note:",
"admin.support.privacyDesc": "Link to Privacy Policy available to users on desktop and on mobile. Leaving this blank will hide the option to display a notice.",
"admin.support.privacyTitle": "Privacy Policy link:",
"admin.support.problemDesc": "Link to help documentation from team site main menu. By default this points to the peer-to-peer troubleshooting forum where users can search for, find and request help with technical issues.",
@@ -425,8 +421,6 @@
"admin.support.termsDesc": "Link to Terms of Service available to users on desktop and on mobile. Leaving this blank will hide the option to display a notice.",
"admin.support.termsTitle": "Terms of Service link:",
"admin.support.title": "Legal and Support Settings",
- "admin.support.noteTitle": "Note:",
- "admin.support.noteDescription": "If linking to an external site, URLs should begin with http:// or https://.",
"admin.system_analytics.activeUsers": "Active Users With Posts",
"admin.system_analytics.title": "the System",
"admin.system_analytics.totalPosts": "Total Posts",
diff --git a/webapp/i18n/es.json b/webapp/i18n/es.json
index 606b4376d..8852dd3c6 100644
--- a/webapp/i18n/es.json
+++ b/webapp/i18n/es.json
@@ -230,15 +230,9 @@
"admin.ldap.usernameAttrTitle": "Atributo Usuario:",
"admin.licence.keyMigration": "Si estás migrando servidores es posible que necesites remover tu licencia de este servidor para poder instalarlo en un servidor nuevo. Para empezar, <a href=\"http://mattermost.com\" target=\"_blank\">deshabilita todas las características de la Edición Enterprise de este servidor</a>. Esta operación habilitará la opción para remover la licencia y degradar este servidor de la Edición Enterprise a la Edición Team.",
"admin.license.chooseFile": "Escoger Archivo",
- "admin.license.edition": "Edición: ",
- "admin.license.enterpriseEdition": "Mattermost Edición Enterprise. Diseñada para comunicación de escala empresarial.",
- "admin.license.enterpriseType": "<div><p>Esta versión compilada de la plataforma de Mattermost es provista bajo una <a href=\"http://mattermost.com\" target=\"_blank\">licencia comercial</a> de Mattermost, Inc. en función en su nivel de subscripción y bajo los <a href=\"{terms}\" target=\"_blank\">Términos del Servicio.</a></p><p>Los detalles de tu subscripción son los siguientes:</p>Nombre: {name}<br />Nombre compañía u organización: {company}<br/>Cantidad de usuarios: {users}<br/>Licencia emitida: {issued}<br/>Fecha de inicio: {start}<br/>Fecha de expiración: {expires}<br/>LDAP: {ldap}<br/></div>",
- "admin.license.key": "Llave de la Licencia: ",
"admin.license.keyRemove": "Remover la Licencia Enterprise y Degradar el Servidor",
"admin.license.noFile": "No se subió ningún archivo",
"admin.license.removing": "Removiendo Licencia...",
- "admin.license.teamEdition": "Mattermost Edición Team. Diseñado para equipos desde 5 hasta 50 usuarios.",
- "admin.license.teamType": "<span><p>Esta versión compilada de la plataforma de Mattermost es proporcionada bajo la licencia MIT.</p><p>Lea MIT-COMPILED-LICENSE.txt en el directorio raíz de la instalación para más detalles. Lea NOTICES.txt para información sobre software libre utilizado en este sistema.</p></span>",
"admin.license.title": "Edición y Licencia",
"admin.license.type": "Licencia: ",
"admin.license.upload": "Subir",
@@ -416,6 +410,8 @@
"admin.support.emailTitle": "Correo electrónico de Soporte:",
"admin.support.helpDesc": "Enlace con la documentación de ayuda para el equipo desde el menú principal. Normalmente no cambia a menos que tu organización decida crear una documentación personalizada.",
"admin.support.helpTitle": "Enlace de Ayuda:",
+ "admin.support.noteDescription": "Si se enlaza a un sitio externo, las URLs deben comenzar con http:// o https://.",
+ "admin.support.noteTitle": "Nota:",
"admin.support.privacyDesc": "Enlace para las políticas de Privacidad disponible para los usuarios en versión de escritorio y movil. Al dejarlo en blanco esconderá la opción que muestra el aviso.",
"admin.support.privacyTitle": "Enlace de políticas de Privacidad:",
"admin.support.problemDesc": "Enlace con la documentación de ayuda para el equipo desde el menú principal. Como predeterminado esto apunta a un foro de ayuda donde los usuarios pueden buscar, encontrar y solicitar ayuda sobre temas técnicos.",
diff --git a/webapp/i18n/pt.json b/webapp/i18n/pt.json
index 17ffe1b16..41d3bbc1c 100644
--- a/webapp/i18n/pt.json
+++ b/webapp/i18n/pt.json
@@ -1,12 +1,12 @@
{
"about.close": "Fechar",
"about.date": "Data De Criação:",
- "about.enterpriseEditione1": "Enterprise Edition E1",
+ "about.enterpriseEditione1": "Enterprise Edition",
"about.hash": "Hash de Compilação:",
"about.licensed": "Licenciado pela:",
"about.number": "O Número De Compilação:",
- "about.teamEditiont0": "Team Edition T0",
- "about.teamEditiont1": "Team Edition T1",
+ "about.teamEditiont0": "Team Edition",
+ "about.teamEditiont1": "Enterprise Edition",
"about.title": "Sobre o Mattermost",
"about.version": "Versão:",
"access_history.title": "Histórico de Acesso",
@@ -24,6 +24,39 @@
"activity_log_modal.iphoneNativeApp": "App Nativo para iPhone",
"admin.audits.reload": "Recarregar",
"admin.audits.title": "Atividade de Usuário",
+ "admin.compliance.directoryDescription": "Diretório o qual os relatórios compliance são gravados, Se estiver em branco, será usado ./data/.",
+ "admin.compliance.directoryExample": "Ex \"./data/\"",
+ "admin.compliance.directoryTitle": "Localização do Diretório de Compliance:",
+ "admin.compliance.enableDailyTitle": "Ativar Relatório Diário:",
+ "admin.compliance.enableDesc": "Quando verdadeiro, Mattermost irá gerar um relatório diário de compliance.",
+ "admin.compliance.enableTitle": "Ativar Compliance:",
+ "admin.compliance.false": "falso",
+ "admin.compliance.noLicense": "<h4 class=\"banner__heading\">Nota:</h4><p>Compliance é um recurso empresarial. Sua licença atual não suporta Compliance. Clique <a href=\"http://mattermost.com\" target=\"_blank\">aqui</a> para informações e preços da licença empresarial.</p>",
+ "admin.compliance.save": "Salvar",
+ "admin.compliance.saving": "Salvando Config...",
+ "admin.compliance.title": "Configurações Compliance",
+ "admin.compliance.true": "verdadeiro",
+ "admin.compliance_reports.desc": "Nome da Tarefa:",
+ "admin.compliance_reports.desc_placeholder": "Ex \"Audit 445 for HR\"",
+ "admin.compliance_reports.emails": "Emails:",
+ "admin.compliance_reports.emails_placeholder": "Ex \"bill@example.com, bob@example.com\"",
+ "admin.compliance_reports.from": "De:",
+ "admin.compliance_reports.from_placeholder": "Ex \"2016-03-11\"",
+ "admin.compliance_reports.keywords": "Palavras-chave:",
+ "admin.compliance_reports.keywords_placeholder": "Ex \"diminuir estoque\"",
+ "admin.compliance_reports.reload": "Recarregar",
+ "admin.compliance_reports.run": "Executar",
+ "admin.compliance_reports.title": "Relatórios Compliance",
+ "admin.compliance_reports.to": "Para:",
+ "admin.compliance_reports.to_placeholder": "Ex \"2016-03-15\"",
+ "admin.compliance_table.desc": "Descrição",
+ "admin.compliance_table.download": "Download",
+ "admin.compliance_table.params": "Parâmetros",
+ "admin.compliance_table.records": "Registros",
+ "admin.compliance_table.status": "Status",
+ "admin.compliance_table.timestamp": "Timestamp",
+ "admin.compliance_table.type": "Tipo",
+ "admin.compliance_table.userId": "Solicitado Por",
"admin.email.allowEmailSignInDescription": "Quando verdadeiro, Mattermost permite aos usuários fazer login usando o e-mail e senha.",
"admin.email.allowEmailSignInTitle": "Permitir Login Com E-mail: ",
"admin.email.allowSignupDescription": "Quando verdadeiro, Mattermost permite a criação de equipe e conta de inscrição através de e-mail e senha. Este valor deve ser falso somente quando você deseja limitar a entrada para o single-sign-on service como OAuth ou LDAP.",
@@ -42,6 +75,8 @@
"admin.email.emailSettings": "Configuração do e-mail",
"admin.email.emailSuccess": "Nenhum erro foram relatados durante o envio de um e-mail. Por favor verifique a sua caixa de entrada para se certificar.",
"admin.email.false": "falso",
+ "admin.email.fullPushNotification": "Enviar trecho de mensagem",
+ "admin.email.genericPushNotification": "Enviar descrição genérica com nomes do usuário e canal",
"admin.email.inviteSaltDescription": "32-caracteres salt adicionados a assinatura de convites por e-mail. Aleatoriamente gerados na instalação. Click \"Re-Gerar\" para criar um novo salt.",
"admin.email.inviteSaltExample": "Ex \"bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo\"",
"admin.email.inviteSaltTitle": "Salt Convite:",
@@ -56,6 +91,8 @@
"admin.email.passwordSaltDescription": "32-caracteres de salt adicionado para assinar o redefinição de senha de e-mails. Gerada aleatoriamente na instalação. Clique em \"Re-Gerar\" para criar novos salt.",
"admin.email.passwordSaltExample": "Ex \"bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo\"",
"admin.email.passwordSaltTitle": "Salt Reset Senha:",
+ "admin.email.pushContentDesc": "Selecionar \"Enviar descrição genérica com nomes de usuário e canal\" fornece envio de notificações com mensagens genéricas, inclui nomes de usuários e canais mas não específica detalhes do texto da mensagem.<br /><br />Selecionar \"Enviar trecho da mensagem\" envia trechos da mensagem que desencadearam as notificações e pode incluir informações confidenciais enviadas na mensagem. Se o seu serviço de Envio de Notificação está fora de um firewall, é ALTAMENTE RECOMENDADO que está opção somente seja usada com o protocolo \"https\" para encriptar a conexão.",
+ "admin.email.pushContentTitle": "Enviar Notificação Contendo:",
"admin.email.pushDesc": "Normalmente definida como verdadeiro na produção. Quando verdadeiro, Mattermost tenta enviar notificações no iOS e Android, através do servidor de notificação.",
"admin.email.pushServerDesc": "Localização do serviço de notificação push Mattermost você pode configurar por trás do firewall usando https://github.com/mattermost/push-proxy. Para testar, você pode usar http://push-test.mattermost.com, que liga à amostra do app Mattermost iOS na Apple AppStore pública. Por favor, não use o serviço de teste para implantações de produção.",
"admin.email.pushServerEx": "Ex: \"http://push-test.mattermost.com\"",
@@ -326,6 +363,7 @@
"admin.service.webhooksTitle": "Ativar Webhooks Entrada: ",
"admin.sidebar.addTeamSidebar": "Adicionar equipe do menu lateral",
"admin.sidebar.audits": "Conformidade e Auditoria",
+ "admin.sidebar.compliance": "Configurações Compliance",
"admin.sidebar.email": "Configuração do e-mail",
"admin.sidebar.file": "Configurações do arquivo",
"admin.sidebar.gitlab": "Configurações GitLab",
@@ -387,6 +425,8 @@
"admin.support.termsDesc": "Link para os Termos de Serviço para os usuários no desktop ou móvel. Deixando este espaço em branco irá esconder a opção de exibir um aviso.",
"admin.support.termsTitle": "Link Termos do Serviço:",
"admin.support.title": "Configurações jurídico e apoio",
+ "admin.support.noteTitle": "Note:",
+ "admin.support.noteDescription": "If linking to an external site, URLs should begin with http:// or https://.",
"admin.system_analytics.activeUsers": "Usuários Ativos com Postagens",
"admin.system_analytics.title": "o Sistema",
"admin.system_analytics.totalPosts": "Total Posts",
@@ -660,13 +700,13 @@
"email_signup.emailError": "Por favor introduza um endereço de e-mail válido",
"email_signup.find": "Encontrar minhas equipes",
"email_verify.almost": "{siteName}: Você está quase pronto",
+ "email_verify.failed": " Falha ao enviar verificação por email.",
"email_verify.notVerifiedBody": "Por favor verifique seu endereço de email. Verifique por um email em sua caixa de entrada.",
- "email_verify.verifyFailed": "Falha ao verificar seu email.",
"email_verify.resend": "Re-enviar Email",
"email_verify.sent": " Verificação de email enviado.",
- "email_verify.failed": " Falha ao enviar verificação por email.",
"email_verify.verified": "{siteName} Email Verificado",
"email_verify.verifiedBody": "<p>Seu email foi verificado! Clique <a href={url}>aqui</a> para login.</p>",
+ "email_verify.verifyFailed": "Falha ao verificar seu email.",
"error_bar.preview_mode": "Modo de visualização: Notificações por E-mail não foram configuradas",
"file_attachment.download": "Download",
"file_info_preview.size": "Tamanho ",
@@ -758,9 +798,9 @@
"login.noAccount": "Não tem uma conta? ",
"login.on": "no {siteName}",
"login.or": "ou",
+ "login.session_expired": " Sua sessão expirou. Por favor faça login novamente.",
"login.signTo": "Login em:",
"login.verified": " Email Verificado",
- "login.session_expired": " Sua sessão expirou. Por favor faça login novamente.",
"login_email.badTeam": "Nome ruim de equipe",
"login_email.email": "E-mail",
"login_email.emailReq": "Um email é necessário",
@@ -1102,6 +1142,7 @@
"user.settings.advance.preReleaseTitle": "Visualizar recursos de pré-lançamento",
"user.settings.advance.sendDesc": "Se habilitado 'Enter' insere uma nova linha e 'Ctrl + Enter' envia a mensagem.",
"user.settings.advance.sendTitle": "Enviar mensagens Ctrl + Enter",
+ "user.settings.advance.slashCmd_autocmp": "Ativar aplicação externa para autocompletar comandos slash",
"user.settings.advance.title": "Configurações Avançadas",
"user.settings.cmds.add": "Adicionar",
"user.settings.cmds.add_desc": "Criar comandos slash para enviar eventos para integrações externas e receber uma resposta. Por exemplo digitando `/patient Joe Smith` poderia trazer de volta os resultados de pesquisa a partir do seu sistema de gestão de registos internos de saúde para o nome “Joe Smith”. Por favor veja <a href=\"http://docs.mattermost.com/developer/slash-commands.html\">Documentação comandos Slash</a> para detalhes e instruções. Ver todos os comandos slash configurados nesta equipe abaixo.",
@@ -1130,6 +1171,7 @@
"user.settings.cmds.request_type_desc": "O tipo de solicitação do comando emitido para a URL requisitada.",
"user.settings.cmds.request_type_get": "GET",
"user.settings.cmds.request_type_post": "POST",
+ "user.settings.cmds.slashCmd_autocmp": "Ativar aplicação externa para autocompletar",
"user.settings.cmds.token": "Token: ",
"user.settings.cmds.trigger": "Comando Palavra Gatilho: ",
"user.settings.cmds.trigger_desc": "Exemplos: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug",
@@ -1313,4 +1355,4 @@
"web.footer.terms": "Termos",
"web.header.back": "Voltar",
"web.root.singup_info": "Toda comunicação em um só lugar, pesquisável e acessível em qualquer lugar"
-}
+} \ No newline at end of file
diff --git a/webapp/package.json b/webapp/package.json
index 0c3e9313e..cdfba8ef0 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -11,6 +11,7 @@
"fastclick": "1.0.6",
"flux": "2.1.1",
"highlight.js": "9.2.0",
+ "intl": "1.1.0",
"jasny-bootstrap": "3.1.3",
"jquery": "2.2.1",
"keymirror": "0.1.1",
diff --git a/webapp/root.jsx b/webapp/root.jsx
index 2ce220f1d..b0a6ae1ac 100644
--- a/webapp/root.jsx
+++ b/webapp/root.jsx
@@ -109,11 +109,30 @@ function preRenderSetup(callwhendone) {
}
);
- addLocaleData(enLocaleData);
- addLocaleData(esLocaleData);
- addLocaleData(ptLocaleData);
+ function afterIntl() {
+ addLocaleData(enLocaleData);
+ addLocaleData(esLocaleData);
+ addLocaleData(ptLocaleData);
- $.when(d1, d2).done(callwhendone);
+ $.when(d1, d2).done(callwhendone);
+ }
+
+ if (global.Intl) {
+ afterIntl();
+ } else {
+ require.ensure([
+ 'intl',
+ 'intl/locale-data/jsonp/en.js',
+ 'intl/locale-data/jsonp/es.js',
+ 'intl/locale-data/jsonp/pt.js'
+ ], (require) => {
+ require('intl');
+ require('intl/locale-data/jsonp/en.js');
+ require('intl/locale-data/jsonp/es.js');
+ require('intl/locale-data/jsonp/pt.js');
+ afterIntl();
+ });
+ }
}
function preLoggedIn(nextState, replace, callback) {
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index a4aa7604c..872bdb8ab 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -429,6 +429,21 @@ export default {
uiName: 'Mention Highlight Link'
},
{
+ group: 'linkAndButtonElements',
+ id: 'linkColor',
+ uiName: 'Link Color'
+ },
+ {
+ group: 'linkAndButtonElements',
+ id: 'buttonBg',
+ uiName: 'Button BG'
+ },
+ {
+ group: 'linkAndButtonElements',
+ id: 'buttonColor',
+ uiName: 'Button Text'
+ },
+ {
group: 'centerChannelElements',
id: 'codeTheme',
uiName: 'Code Theme',
@@ -458,21 +473,6 @@ export default {
iconURL: monokaiIcon
}
]
- },
- {
- group: 'linkAndButtonElements',
- id: 'linkColor',
- uiName: 'Link Color'
- },
- {
- group: 'linkAndButtonElements',
- id: 'buttonBg',
- uiName: 'Button BG'
- },
- {
- group: 'linkAndButtonElements',
- id: 'buttonColor',
- uiName: 'Button Text'
}
],
DEFAULT_CODE_THEME: 'github',