mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-26 21:27:40 -05:00
Merge branch 'master' into mm-1355
This commit is contained in:
+31
-30
@@ -1,38 +1,39 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.2
|
||||
|
||||
- 1.4.2
|
||||
before_install:
|
||||
- gem install compass
|
||||
- "sudo apt-get update -qq"
|
||||
|
||||
- "sudo apt-get remove mysql-common mysql-server-5.5 mysql-server-core-5.5 mysql-client-5.5 mysql-client-core-5.5"
|
||||
- "sudo apt-get autoremove"
|
||||
- "sudo apt-get install libaio1"
|
||||
- "wget -O mysql-5.6.17.deb http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.17-debian6.0-x86_64.deb"
|
||||
- "sudo dpkg -i mysql-5.6.17.deb"
|
||||
- "sudo cp /opt/mysql/server-5.6/support-files/mysql.server /etc/init.d/mysql.server"
|
||||
- "sudo ln -s /opt/mysql/server-5.6/bin/* /usr/bin/"
|
||||
# some config values were changed since 5.5
|
||||
- "sudo sed -i'' 's/table_cache/table_open_cache/' /etc/mysql/my.cnf"
|
||||
- "sudo sed -i'' 's/log_slow_queries/slow_query_log/' /etc/mysql/my.cnf"
|
||||
- "sudo sed -i'' 's/basedir[^=]\\+=.*$/basedir = \\/opt\\/mysql\\/server-5.6/' /etc/mysql/my.cnf"
|
||||
- "sudo /etc/init.d/mysql.server start"
|
||||
|
||||
- gem install compass
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get remove mysql-common mysql-server-5.5 mysql-server-core-5.5 mysql-client-5.5
|
||||
mysql-client-core-5.5
|
||||
- sudo apt-get autoremove
|
||||
- sudo apt-get install libaio1
|
||||
- wget -O mysql-5.6.17.deb http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.17-debian6.0-x86_64.deb
|
||||
- sudo dpkg -i mysql-5.6.17.deb
|
||||
- sudo cp /opt/mysql/server-5.6/support-files/mysql.server /etc/init.d/mysql.server
|
||||
- sudo ln -s /opt/mysql/server-5.6/bin/* /usr/bin/
|
||||
- sudo sed -i'' 's/table_cache/table_open_cache/' /etc/mysql/my.cnf
|
||||
- sudo sed -i'' 's/log_slow_queries/slow_query_log/' /etc/mysql/my.cnf
|
||||
- sudo sed -i'' 's/basedir[^=]\+=.*$/basedir = \/opt\/mysql\/server-5.6/' /etc/mysql/my.cnf
|
||||
- sudo /etc/init.d/mysql.server start
|
||||
install:
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- go get github.com/tools/godep
|
||||
- godep restore
|
||||
|
||||
- export PATH=$PATH:$HOME/gopath/bin
|
||||
- go get github.com/tools/godep
|
||||
- godep restore
|
||||
before_script:
|
||||
- mysql -e "CREATE DATABASE IF NOT EXISTS mattermost_test ;" -uroot
|
||||
- mysql -e "CREATE USER 'mmuser'@'%' IDENTIFIED BY 'mostest' ;" -uroot
|
||||
- mysql -e "GRANT ALL ON mattermost_test.* TO 'mmuser'@'%' ;" -uroot
|
||||
|
||||
- mysql -e "CREATE DATABASE IF NOT EXISTS mattermost_test ;" -uroot
|
||||
- mysql -e "CREATE USER 'mmuser'@'%' IDENTIFIED BY 'mostest' ;" -uroot
|
||||
- mysql -e "GRANT ALL ON mattermost_test.* TO 'mmuser'@'%' ;" -uroot
|
||||
services:
|
||||
- redis-server
|
||||
|
||||
- redis-server
|
||||
addons:
|
||||
hosts:
|
||||
- 127.0.0.1 dockerhost
|
||||
- 127.0.0.1 dockerhost
|
||||
deploy:
|
||||
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:
|
||||
tags: true
|
||||
|
||||
@@ -5,11 +5,18 @@ GOFLAGS ?= $(GOFLAGS:)
|
||||
BUILD_NUMBER ?= $(BUILD_NUMBER:)
|
||||
|
||||
GO=$(GOPATH)/bin/godep go
|
||||
ESLINT=web/react/node_modules/eslint/bin/eslint.js
|
||||
|
||||
ifeq ($(BUILD_NUMBER),)
|
||||
BUILD_NUMBER := dev
|
||||
endif
|
||||
|
||||
ifeq ($(TRAVIS_BUILD_NUMBER),)
|
||||
BUILD_NUMBER := dev
|
||||
else
|
||||
BUILD_NUMBER := $(TRAVIS_BUILD_NUMBER)
|
||||
endif
|
||||
|
||||
DIST_ROOT=dist
|
||||
DIST_PATH=$(DIST_ROOT)/mattermost
|
||||
DIST_RESULTS=$(DIST_ROOT)/results
|
||||
@@ -28,6 +35,7 @@ travis:
|
||||
@cd web/react/ && npm install
|
||||
|
||||
@$(GO) build $(GOFLAGS) ./...
|
||||
@$(GO) install $(GOFLAGS) -a ./...
|
||||
|
||||
@mkdir -p logs
|
||||
|
||||
@@ -37,6 +45,38 @@ travis:
|
||||
@$(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
|
||||
|
||||
mkdir -p $(DIST_PATH)/bin
|
||||
cp $(GOPATH)/bin/platform $(DIST_PATH)/bin
|
||||
|
||||
cp -RL config $(DIST_PATH)/config
|
||||
touch $(DIST_PATH)/config/build.txt
|
||||
echo $(BUILD_NUMBER) | tee -a $(DIST_PATH)/config/build.txt
|
||||
|
||||
mkdir -p $(DIST_PATH)/logs
|
||||
|
||||
mkdir -p web/static/js
|
||||
cd web/react && npm run build
|
||||
|
||||
cd web/sass-files && compass compile
|
||||
|
||||
mkdir -p $(DIST_PATH)/web
|
||||
cp -RL web/static $(DIST_PATH)/web
|
||||
cp -RL web/templates $(DIST_PATH)/web
|
||||
|
||||
mkdir -p $(DIST_PATH)/api
|
||||
cp -RL api/templates $(DIST_PATH)/api
|
||||
|
||||
mv $(DIST_PATH)/web/static/js/bundle.min.js $(DIST_PATH)/web/static/js/bundle-$(BUILD_NUMBER).min.js
|
||||
|
||||
@sed -i'.bak' 's|react-with-addons-0.13.1.js|react-with-addons-0.13.1.min.js|g' $(DIST_PATH)/web/templates/head.html
|
||||
@sed -i'.bak' 's|jquery-1.11.1.js|jquery-1.11.1.min.js|g' $(DIST_PATH)/web/templates/head.html
|
||||
@sed -i'.bak' 's|bootstrap-3.3.1.js|bootstrap-3.3.1.min.js|g' $(DIST_PATH)/web/templates/head.html
|
||||
@sed -i'.bak' 's|perfect-scrollbar.js|perfect-scrollbar.min.js|g' $(DIST_PATH)/web/templates/head.html
|
||||
@sed -i'.bak' 's|bundle.js|bundle-$(BUILD_NUMBER).min.js|g' $(DIST_PATH)/web/templates/head.html
|
||||
rm $(DIST_PATH)/web/templates/*.bak
|
||||
|
||||
tar -C dist -czf $(DIST_PATH).tar.gz mattermost
|
||||
|
||||
build:
|
||||
@$(GO) build $(GOFLAGS) ./...
|
||||
|
||||
@@ -62,6 +102,14 @@ install:
|
||||
|
||||
@cd web/react/ && npm install
|
||||
|
||||
check: install
|
||||
@echo Running ESLint...
|
||||
@$(ESLINT) web/react/components/*
|
||||
@$(ESLINT) web/react/dispatcher/*
|
||||
@$(ESLINT) web/react/pages/*
|
||||
@$(ESLINT) web/react/stores/*
|
||||
@$(ESLINT) web/react/utils/*
|
||||
|
||||
test: install
|
||||
@mkdir -p logs
|
||||
@$(GO) test $(GOFLAGS) -run=$(TESTS) -test.v -test.timeout=180s ./api || exit 1
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
Mattermost Platform Preview<br>
|
||||
© 2015 Spinpunch, Inc. All Rights Reserved. See LICENSE.txt for license information.
|
||||
|
||||
NOTICES:
|
||||
--------
|
||||
|
||||
This product contains a modified portion of 'react', a declarative, efficient, and flexible JavaScript library for building user interfaces by Facebook, Inc.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/facebook/react
|
||||
|
||||
* LICENSE:
|
||||
|
||||
BSD License
|
||||
|
||||
For React software
|
||||
|
||||
Copyright (c) 2013-2015, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name Facebook nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This product contains a modified portion of 'perfect-scrollbar', a scrollbar plugin by Hyunje Alex Jun and other contributors.
|
||||
* HOMEPAGE:
|
||||
* https://github.com/noraesae/perfect-scrollbar
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The MIT License (MIT) Copyright (c) 2015 Hyunje Alex Jun and other contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This product contains a modified portion of 'golang-lru', a golang LRU cache by hashicorp, based on Groupcache by Google Inc.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/hashicorp/golang-lru
|
||||
|
||||
* LICENSE:
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
Mattermost Platform
|
||||
© 2015 Spinpunch, Inc. All Rights Reserved. See LICENSE.txt for license information.
|
||||
|
||||
NOTICES:
|
||||
--------
|
||||
|
||||
This product contains a modified portion of 'react', a declarative, efficient, and
|
||||
flexible JavaScript library for building user interfaces by Facebook, Inc.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/facebook/react
|
||||
|
||||
* LICENSE:
|
||||
|
||||
BSD License
|
||||
|
||||
For React software
|
||||
|
||||
Copyright (c) 2013-2015, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name Facebook nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---
|
||||
|
||||
This product contains a modified portion of 'perfect-scrollbar', a scrollbar plugin
|
||||
by Hyunje Alex Jun and other contributors.
|
||||
* HOMEPAGE:
|
||||
* https://github.com/noraesae/perfect-scrollbar
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The MIT License (MIT) Copyright (c) 2015 Hyunje Alex Jun and other contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
This product contains a modified portion of 'golang-lru', a golang LRU cache by hashicorp,
|
||||
based on Groupcache by Google Inc.
|
||||
|
||||
* HOMEPAGE:
|
||||
* https://github.com/hashicorp/golang-lru
|
||||
|
||||
* LICENSE:
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a
|
||||
copy of the MPL was not distributed with this file, You can obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
---
|
||||
|
||||
This product contains a modified portion of 'golang-freetype', a port of the Freetype
|
||||
font rasterizer (www.freetype.org) to the Go programming.
|
||||
|
||||
Portions of this software are copyright © 2010 The FreeType Project (www.freetype.org).
|
||||
All rights reserved.
|
||||
|
||||
* HOMEPAGE:
|
||||
* http://www.freetype.org
|
||||
|
||||
* LICENSE:
|
||||
|
||||
The FreeType Project LICENSE
|
||||
----------------------------
|
||||
|
||||
2006-Jan-27
|
||||
|
||||
Copyright 1996-2002, 2006 by
|
||||
David Turner, Robert Wilhelm, and Werner Lemberg
|
||||
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The FreeType Project is distributed in several archive packages;
|
||||
some of them may contain, in addition to the FreeType font engine,
|
||||
various tools and contributions which rely on, or relate to, the
|
||||
FreeType Project.
|
||||
|
||||
This license applies to all files found in such packages, and
|
||||
which do not fall under their own explicit license. The license
|
||||
affects thus the FreeType font engine, the test programs,
|
||||
documentation and makefiles, at the very least.
|
||||
|
||||
This license was inspired by the BSD, Artistic, and IJG
|
||||
(Independent JPEG Group) licenses, which all encourage inclusion
|
||||
and use of free software in commercial and freeware products
|
||||
alike. As a consequence, its main points are that:
|
||||
|
||||
o We don't promise that this software works. However, we will be
|
||||
interested in any kind of bug reports. (`as is' distribution)
|
||||
|
||||
o You can use this software for whatever you want, in parts or
|
||||
full form, without having to pay us. (`royalty-free' usage)
|
||||
|
||||
o You may not pretend that you wrote this software. If you use
|
||||
it, or only parts of it, in a program, you must acknowledge
|
||||
somewhere in your documentation that you have used the
|
||||
FreeType code. (`credits')
|
||||
|
||||
We specifically permit and encourage the inclusion of this
|
||||
software, with or without modifications, in commercial products.
|
||||
We disclaim all warranties covering The FreeType Project and
|
||||
assume no liability related to The FreeType Project.
|
||||
|
||||
|
||||
Finally, many people asked us for a preferred form for a
|
||||
credit/disclaimer to use in compliance with this license. We thus
|
||||
encourage you to use the following text:
|
||||
|
||||
"""
|
||||
Portions of this software are copyright � <year> The FreeType
|
||||
Project (www.freetype.org). All rights reserved.
|
||||
"""
|
||||
|
||||
Please replace <year> with the value from the FreeType version you
|
||||
actually use.
|
||||
|
||||
|
||||
Legal Terms
|
||||
===========
|
||||
|
||||
0. Definitions
|
||||
--------------
|
||||
|
||||
Throughout this license, the terms `package', `FreeType Project',
|
||||
and `FreeType archive' refer to the set of files originally
|
||||
distributed by the authors (David Turner, Robert Wilhelm, and
|
||||
Werner Lemberg) as the `FreeType Project', be they named as alpha,
|
||||
beta or final release.
|
||||
|
||||
`You' refers to the licensee, or person using the project, where
|
||||
`using' is a generic term including compiling the project's source
|
||||
code as well as linking it to form a `program' or `executable'.
|
||||
This program is referred to as `a program using the FreeType
|
||||
engine'.
|
||||
|
||||
This license applies to all files distributed in the original
|
||||
FreeType Project, including all source code, binaries and
|
||||
documentation, unless otherwise stated in the file in its
|
||||
original, unmodified form as distributed in the original archive.
|
||||
If you are unsure whether or not a particular file is covered by
|
||||
this license, you must contact us to verify this.
|
||||
|
||||
The FreeType Project is copyright (C) 1996-2000 by David Turner,
|
||||
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
|
||||
specified below.
|
||||
|
||||
1. No Warranty
|
||||
--------------
|
||||
|
||||
THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
|
||||
USE, OF THE FREETYPE PROJECT.
|
||||
|
||||
2. Redistribution
|
||||
-----------------
|
||||
|
||||
This license grants a worldwide, royalty-free, perpetual and
|
||||
irrevocable right and license to use, execute, perform, compile,
|
||||
display, copy, create derivative works of, distribute and
|
||||
sublicense the FreeType Project (in both source and object code
|
||||
forms) and derivative works thereof for any purpose; and to
|
||||
authorize others to exercise some or all of the rights granted
|
||||
herein, subject to the following conditions:
|
||||
|
||||
o Redistribution of source code must retain this license file
|
||||
(`FTL.TXT') unaltered; any additions, deletions or changes to
|
||||
the original files must be clearly indicated in accompanying
|
||||
documentation. The copyright notices of the unaltered,
|
||||
original files must be preserved in all copies of source
|
||||
files.
|
||||
|
||||
o Redistribution in binary form must provide a disclaimer that
|
||||
states that the software is based in part of the work of the
|
||||
FreeType Team, in the distribution documentation. We also
|
||||
encourage you to put an URL to the FreeType web page in your
|
||||
documentation, though this isn't mandatory.
|
||||
|
||||
These conditions apply to any software derived from or based on
|
||||
the FreeType Project, not just the unmodified files. If you use
|
||||
our work, you must acknowledge us. However, no fee need be paid
|
||||
to us.
|
||||
|
||||
3. Advertising
|
||||
--------------
|
||||
|
||||
Neither the FreeType authors and contributors nor you shall use
|
||||
the name of the other for commercial, advertising, or promotional
|
||||
purposes without specific prior written permission.
|
||||
|
||||
We suggest, but do not require, that you use one or more of the
|
||||
following phrases to refer to this software in your documentation
|
||||
or advertising materials: `FreeType Project', `FreeType Engine',
|
||||
`FreeType library', or `FreeType Distribution'.
|
||||
|
||||
As you have not signed this license, you are not required to
|
||||
accept it. However, as the FreeType Project is copyrighted
|
||||
material, only this license, or another one contracted with the
|
||||
authors, grants you the right to use, distribute, and modify it.
|
||||
Therefore, by using, distributing, or modifying the FreeType
|
||||
Project, you indicate that you understand and accept all the terms
|
||||
of this license.
|
||||
|
||||
4. Contacts
|
||||
-----------
|
||||
|
||||
There are two mailing lists related to FreeType:
|
||||
|
||||
o freetype@nongnu.org
|
||||
|
||||
Discusses general use and applications of FreeType, as well as
|
||||
future and wanted additions to the library and distribution.
|
||||
If you are looking for support, start in this list if you
|
||||
haven't found anything to help you in the documentation.
|
||||
|
||||
o freetype-devel@nongnu.org
|
||||
|
||||
Discusses bugs, as well as engine internals, design issues,
|
||||
specific licenses, porting, etc.
|
||||
|
||||
Our home page can be found at
|
||||
|
||||
http://www.freetype.org
|
||||
|
||||
|
||||
--- end of FTL.TXT ---
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
# Mattermost Style Guide
|
||||
|
||||
1. [GO](#go)
|
||||
2. [Javascript](#javascript)
|
||||
3. [React-JSX](#react-jsx)
|
||||
|
||||
|
||||
## Go
|
||||
|
||||
All go code must follow the golang official [Style Guide](https://golang.org/doc/effective_go.html)
|
||||
|
||||
In addition all code must be run though the official go formatter tool [gofmt](https://golang.org/cmd/gofmt/)
|
||||
|
||||
|
||||
## Javascript
|
||||
|
||||
Part of the build process is running ESLint. ESLint is the final authority on all style issues. PRs will not be accepted unless there are no errors or warnings running ESLint. The ESLint configuration file can be found in: [web/react/.eslintrc](https://github.com/mattermost/platform/blob/master/web/react/.eslintrc.json)
|
||||
|
||||
Instructions on how to use ESLint with your favourite editor can be found here: [http://eslint.org/docs/user-guide/integrations](http://eslint.org/docs/user-guide/integrations)
|
||||
|
||||
The following is an abridged version of the [Airbnb Javascript Style Guide](https://github.com/airbnb/javascript/blob/master/README.md#airbnb-javascript-style-guide-), with modifications. Anything that is unclear here follow that guide. If there is a conflict, follow what is said below.
|
||||
|
||||
### Whitespace
|
||||
|
||||
- Indentation is four spaces
|
||||
- Use a space before the leading brace
|
||||
- Use one space between the comma and the next argument in a bracketed list. No other space.
|
||||
- Use whitespace to make code more readable.
|
||||
- Do not use more than one newline to separate code blocks.
|
||||
- Do not use a newline as the first line of a function
|
||||
|
||||
```javascript
|
||||
// Correct
|
||||
function myFunction(parm1, parm2) {
|
||||
stuff...;
|
||||
|
||||
morestuff;
|
||||
}
|
||||
|
||||
// Incorrect
|
||||
function myFunction ( parm1, parm2 ){
|
||||
stuff...;
|
||||
|
||||
|
||||
morestuff;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Semicolons
|
||||
|
||||
- You must use them always
|
||||
|
||||
```javascript
|
||||
// Correct
|
||||
var x = 1;
|
||||
|
||||
// Incorrect
|
||||
var x = 1
|
||||
```
|
||||
|
||||
### Variables
|
||||
|
||||
- Declarations must always use var, let or const.
|
||||
- Prefer let or const over var.
|
||||
- camelCase for all variable names.
|
||||
|
||||
```javascript
|
||||
// Correct
|
||||
let myVariable = 4;
|
||||
|
||||
// OK
|
||||
var myVariable = 4;
|
||||
|
||||
// Incorrect
|
||||
myVariable = 4;
|
||||
var my_variable = 4;
|
||||
```
|
||||
|
||||
### Blocks
|
||||
|
||||
- Braces must be used on all blocks.
|
||||
- Braces must start on the same line as the statement starting the block.
|
||||
- Else and else if must be on the same line as the if block closing brace.
|
||||
|
||||
```javascript
|
||||
// Correct
|
||||
if (somthing) {
|
||||
stuff...;
|
||||
} else if (otherthing) {
|
||||
stuff...;
|
||||
}
|
||||
|
||||
// Incorrect
|
||||
if (somthing)
|
||||
{
|
||||
stuff...;
|
||||
}
|
||||
else
|
||||
{
|
||||
stuff...;
|
||||
}
|
||||
|
||||
// Incorrect
|
||||
if (somthing) stuff...;
|
||||
if (somthing)
|
||||
stuff...;
|
||||
|
||||
```
|
||||
|
||||
### Strings
|
||||
|
||||
- Use template strings instead of concatenation.
|
||||
|
||||
```javascript
|
||||
// Correct
|
||||
function getStr(stuff) {
|
||||
return "This is the ${stuff} string";
|
||||
}
|
||||
|
||||
// Incorrect
|
||||
function wrongGetStr(stuff) {
|
||||
return "This is the " + stuff + " string";
|
||||
}
|
||||
```
|
||||
|
||||
## React-JSX
|
||||
|
||||
Part of the build process is running ESLint. ESLint is the final authority on all style issues. PRs will not be accepted unless there are no errors or warnings running ESLint. The ESLint configuration file can be found in: [web/react/.eslintrc](https://github.com/mattermost/platform/blob/master/web/react/.eslintrc.json)
|
||||
|
||||
Instructions on how to use ESLint with your favourite editor can be found here: [http://eslint.org/docs/user-guide/integrations](http://eslint.org/docs/user-guide/integrations)
|
||||
|
||||
This is an abridged version of the [Airbnb React/JSX Style Guide](https://github.com/airbnb/javascript/tree/master/react#airbnb-reactjsx-style-guide). Anything that is unclear here follow that guide. If there is a conflict, follow what is said below.
|
||||
|
||||
### General
|
||||
|
||||
- Include only one React component per file.
|
||||
- Use class \<name\> extends React.Component over React.createClass unless you need mixins
|
||||
- CapitalCamelCase with .jsx extension for component filenames.
|
||||
- Filenames should be the component name.
|
||||
|
||||
### Alignment
|
||||
|
||||
- Follow alignment styles shown below:
|
||||
```xml
|
||||
// Correct
|
||||
<Tag
|
||||
propertyOne="1"
|
||||
propertyTwo="2"
|
||||
>
|
||||
<Child />
|
||||
</Tag>
|
||||
|
||||
// Correct
|
||||
<Tag propertyOne="1" />
|
||||
```
|
||||
|
||||
### Naming
|
||||
|
||||
- Property names use camelCase.
|
||||
- React component names use CapitalCamelCase.
|
||||
- Do not use an understore for internal methods in a react component.
|
||||
|
||||
```xml
|
||||
// Correct
|
||||
<ReactComponent propertyOne="value" />
|
||||
```
|
||||
+2
-2
@@ -56,7 +56,7 @@ func TestCreateChannel(t *testing.T) {
|
||||
|
||||
rchannel.Data.(*model.Channel).Id = ""
|
||||
if _, err := Client.CreateChannel(rchannel.Data.(*model.Channel)); err != nil {
|
||||
if err.Message != "A channel with that name already exists" {
|
||||
if err.Message != "A channel with that handle already exists" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func TestCreateChannel(t *testing.T) {
|
||||
|
||||
Client.DeleteChannel(savedId)
|
||||
if _, err := Client.CreateChannel(rchannel.Data.(*model.Channel)); err != nil {
|
||||
if err.Message != "A channel with that name was previously created" {
|
||||
if err.Message != "A channel with that handle was previously created" {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,25 +35,18 @@ func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
m := model.MapFromJson(r.Body)
|
||||
email := strings.ToLower(strings.TrimSpace(m["email"]))
|
||||
displayName := strings.TrimSpace(m["display_name"])
|
||||
|
||||
if len(email) == 0 {
|
||||
c.SetInvalidParam("signupTeam", "email")
|
||||
return
|
||||
}
|
||||
|
||||
if len(displayName) == 0 {
|
||||
c.SetInvalidParam("signupTeam", "display_name")
|
||||
return
|
||||
}
|
||||
|
||||
subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL())
|
||||
bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL())
|
||||
bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink
|
||||
|
||||
props := make(map[string]string)
|
||||
props["email"] = email
|
||||
props["display_name"] = displayName
|
||||
props["time"] = fmt.Sprintf("%v", model.GetMillis())
|
||||
|
||||
data := model.MapToJson(props)
|
||||
|
||||
@@ -84,9 +84,9 @@ func (s SqlChannelStore) Save(channel *model.Channel) StoreChannel {
|
||||
dupChannel := model.Channel{}
|
||||
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId = :TeamId AND Name = :Name AND DeleteAt > 0", map[string]interface{}{"TeamId": channel.TeamId, "Name": channel.Name})
|
||||
if dupChannel.DeleteAt > 0 {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that handle was previously created", "id="+channel.Id+", "+err.Error())
|
||||
} else {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that handle already exists", "id="+channel.Id+", "+err.Error())
|
||||
}
|
||||
} else {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Save", "We couldn't save the channel", "id="+channel.Id+", "+err.Error())
|
||||
@@ -122,9 +122,9 @@ func (s SqlChannelStore) Update(channel *model.Channel) StoreChannel {
|
||||
dupChannel := model.Channel{}
|
||||
s.GetReplica().SelectOne(&dupChannel, "SELECT * FROM Channels WHERE TeamId = :TeamId AND Name= :Name AND DeleteAt > 0", map[string]interface{}{"TeamId": channel.TeamId, "Name": channel.Name})
|
||||
if dupChannel.DeleteAt > 0 {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name was previously created", "id="+channel.Id+", "+err.Error())
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that handle was previously created", "id="+channel.Id+", "+err.Error())
|
||||
} else {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that name already exists", "id="+channel.Id+", "+err.Error())
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "A channel with that handle already exists", "id="+channel.Id+", "+err.Error())
|
||||
}
|
||||
} else {
|
||||
result.Err = model.NewAppError("SqlChannelStore.Update", "We encounted an error updating the channel", "id="+channel.Id+", "+err.Error())
|
||||
|
||||
@@ -445,12 +445,12 @@ func TestPostStoreSearch(t *testing.T) {
|
||||
t.Fatal("returned wrong serach result")
|
||||
}
|
||||
|
||||
if utils.Cfg.SqlSettings.DriverName == "mysql" {
|
||||
r2 := (<-store.Post().Search(teamId, userId, "new york", false)).Data.(*model.PostList)
|
||||
if len(r2.Order) >= 1 && r2.Order[0] != o2.Id {
|
||||
t.Fatal("returned wrong serach result")
|
||||
}
|
||||
}
|
||||
// if utils.Cfg.SqlSettings.DriverName == "mysql" {
|
||||
// r2 := (<-store.Post().Search(teamId, userId, "new york", false)).Data.(*model.PostList)
|
||||
// if len(r2.Order) >= 1 && r2.Order[0] != o2.Id {
|
||||
// t.Fatal("returned wrong serach result")
|
||||
// }
|
||||
// }
|
||||
|
||||
r3 := (<-store.Post().Search(teamId, userId, "new", false)).Data.(*model.PostList)
|
||||
if len(r3.Order) != 2 && r3.Order[0] != o1.Id {
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"blockBindings": true,
|
||||
"modules": true
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jquery": true,
|
||||
"es6": true
|
||||
},
|
||||
"globals": {
|
||||
"React": false
|
||||
},
|
||||
"rules": {
|
||||
"comma-dangle": [2, "never"],
|
||||
"no-cond-assign": [2, "except-parens"],
|
||||
"no-console": 1,
|
||||
"no-constant-condition": 1,
|
||||
"no-debugger": 1,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-empty": 1,
|
||||
"no-ex-assign": 1,
|
||||
"no-extra-semi": 2,
|
||||
"no-func-assign": 1,
|
||||
"no-inner-declarations": 0,
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-unreachable": 2,
|
||||
"valid-typeof": 2,
|
||||
"no-unexpected-multiline": 2,
|
||||
|
||||
"block-scoped-var": 1,
|
||||
"complexity": [1, 8],
|
||||
"consistent-return": 2,
|
||||
"curly": [2, "all"],
|
||||
"dot-notation": 2,
|
||||
"dot-location": [2, "object"],
|
||||
"eqeqeq": [2, "smart"],
|
||||
"guard-for-in": 1,
|
||||
"no-alert": 1,
|
||||
"no-caller": 2,
|
||||
"no-div-regex": 1,
|
||||
"no-else-return": 1,
|
||||
"no-eval": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 1,
|
||||
"no-multi-spaces": [2, { "exceptions": { "Property": false } }],
|
||||
"no-multi-str": 0,
|
||||
"no-param-reassign": 2,
|
||||
"no-process-env": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-return-assign": [2, "always"],
|
||||
"no-script-url": 2,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-throw-literal": 2,
|
||||
"no-unused-expressions": 2,
|
||||
"no-void": 2,
|
||||
"no-warning-comments": 0,
|
||||
"no-with": 2,
|
||||
"radix": 2,
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": [2, "outside"],
|
||||
"yoda": [2, "never", {"exceptRange": false, "onlyEquality": false}],
|
||||
|
||||
"no-undefined": 2,
|
||||
"no-shadow": [2, {"hoist": "functions"}],
|
||||
"no-unused-vars": [2, {"vars": "all", "args": "all"}],
|
||||
"no-use-before-define": [2, "nofunc"],
|
||||
|
||||
// Style
|
||||
"array-bracket-spacing": [2, "never"],
|
||||
"brace-style": [2, "1tbs", { "allowSingleLine": false }],
|
||||
"camelcase": [2, {"properties": "always"}],
|
||||
"comma-spacing": [2, {"before": false, "after": true}],
|
||||
"comma-style": [2, "last"],
|
||||
"computed-property-spacing": [2, "never"],
|
||||
"consistent-this": [2, "self"],
|
||||
"func-names": 2,
|
||||
"func-style": [2, "declaration"],
|
||||
"indent": [2, 4, {"indentSwitchCase": false}],
|
||||
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
|
||||
"lines-around-comment": [2, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, "allowBlockEnd": true }],
|
||||
"linebreak-style": 2,
|
||||
"new-cap": 2,
|
||||
"new-parens": 2,
|
||||
"no-lonely-if": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"no-multiple-empty-lines": [2, {"max": 1}],
|
||||
"no-spaced-func": 2,
|
||||
"no-ternary": 2,
|
||||
"no-trailing-spaces": [2, { "skipBlankLines": false }],
|
||||
"no-underscore-dangle": 2,
|
||||
"no-unneeded-ternary": 2,
|
||||
"object-curly-spacing": [2, "never"],
|
||||
"one-var": [2, "never"],
|
||||
"operator-linebreak": [2, "after"],
|
||||
"padded-blocks": [2, "never"],
|
||||
"quote-props": [2, "as-needed"],
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"semi-spacing": [2, {"before": false, "after": true}],
|
||||
"semi": [2, "always"],
|
||||
"space-after-keywords": [2, "always"],
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-return-throw-case": 2,
|
||||
"space-unary-ops": [2, { "words": true, "nonwords": false }],
|
||||
"wrap-regex": 2,
|
||||
|
||||
// React Specific
|
||||
"react/display-name": [2, { "acceptTranspilerName": true }],
|
||||
"react/jsx-boolean-value": [2, "always"],
|
||||
"react/jsx-curly-spacing": [2, "never"],
|
||||
"react/jsx-no-duplicate-props": [2, { "ignoreCase": false }],
|
||||
"react/jsx-no-undef": 2,
|
||||
"react/jsx-quotes": [2, "single", "avoid-escape"],
|
||||
"react/jsx-uses-react": 2,
|
||||
"react/jsx-uses-vars": 2,
|
||||
"react/no-danger": 0,
|
||||
"react/no-did-mount-set-state": 2,
|
||||
"react/no-did-update-set-state": 2,
|
||||
"react/no-multi-comp": 2,
|
||||
"react/no-unknown-property": 2,
|
||||
"react/prop-types": 2,
|
||||
"react/sort-comp": 0,
|
||||
"react/wrap-multilines": 2
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
var UserStore = require('../stores/user_store.jsx');
|
||||
var AsyncClient = require('../utils/async_client.jsx');
|
||||
var Utils = require('../utils/utils.jsx');
|
||||
var LoadingScreen = require('./loading_screen.jsx');
|
||||
var utils = require('../utils/utils.jsx');
|
||||
|
||||
function getStateFromStoresForAudits() {
|
||||
return {
|
||||
@@ -14,7 +15,9 @@ function getStateFromStoresForAudits() {
|
||||
module.exports = React.createClass({
|
||||
componentDidMount: function() {
|
||||
UserStore.addAuditsChangeListener(this._onChange);
|
||||
AsyncClient.getAudits();
|
||||
$(this.refs.modal.getDOMNode()).on('shown.bs.modal', function (e) {
|
||||
AsyncClient.getAudits();
|
||||
});
|
||||
|
||||
var self = this;
|
||||
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
|
||||
@@ -25,7 +28,10 @@ module.exports = React.createClass({
|
||||
UserStore.removeAuditsChangeListener(this._onChange);
|
||||
},
|
||||
_onChange: function() {
|
||||
this.setState(getStateFromStoresForAudits());
|
||||
var newState = getStateFromStoresForAudits();
|
||||
if (!utils.areStatesEqual(newState.audits, this.state.audits)) {
|
||||
this.setState(newState);
|
||||
}
|
||||
},
|
||||
handleMoreInfo: function(index) {
|
||||
var newMoreInfo = this.state.moreInfo;
|
||||
@@ -87,9 +93,13 @@ module.exports = React.createClass({
|
||||
<h4 className="modal-title" id="myModalLabel">Access History</h4>
|
||||
</div>
|
||||
<div ref="modalBody" className="modal-body">
|
||||
{ !this.state.audits.loading ?
|
||||
<form role="form">
|
||||
{ accessList }
|
||||
</form>
|
||||
:
|
||||
<LoadingScreen />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
var UserStore = require('../stores/user_store.jsx');
|
||||
var Client = require('../utils/client.jsx');
|
||||
var AsyncClient = require('../utils/async_client.jsx');
|
||||
var LoadingScreen = require('./loading_screen.jsx');
|
||||
var utils = require('../utils/utils.jsx');
|
||||
|
||||
function getStateFromStoresForSessions() {
|
||||
return {
|
||||
@@ -29,7 +31,9 @@ module.exports = React.createClass({
|
||||
},
|
||||
componentDidMount: function() {
|
||||
UserStore.addSessionsChangeListener(this._onChange);
|
||||
AsyncClient.getSessions();
|
||||
$(this.refs.modal.getDOMNode()).on('shown.bs.modal', function (e) {
|
||||
AsyncClient.getSessions();
|
||||
});
|
||||
|
||||
var self = this;
|
||||
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
|
||||
@@ -40,7 +44,10 @@ module.exports = React.createClass({
|
||||
UserStore.removeSessionsChangeListener(this._onChange);
|
||||
},
|
||||
_onChange: function() {
|
||||
this.setState(getStateFromStoresForSessions());
|
||||
var newState = getStateFromStoresForSessions();
|
||||
if (!utils.areStatesEqual(newState.sessions, this.state.sessions)) {
|
||||
this.setState(newState);
|
||||
}
|
||||
},
|
||||
handleMoreInfo: function(index) {
|
||||
var newMoreInfo = this.state.moreInfo;
|
||||
@@ -106,10 +113,16 @@ module.exports = React.createClass({
|
||||
</div>
|
||||
<p className="session-help-text">Sessions are created when you log in with your email and password to a new browser on a device. Sessions let you use Mattermost for up to 30 days without having to log in again. If you want to log out sooner, use the "Logout" button below to end a session.</p>
|
||||
<div ref="modalBody" className="modal-body">
|
||||
{ !this.state.sessions.loading ?
|
||||
<div>
|
||||
<form role="form">
|
||||
{ activityList }
|
||||
</form>
|
||||
{ server_error }
|
||||
</div>
|
||||
:
|
||||
<LoadingScreen />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -153,7 +153,7 @@ module.exports = React.createClass({
|
||||
if (isDirect) {
|
||||
if (this.state.users.length > 1) {
|
||||
var contact = this.state.users[((this.state.users[0].id === currentId) ? 1 : 0)];
|
||||
channelTitle = <UserProfile userId={contact.id} overwriteName={contact.nickname || contact.username} />;
|
||||
channelTitle = contact.nickname || contact.username;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,13 +161,13 @@ module.exports = React.createClass({
|
||||
<table className="channel-header alt">
|
||||
<tr>
|
||||
<th>
|
||||
{ !isDirect ?
|
||||
<div className="channel-header__info">
|
||||
<div className="dropdown">
|
||||
<a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
|
||||
<strong className="heading">{channelTitle} </strong>
|
||||
<span className="glyphicon glyphicon-chevron-down header-dropdown__icon"></span>
|
||||
</a>
|
||||
{ !isDirect ?
|
||||
<ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
|
||||
<li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_info" data-channelid={channel.id} href="#">View Info</a></li>
|
||||
{ !ChannelStore.isDefault(channel) ?
|
||||
@@ -193,12 +193,14 @@ module.exports = React.createClass({
|
||||
: null
|
||||
}
|
||||
</ul>
|
||||
:
|
||||
<ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
|
||||
<li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set Channel Description...</a></li>
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
<div data-toggle="popover" data-content={popoverContent} className="description">{description}</div>
|
||||
</div>
|
||||
:
|
||||
<a href="#"><strong className="heading">{channelTitle}</strong></a>
|
||||
}
|
||||
</th>
|
||||
<th><PopoverListMembers members={this.state.users} channelId={channel.id} /></th>
|
||||
<th className="search-bar__container"><NavbarSearchBox /></th>
|
||||
|
||||
@@ -98,7 +98,7 @@ module.exports = React.createClass({
|
||||
: "" }
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
|
||||
<button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" className="btn btn-danger" data-dismiss="modal" onClick={this.handleDelete}>Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports = React.createClass({
|
||||
if (filename.indexOf("/api/v1/files/get") != -1) {
|
||||
filename = filename.split("/api/v1/files/get")[1];
|
||||
}
|
||||
filename = window.location.origin + "/api/v1/files/get" + filename;
|
||||
filename = utils.getWindowLocationOrigin() + "/api/v1/files/get" + filename;
|
||||
|
||||
if (type === "image") {
|
||||
previews.push(
|
||||
|
||||
@@ -103,13 +103,9 @@ module.exports = React.createClass({
|
||||
|
||||
return (
|
||||
<div className="signup-team__container">
|
||||
<div>
|
||||
<span className="signup-team__name">{ teamDisplayName }</span>
|
||||
<br/>
|
||||
<span className="signup-team__subdomain">/{ teamName }/</span>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
<h5 className="margin--less">Sign in to:</h5>
|
||||
<h2 className="signup-team__name">{ teamDisplayName }</h2>
|
||||
<h2 className="signup-team__subdomain">on { config.SiteName }</h2>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div className={server_error ? 'form-group has-error' : 'form-group'}>
|
||||
{ server_error }
|
||||
@@ -124,13 +120,13 @@ module.exports = React.createClass({
|
||||
<button type="submit" className="btn btn-primary">Sign in</button>
|
||||
</div>
|
||||
{ login_message }
|
||||
<div className="form-group form-group--small">
|
||||
<div className="form-group margin--extra form-group--small">
|
||||
<span><a href="/find_team">{"Find other " + strings.TeamPlural}</a></span>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<a href={"/" + teamName + "/reset_password"}>I forgot my password</a>
|
||||
</div>
|
||||
<div className="external-link">
|
||||
<div className="margin--extra">
|
||||
<span>{"Want to create your own " + strings.Team + "?"} <a href="/" className="signup-team-login">Sign up now</a></span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -32,7 +32,7 @@ module.exports = React.createClass({
|
||||
if (fileInfo.path.indexOf("/api/v1/files/get") != -1) {
|
||||
fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path;
|
||||
fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path;
|
||||
|
||||
if (type === "image") {
|
||||
$('<img/>').attr('src', fileInfo.path+'_thumb.jpg').load(function(path, name){ return function() {
|
||||
@@ -112,7 +112,7 @@ module.exports = React.createClass({
|
||||
if (fileInfo.path.indexOf("/api/v1/files/get") != -1) {
|
||||
fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path;
|
||||
fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path;
|
||||
|
||||
if (type === "image") {
|
||||
if (i < Constants.MAX_DISPLAY_FILES) {
|
||||
|
||||
@@ -309,12 +309,15 @@ module.exports = React.createClass({
|
||||
|
||||
var more_messages = <p className="beginning-messages-text">Beginning of Channel</p>;
|
||||
|
||||
var userStyle = { color: UserStore.getCurrentUser().props.theme }
|
||||
|
||||
if (channel != null) {
|
||||
if (order.length > 0 && order.length % Constants.POST_CHUNK_SIZE === 0) {
|
||||
more_messages = <a ref="loadmore" className="more-messages-text theme" href="#" onClick={this.getMorePosts}>Load more messages</a>;
|
||||
} else if (channel.type === 'D') {
|
||||
var teammate = utils.getDirectTeammate(channel.id)
|
||||
|
||||
|
||||
if (teammate) {
|
||||
var teammate_name = teammate.nickname.length > 0 ? teammate.nickname : teammate.username;
|
||||
more_messages = (
|
||||
@@ -329,6 +332,7 @@ module.exports = React.createClass({
|
||||
{"This is the start of your private message history with " + teammate_name + "." }<br/>
|
||||
{"Private messages and files shared here are not shown to people outside this area."}
|
||||
</p>
|
||||
<a className="intro-links" href="#" style={userStyle} data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}><i className="fa fa-pencil"></i>Set a description</a>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
@@ -342,7 +346,6 @@ module.exports = React.createClass({
|
||||
var ui_name = channel.display_name
|
||||
var members = ChannelStore.getCurrentExtraInfo().members;
|
||||
var creator_name = "";
|
||||
var userStyle = { color: UserStore.getCurrentUser().props.theme }
|
||||
|
||||
for (var i = 0; i < members.length; i++) {
|
||||
if (members[i].roles.indexOf('admin') > -1) {
|
||||
|
||||
@@ -98,7 +98,7 @@ RootPost = React.createClass({
|
||||
if (fileInfo.path.indexOf("/api/v1/files/get") != -1) {
|
||||
fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path;
|
||||
fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path;
|
||||
|
||||
if (ftype === "image") {
|
||||
var url = fileInfo.path.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29');
|
||||
@@ -208,7 +208,7 @@ CommentPost = React.createClass({
|
||||
if (fileInfo.path.indexOf("/api/v1/files/get") != -1) {
|
||||
fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path;
|
||||
fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path;
|
||||
|
||||
if (type === "image") {
|
||||
var url = fileInfo.path.replace(re1, '%20').replace(re2, '%28').replace(re3, '%29');
|
||||
|
||||
@@ -36,6 +36,9 @@ module.exports = React.createClass({
|
||||
}
|
||||
}
|
||||
},
|
||||
clearFocus: function(e) {
|
||||
$('.search-bar__container').removeClass('focused');
|
||||
},
|
||||
handleClose: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -57,6 +60,7 @@ module.exports = React.createClass({
|
||||
},
|
||||
handleUserFocus: function(e) {
|
||||
e.target.select();
|
||||
$('.search-bar__container').addClass('focused');
|
||||
},
|
||||
performSearch: function(terms, isMentionSearch) {
|
||||
if (terms.length) {
|
||||
@@ -92,13 +96,14 @@ module.exports = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<div className="sidebar__collapse" onClick={this.handleClose}>Cancel</div>
|
||||
<span className="glyphicon glyphicon-search sidebar__search-icon"></span>
|
||||
<div className="sidebar__collapse" onClick={this.handleClose}><span className="fa fa-angle-left"></span></div>
|
||||
<span onClick={this.clearFocus} className="search__clear">Cancel</span>
|
||||
<form role="form" className="search__form relative-div" onSubmit={this.handleSubmit}>
|
||||
<span className="glyphicon glyphicon-search sidebar__search-icon"></span>
|
||||
<input
|
||||
type="text"
|
||||
ref="search"
|
||||
className="form-control search-bar-box"
|
||||
className="form-control search-bar"
|
||||
placeholder="Search"
|
||||
value={this.state.search_term}
|
||||
onFocus={this.handleUserFocus}
|
||||
|
||||
@@ -68,10 +68,10 @@ var NavbarDropdown = React.createClass({
|
||||
for (var i = 0; i < this.state.teams.length; i++) {
|
||||
var teamName = this.state.teams[i];
|
||||
|
||||
teams.push(<li key={ teamName }><a href={window.location.origin + "/" + teamName }>Switch to { teamName }</a></li>);
|
||||
teams.push(<li key={ teamName }><a href={utils.getWindowLocationOrigin() + "/" + teamName }>Switch to { teamName }</a></li>);
|
||||
}
|
||||
}
|
||||
teams.push(<li><a href={window.location.origin + "/signup_team" }>Create a New Team</a></li>);
|
||||
teams.push(<li><a href={utils.getWindowLocationOrigin() + "/signup_team" }>Create a New Team</a></li>);
|
||||
|
||||
return (
|
||||
<ul className="nav navbar-nav navbar-right">
|
||||
@@ -107,6 +107,10 @@ module.exports = React.createClass({
|
||||
};
|
||||
},
|
||||
|
||||
toggleDropdown: function(e) {
|
||||
$('.team__header').find('.dropdown-toggle').trigger('click');
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var me = UserStore.getCurrentUser();
|
||||
|
||||
@@ -116,7 +120,7 @@ module.exports = React.createClass({
|
||||
|
||||
return (
|
||||
<div className="team__header theme">
|
||||
<a className="settings_link" href="#" data-toggle="modal" data-target="#user_settings1">
|
||||
<a href="#" onClick={this.toggleDropdown}>
|
||||
{ me.last_picture_update ?
|
||||
<img className="user__picture" src={"/api/v1/users/" + me.id + "/image?time=" + me.update_at} />
|
||||
:
|
||||
|
||||
@@ -20,21 +20,12 @@ module.exports = React.createClass({
|
||||
state.email_error = "";
|
||||
}
|
||||
|
||||
team.display_name = this.refs.name.getDOMNode().value.trim();
|
||||
if (!team.display_name) {
|
||||
state.name_error = "This field is required";
|
||||
state.inValid = true;
|
||||
}
|
||||
else {
|
||||
state.name_error = "";
|
||||
}
|
||||
|
||||
if (state.inValid) {
|
||||
this.setState(state);
|
||||
return;
|
||||
}
|
||||
|
||||
client.signupTeam(team.email, team.display_name,
|
||||
client.signupTeam(team.email,
|
||||
function(data) {
|
||||
if (data["follow_link"]) {
|
||||
window.location.href = data["follow_link"];
|
||||
@@ -55,7 +46,6 @@ module.exports = React.createClass({
|
||||
render: function() {
|
||||
|
||||
var email_error = this.state.email_error ? <label className='control-label'>{ this.state.email_error }</label> : null;
|
||||
var name_error = this.state.name_error ? <label className='control-label'>{ this.state.name_error }</label> : null;
|
||||
var server_error = this.state.server_error ? <div className={ "form-group has-error" }><label className='control-label'>{ this.state.server_error }</label></div> : null;
|
||||
|
||||
return (
|
||||
@@ -64,15 +54,11 @@ module.exports = React.createClass({
|
||||
<input autoFocus={true} type="email" ref="email" className="form-control" placeholder="Email Address" maxLength="128" />
|
||||
{ email_error }
|
||||
</div>
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="text" ref="name" className="form-control" placeholder={utils.toTitleCase(strings.Company) + " Name"} maxLength="64" />
|
||||
{ name_error }
|
||||
</div>
|
||||
{ server_error }
|
||||
<div className="form-group">
|
||||
<button className="btn btn-md btn-primary" type="submit">Sign up for Free</button>
|
||||
<button className="btn btn-md btn-primary" type="submit">Sign up</button>
|
||||
</div>
|
||||
<div className="form-group form-group--small">
|
||||
<div className="form-group margin--extra-2x">
|
||||
<span><a href="/find_team">{"Find my " + strings.Team}</a></span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -42,11 +42,15 @@ WelcomePage = React.createClass({
|
||||
state.email_error = "";
|
||||
}
|
||||
|
||||
client.signupTeam(email, this.props.state.team.name,
|
||||
client.signupTeam(email,
|
||||
function(data) {
|
||||
this.props.state.wizard = "finished";
|
||||
this.props.updateParent(this.props.state);
|
||||
window.location.href = "/signup_team_confirm/?email=" + encodeURI(email);
|
||||
if (data["follow_link"]) {
|
||||
window.location.href = data["follow_link"];
|
||||
} else {
|
||||
this.props.state.wizard = "finished";
|
||||
this.props.updateParent(this.props.state);
|
||||
window.location.href = "/signup_team_confirm/?email=" + encodeURIComponent(team.email);
|
||||
}
|
||||
}.bind(this),
|
||||
function(err) {
|
||||
this.state.server_error = err.message;
|
||||
@@ -80,19 +84,25 @@ WelcomePage = React.createClass({
|
||||
<div>
|
||||
<p>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>Welcome!</h2>
|
||||
<h3>{"Let's set up your " + strings.Team + " on " + config.SiteName + "."}</h3>
|
||||
<h3 className="sub-heading">Welcome to:</h3>
|
||||
<h1 className="margin--top-none">{config.SiteName}</h1>
|
||||
</p>
|
||||
<p className="margin--less">Let's setup your new team</p>
|
||||
<p>
|
||||
Please confirm your email address:<br />
|
||||
<span className="black">{ this.props.state.team.email }</span><br />
|
||||
<div className="inner__content">
|
||||
<div className="block--gray">{ this.props.state.team.email }</div>
|
||||
</div>
|
||||
</p>
|
||||
<p className="margin--extra color--light">
|
||||
Your account will administer the new team site. <br />
|
||||
You can add other administrators later.
|
||||
</p>
|
||||
<div className="form-group">
|
||||
<button className="btn-primary btn form-group" type="submit" onClick={this.submitNext}><i className="glyphicon glyphicon-ok"></i>Yes, this address is correct</button>
|
||||
{ storage_error }
|
||||
</div>
|
||||
<hr />
|
||||
<p>If this is not correct, you can switch to a different email. We'll send you a new invite right away.</p>
|
||||
<div className={ this.state.use_diff ? "" : "hidden" }>
|
||||
<div className={ email_error ? "form-group has-error" : "form-group" }>
|
||||
<div className="row">
|
||||
@@ -105,7 +115,7 @@ WelcomePage = React.createClass({
|
||||
{ server_error }
|
||||
<button className="btn btn-md btn-primary" type="button" onClick={this.handleDiffSubmit} type="submit">Use this instead</button>
|
||||
</div>
|
||||
<button type="button" onClick={this.handleDiffEmail} className={ this.state.use_diff ? "btn-default btn hidden" : "btn-default btn" }>Use a different address</button>
|
||||
<a href="#" onClick={this.handleDiffEmail} className={ this.state.use_diff ? "hidden" : "" }>Use a different email</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -128,6 +138,7 @@ TeamDisplayNamePage = React.createClass({
|
||||
|
||||
this.props.state.wizard = "team_url";
|
||||
this.props.state.team.display_name = display_name;
|
||||
this.props.state.team.name = utils.cleanUpUrlable(display_name);
|
||||
this.props.updateParent(this.props.state);
|
||||
},
|
||||
getInitialState: function() {
|
||||
@@ -158,9 +169,11 @@ TeamDisplayNamePage = React.createClass({
|
||||
</div>
|
||||
{ name_error }
|
||||
</div>
|
||||
<p>{"Your " + strings.Team + " name shows in menus and headings. It may include the name of your " + strings.Company + ", but it's not required."}</p>
|
||||
<button type="button" className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button>
|
||||
<button type="submit" className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
<div>{"Name your " + strings.Team + " in any language. Your " + strings.Team + " name shows in menus and headings."}</div>
|
||||
<button type="submit" className="btn btn-primary margin--extra" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
<div className="margin--extra">
|
||||
<a href="#" onClick={this.submitBack}>Back to previous step</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
@@ -248,17 +261,23 @@ TeamURLPage = React.createClass({
|
||||
<div className="row">
|
||||
<div className="col-sm-11">
|
||||
<div className="input-group">
|
||||
<span className="input-group-addon">{ window.location.origin + "/" }</span>
|
||||
<span className="input-group-addon">{ utils.getWindowLocationOrigin() + "/" }</span>
|
||||
<input type="text" ref="name" className="form-control" placeholder="" maxLength="128" defaultValue={this.props.state.team.name} autoFocus={true} onFocus={this.handleFocus}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{ name_error }
|
||||
</div>
|
||||
<p className="black">{"Pick something short and memorable for your " + strings.Team + "'s web address."}</p>
|
||||
<p>{"Your " + strings.Team + " URL can only contain lowercase letters, numbers and dashes. Also, it needs to start with a letter and cannot end in a dash."}</p>
|
||||
<button type="button" className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button>
|
||||
<button type="submit" className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
<p>{"Choose the web address of your new " + strings.Team + ":"}</p>
|
||||
<ul className="color--light">
|
||||
<li>Short and memorable is best</li>
|
||||
<li>Use lower case letters, numbers and dashes</li>
|
||||
<li>Must start with a letter and can't end in a dash</li>
|
||||
</ul>
|
||||
<button type="submit" className="btn btn-primary margin--extra" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
<div className="margin--extra">
|
||||
<a href="#" onClick={this.submitBack}>Back to previous step</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
@@ -461,14 +480,16 @@ SendInivtesPage = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<form>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>Send Invitations</h2>
|
||||
{ emails }
|
||||
<div className="form-group"><button type="button" className="btn-default btn" onClick={this.submitAddInvite}>Add Invitation</button></div>
|
||||
<div className="form btn-default-group"><button type="button" className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button> <button type="submit" className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button></div>
|
||||
</form>
|
||||
<p>{"If you'd prefer, you can send invitations after you finish setting up the "+ strings.Team + "."}</p>
|
||||
<div><a href="#" onClick={this.submitSkip}>Skip this step</a></div>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>{"Invite " + utils.toTitleCase(strings.Team) + " Members"}</h2>
|
||||
{ emails }
|
||||
<div className="form-group text-right"><a href="#" onClick={this.submitAddInvite}>Add Invitation</a></div>
|
||||
<div className="form-group"><button type="submit" className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button></div>
|
||||
</form>
|
||||
<p className="color--light">{"if you prefer, you can invite " + strings.Team + " members later"}<br /> and <a href="#" onClick={this.submitSkip}>skip this step</a> for now.</p>
|
||||
<div className="margin--extra">
|
||||
<a href="#" onClick={this.submitBack}>Back to previous step</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -512,19 +533,24 @@ UsernamePage = React.createClass({
|
||||
<div>
|
||||
<form>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>Choose a username</h2>
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<div className="row">
|
||||
<div className="col-sm-9">
|
||||
<input autoFocus={true} type="text" ref="name" className="form-control" placeholder="" defaultValue={this.props.state.user.username} maxLength="128" />
|
||||
<h2 className="margin--less">Your username</h2>
|
||||
<h5 className="color--light">{"Select a memorable username that makes it easy for " + strings.Team + "mates to identify you:"}</h5>
|
||||
<div className="inner__content margin--extra">
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<div className="row">
|
||||
<div className="col-sm-11">
|
||||
<h5><strong>Choose your username</strong></h5>
|
||||
<input autoFocus={true} type="text" ref="name" className="form-control" placeholder="" defaultValue={this.props.state.user.username} maxLength="128" />
|
||||
<div className="color--light form__hint">Usernames must begin with a letter and contain 3 to 15 characters made up of lowercase letters, numbers, and the symbols '.', '-' and '_'</div>
|
||||
</div>
|
||||
</div>
|
||||
{ name_error }
|
||||
</div>
|
||||
</div>
|
||||
{ name_error }
|
||||
<button type="submit" className="btn btn-primary margin--extra" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
<div className="margin--extra">
|
||||
<a href="#" onClick={this.submitBack}>Back to previous step</a>
|
||||
</div>
|
||||
<p>{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others."}</p>
|
||||
<p>It can be made of lowercase letters and numbers.</p>
|
||||
<button type="button" className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button>
|
||||
<button type="submit" className="btn-primary btn" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
@@ -542,15 +568,15 @@ PasswordPage = React.createClass({
|
||||
|
||||
var password = this.refs.password.getDOMNode().value.trim();
|
||||
if (!password || password.length < 5) {
|
||||
this.setState({name_error: "Please enter at least 5 characters"});
|
||||
this.setState({password_error: "Please enter at least 5 characters"});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({name_error: ""});
|
||||
this.setState({password_error: null, server_error: null});
|
||||
$('#finish-button').button('loading');
|
||||
var teamSignup = JSON.parse(JSON.stringify(this.props.state));
|
||||
teamSignup.user.password = password;
|
||||
teamSignup.user.allow_marketing = this.refs.email_service.getDOMNode().checked;
|
||||
teamSignup.user.allow_marketing = true;
|
||||
delete teamSignup.wizard;
|
||||
var ctl = this;
|
||||
|
||||
@@ -561,28 +587,26 @@ PasswordPage = React.createClass({
|
||||
|
||||
var props = this.props;
|
||||
|
||||
setTimeout(function() {
|
||||
$('#sign-up-button').button('reset');
|
||||
props.state.wizard = "finished";
|
||||
props.updateParent(props.state, true);
|
||||
$('#sign-up-button').button('reset');
|
||||
props.state.wizard = "finished";
|
||||
props.updateParent(props.state, true);
|
||||
|
||||
window.location.href = window.location.origin + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email);
|
||||
window.location.href = utils.getWindowLocationOrigin() + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email);
|
||||
|
||||
// client.loginByEmail(teamSignup.team.domain, teamSignup.team.email, teamSignup.user.password,
|
||||
// function(data) {
|
||||
// TeamStore.setLastName(teamSignup.team.domain);
|
||||
// UserStore.setLastEmail(teamSignup.team.email);
|
||||
// UserStore.setCurrentUser(data);
|
||||
// window.location.href = '/channels/town-square';
|
||||
// }.bind(ctl),
|
||||
// function(err) {
|
||||
// this.setState({name_error: err.message});
|
||||
// }.bind(ctl)
|
||||
// );
|
||||
}, 5000);
|
||||
// client.loginByEmail(teamSignup.team.domain, teamSignup.team.email, teamSignup.user.password,
|
||||
// function(data) {
|
||||
// TeamStore.setLastName(teamSignup.team.domain);
|
||||
// UserStore.setLastEmail(teamSignup.team.email);
|
||||
// UserStore.setCurrentUser(data);
|
||||
// window.location.href = '/channels/town-square';
|
||||
// }.bind(ctl),
|
||||
// function(err) {
|
||||
// this.setState({name_error: err.message});
|
||||
// }.bind(ctl)
|
||||
// );
|
||||
}.bind(this),
|
||||
function(err) {
|
||||
this.setState({name_error: err.message});
|
||||
this.setState({server_error: err.message});
|
||||
$('#sign-up-button').button('reset');
|
||||
}.bind(this)
|
||||
);
|
||||
@@ -594,30 +618,37 @@ PasswordPage = React.createClass({
|
||||
|
||||
client.track('signup', 'signup_team_07_password');
|
||||
|
||||
var name_error = this.state.name_error ? <label className="control-label">{ this.state.name_error }</label> : null;
|
||||
var password_error = this.state.password_error ? <div className="form-group has-error"><label className="control-label">{ this.state.password_error }</label></div> : null;
|
||||
var server_error = this.state.server_error ? <div className="form-group has-error"><label className="control-label">{ this.state.server_error }</label></div> : null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>Choose a password</h2>
|
||||
<p>You'll use your email address ({this.props.state.team.email}) and password to log into {config.SiteName}.</p>
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<div className="row">
|
||||
<div className="col-sm-9">
|
||||
<input autoFocus={true} type="password" ref="password" className="form-control" placeholder="" maxLength="128" />
|
||||
<h2 className="margin--less">Your password</h2>
|
||||
<h5 className="color--light">Select a password that you'll use to login with your email address:</h5>
|
||||
<div className="inner__content margin--extra">
|
||||
<h5><strong>Email</strong></h5>
|
||||
<div className="block--gray form-group">{this.props.state.team.email}</div>
|
||||
<div className={ password_error ? "form-group has-error" : "form-group" }>
|
||||
<div className="row">
|
||||
<div className="col-sm-11">
|
||||
<h5><strong>Choose your password</strong></h5>
|
||||
<input autoFocus={true} type="password" ref="password" className="form-control" placeholder="" maxLength="128" />
|
||||
<div className="color--light form__hint">Passwords must contain 5 to 50 characters. Your password will be strongest if it contains a mix of symbols, numbers, and upper and lowercase characters.</div>
|
||||
</div>
|
||||
</div>
|
||||
{ password_error }
|
||||
{ server_error }
|
||||
</div>
|
||||
</div>
|
||||
{ name_error }
|
||||
</div>
|
||||
<div className="form-group checkbox">
|
||||
<label><input type="checkbox" ref="email_service" /> It's ok to send me occassional email with updates about the {config.SiteName} service.</label>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<button type="button" className="btn btn-default" onClick={this.submitBack}><i className="glyphicon glyphicon-chevron-left"></i> Back</button>
|
||||
<button type="submit" className="btn-primary btn" id="finish-button" data-loading-text={"<span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> Creating "+strings.Team+"..."} onClick={this.submitNext}>Finish</button>
|
||||
<button type="submit" className="btn btn-primary margin--extra" id="finish-button" data-loading-text={"<span class='glyphicon glyphicon-refresh glyphicon-refresh-animate'></span> Creating "+strings.Team+"..."} onClick={this.submitNext}>Finish</button>
|
||||
</div>
|
||||
<p>By proceeding to create your account and use { config.SiteName }, you agree to our <a href={ config.TermsLink }>Terms of Service</a> and <a href={ config.PrivacyLink }>Privacy Policy</a>. If you do not agree, you cannot use {config.SiteName}.</p>
|
||||
<div className="margin--extra">
|
||||
<a href="#" onClick={this.submitBack}>Back to previous step</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
@@ -640,9 +671,6 @@ module.exports = React.createClass({
|
||||
props.wizard = "welcome";
|
||||
props.team = {};
|
||||
props.team.email = this.props.email;
|
||||
props.team.display_name = this.props.name;
|
||||
props.team.company_name = this.props.name;
|
||||
props.team.name = utils.cleanUpUrlable(this.props.name);
|
||||
props.team.allowed_domains = "";
|
||||
props.invites = [];
|
||||
props.invites.push("");
|
||||
|
||||
@@ -40,7 +40,7 @@ module.exports = React.createClass({
|
||||
|
||||
this.setState({name_error: "", email_error: "", password_error: "", server_error: ""});
|
||||
|
||||
this.state.user.allow_marketing = this.refs.email_service.getDOMNode().checked;
|
||||
this.state.user.allow_marketing = true;
|
||||
|
||||
client.createUser(this.state.user, this.state.data, this.state.hash,
|
||||
function(data) {
|
||||
@@ -104,8 +104,8 @@ module.exports = React.createClass({
|
||||
var yourEmailIs = this.state.user.email == "" ? "" : <span>Your email address is { this.state.user.email }. </span>
|
||||
|
||||
var email = (
|
||||
<div className={ this.state.original_email == "" ? "" : "hidden"} >
|
||||
<label className="control-label">Email</label>
|
||||
<div className={ this.state.original_email == "" ? "margin--extra" : "hidden"} >
|
||||
<h5><strong>What's your email address?</strong></h5>
|
||||
<div className={ email_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="email" ref="email" className="form-control" defaultValue={ this.state.user.email } placeholder="" maxLength="128" />
|
||||
{ email_error }
|
||||
@@ -124,29 +124,33 @@ module.exports = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<img className="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h3 className="text-center extra-margin">Signup to { config.SiteName }</h3>
|
||||
<div className="form-group form-group--small">
|
||||
<span></span>
|
||||
</div>
|
||||
<h5 className="margin--less">Welcome to:</h5>
|
||||
<h2 className="signup-team__name">{ this.props.teamDisplayName }</h2>
|
||||
<h2 className="signup-team__subdomain">on { config.SiteName }</h2>
|
||||
<h4 className="color--light">Let's create your account</h4>
|
||||
{ signup_message }
|
||||
<label className="control-label">Username</label>
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="text" ref="name" className="form-control" placeholder="" maxLength="128" />
|
||||
{ name_error }
|
||||
<p className="form__hint">Your username can be made of lowercase letters and numbers.</p>
|
||||
<p className="form__hint">{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others"}</p>
|
||||
</div>
|
||||
{ email }
|
||||
<label className="control-label">Password</label>
|
||||
<div className={ password_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="password" ref="password" className="form-control" placeholder="" maxLength="128" />
|
||||
{ password_error }
|
||||
</div>
|
||||
<p className={ this.state.original_email == "" ? "hidden" : ""}>{ yourEmailIs } You’ll use this address to sign in to {config.SiteName}.</p>
|
||||
<div className="checkbox"><label><input type="checkbox" ref="email_service" /> It's ok to send me occassional email with updates about the {config.SiteName} service. </label></div>
|
||||
<p><button onClick={this.handleSubmit} className="btn-primary btn">Create Account</button></p>
|
||||
<div className="inner__content">
|
||||
{ email }
|
||||
<p className={ this.state.original_email == "" ? "hidden" : ""}>{ yourEmailIs } You’ll use this address to sign in to {config.SiteName}.</p>
|
||||
<div className="margin--extra">
|
||||
<h5><strong>Choose your username</strong></h5>
|
||||
<div className={ name_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="text" ref="name" className="form-control" placeholder="" maxLength="128" />
|
||||
{ name_error }
|
||||
<p className="form__hint">Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'"</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="margin--extra">
|
||||
<h5><strong>Choose your password</strong></h5>
|
||||
<div className={ password_error ? "form-group has-error" : "form-group" }>
|
||||
<input type="password" ref="password" className="form-control" placeholder="" maxLength="128" />
|
||||
{ password_error }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="margin--extra"><button onClick={this.handleSubmit} className="btn-primary btn">Create Account</button></p>
|
||||
{ server_error }
|
||||
<p>By proceeding to create your account and use { config.SiteName }, you agree to our <a href={ config.TermsLink }>Terms of Service</a> and <a href={ config.PrivacyLink }>Privacy Policy</a>. If you do not agree, you cannot use {config.SiteName}.</p>
|
||||
<p>By creating an account and using Mattermost you are agreeing to our <a href={ config.TermsLink }>Terms of Service</a>. If you do not agree, you cannot use this service.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ module.exports = React.createClass({
|
||||
if (fileInfo.path.indexOf("/api/v1/files/get") !== -1) {
|
||||
fileInfo.path = fileInfo.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
fileInfo.path = window.location.origin + "/api/v1/files/get" + fileInfo.path;
|
||||
fileInfo.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + fileInfo.path;
|
||||
src = fileInfo['path'] + '_preview.jpg';
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ module.exports = React.createClass({
|
||||
if (info.path.indexOf("/api/v1/files/get") !== -1) {
|
||||
info.path = info.path.split("/api/v1/files/get")[1];
|
||||
}
|
||||
info.path = window.location.origin + "/api/v1/files/get" + info.path;
|
||||
info.path = utils.getWindowLocationOrigin() + "/api/v1/files/get" + info.path;
|
||||
preview_filename = info['path'] + '_preview.jpg';
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ module.exports = React.createClass({
|
||||
if (download_link.indexOf("/api/v1/files/get") !== -1) {
|
||||
download_link = download_link.split("/api/v1/files/get")[1];
|
||||
}
|
||||
download_link = window.location.origin + "/api/v1/files/get" + download_link;
|
||||
download_link = utils.getWindowLocationOrigin() + "/api/v1/files/get" + download_link;
|
||||
|
||||
return (
|
||||
<div className="modal fade image_modal" ref="modal" id={this.props.modalId} tabIndex="-1" role="dialog" aria-hidden="true">
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
"jest-cli": "~0.1.17",
|
||||
"reactify": "^0.15.2",
|
||||
"uglify-js": "~2.4.15",
|
||||
"watchify": "^2.1.1"
|
||||
"watchify": "^2.1.1",
|
||||
"eslint": "^0.24.1",
|
||||
"eslint-plugin-react": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "watchify --extension=jsx -o ../static/js/bundle.js -v -d ./**/*.jsx",
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
var SignupTeamComplete =require('../components/signup_team_complete.jsx');
|
||||
|
||||
global.window.setup_signup_team_complete_page = function(email, name, data, hash) {
|
||||
global.window.setup_signup_team_complete_page = function(email, data, hash) {
|
||||
React.render(
|
||||
<SignupTeamComplete name={name} email={email} hash={hash} data={data}/>,
|
||||
<SignupTeamComplete email={email} hash={hash} data={data}/>,
|
||||
document.getElementById('signup-team-complete')
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
var SignupUserComplete =require('../components/signup_user_complete.jsx');
|
||||
var SignupUserComplete = require('../components/signup_user_complete.jsx');
|
||||
|
||||
global.window.setup_signup_user_complete_page = function(email, name, ui_name, id, data, hash, auth_services) {
|
||||
React.render(
|
||||
|
||||
@@ -11,6 +11,12 @@ var BrowserStore = require('../stores/browser_store.jsx');
|
||||
|
||||
var CHANGE_EVENT = 'change';
|
||||
|
||||
var utils;
|
||||
function getWindowLocationOrigin() {
|
||||
if (!utils) utils = require('../utils/utils.jsx');
|
||||
return utils.getWindowLocationOrigin();
|
||||
}
|
||||
|
||||
var TeamStore = assign({}, EventEmitter.prototype, {
|
||||
emitChange: function() {
|
||||
this.emit(CHANGE_EVENT);
|
||||
@@ -58,7 +64,7 @@ var TeamStore = assign({}, EventEmitter.prototype, {
|
||||
return null;
|
||||
},
|
||||
getCurrentTeamUrl: function() {
|
||||
return window.location.origin + "/" + this.getCurrent().name;
|
||||
return getWindowLocationOrigin() + "/" + this.getCurrent().name;
|
||||
},
|
||||
storeTeam: function(team) {
|
||||
var teams = this._getTeams();
|
||||
|
||||
@@ -164,13 +164,13 @@ var UserStore = assign({}, EventEmitter.prototype, {
|
||||
BrowserStore.setItem("sessions", sessions);
|
||||
},
|
||||
getSessions: function() {
|
||||
return BrowserStore.getItem("sessions", []);
|
||||
return BrowserStore.getItem("sessions", {loading: true});
|
||||
},
|
||||
setAudits: function(audits) {
|
||||
BrowserStore.setItem("audits", audits);
|
||||
},
|
||||
getAudits: function() {
|
||||
return BrowserStore.getItem("audits", []);
|
||||
return BrowserStore.getItem("audits", {loading: true});
|
||||
},
|
||||
setTeams: function(teams) {
|
||||
BrowserStore.setItem("teams", teams);
|
||||
|
||||
@@ -341,13 +341,13 @@ module.exports.updateTeamDisplayName = function(data, success, error) {
|
||||
module.exports.track('api', 'api_teams_update_name');
|
||||
};
|
||||
|
||||
module.exports.signupTeam = function(email, display_name, success, error) {
|
||||
module.exports.signupTeam = function(email, success, error) {
|
||||
$.ajax({
|
||||
url: "/api/v1/teams/signup",
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
type: 'POST',
|
||||
data: JSON.stringify({email: email, display_name: display_name}),
|
||||
data: JSON.stringify({email: email}),
|
||||
success: success,
|
||||
error: function(xhr, status, err) {
|
||||
e = handleError("singupTeam", xhr, status, err);
|
||||
|
||||
@@ -22,8 +22,6 @@ module.exports.cleanUpUrlable = function(input) {
|
||||
return cleaned;
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports.isTestDomain = function() {
|
||||
|
||||
if ((/^localhost/).test(window.location.hostname))
|
||||
@@ -841,3 +839,12 @@ module.exports.getDisplayName = function(user) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//IE10 does not set window.location.origin automatically so this must be called instead when using it
|
||||
module.exports.getWindowLocationOrigin = function() {
|
||||
var windowLocationOrigin = window.location.origin;
|
||||
if (!windowLocationOrigin) {
|
||||
windowLocationOrigin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
|
||||
}
|
||||
return windowLocationOrigin;
|
||||
};
|
||||
|
||||
@@ -84,8 +84,32 @@
|
||||
// Team Header in Sidebar
|
||||
.sidebar--left, .sidebar--menu {
|
||||
.team__header {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
@include legacy-pie-clearfix;
|
||||
&:before {
|
||||
@include single-transition(all, 0.05s, linear);
|
||||
content: "";
|
||||
background: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
&:hover {
|
||||
&:before {
|
||||
background: rgba(black, 0.1);
|
||||
}
|
||||
.user__name {
|
||||
color: #fff;
|
||||
}
|
||||
.navbar-right {
|
||||
.dropdown-toggle {
|
||||
@include opacity(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -94,12 +118,11 @@
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 22px;
|
||||
z-index: 5;
|
||||
.dropdown-toggle {
|
||||
@include single-transition(all, 0.1s, linear);
|
||||
padding: 10px;
|
||||
@include opacity(0.8);
|
||||
&:hover {
|
||||
@include opacity(1);
|
||||
}
|
||||
}
|
||||
.dropdown-menu {
|
||||
li a {
|
||||
@@ -124,6 +147,8 @@
|
||||
.header__info {
|
||||
color: #fff;
|
||||
padding-left: 4px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
.team__name, .user__name {
|
||||
display: block;
|
||||
@@ -137,9 +162,11 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
.user__name {
|
||||
@include single-transition(all, 0.1s, linear);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #eee;
|
||||
color: rgba(#fff, 0.8);
|
||||
}
|
||||
> .nav {
|
||||
> li {
|
||||
@@ -250,10 +277,10 @@
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
margin: 9px 4px 3px 0;
|
||||
margin: 9px 6px 3px 0;
|
||||
&:hover {
|
||||
svg {
|
||||
fill: #888;
|
||||
fill: #777;
|
||||
}
|
||||
}
|
||||
a {
|
||||
@@ -263,6 +290,6 @@
|
||||
svg {
|
||||
vertical-align: top;
|
||||
margin-top: 8px;
|
||||
fill: #AAA;
|
||||
fill: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
.navbar-default {
|
||||
position: absolute;
|
||||
border: none;
|
||||
min-height: 50px;
|
||||
min-height: 45px;
|
||||
background: $primary-color;
|
||||
.navbar-nav {
|
||||
> li {
|
||||
> a {
|
||||
height: 50px;
|
||||
height: 45px;
|
||||
padding: 0 1.3em;
|
||||
i {
|
||||
line-height: 50px;
|
||||
line-height: 45px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
padding: 0 10px;
|
||||
line-height: 53px;
|
||||
height: 50px;
|
||||
line-height: 48px;
|
||||
height: 44px;
|
||||
z-index: 5;
|
||||
fill: #fff;
|
||||
.icon-bar {
|
||||
@@ -38,8 +38,8 @@
|
||||
}
|
||||
.navbar-brand {
|
||||
padding: 0 0.5em;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
float: none;
|
||||
font-size: 16px;
|
||||
.heading {
|
||||
|
||||
@@ -426,13 +426,15 @@
|
||||
}
|
||||
body {
|
||||
&.white {
|
||||
.row.content {
|
||||
.inner__wrap {
|
||||
>.row.content {
|
||||
margin-bottom: -185px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer, .footer-pane, .footer-push {
|
||||
height: auto;
|
||||
height: 187px;
|
||||
}
|
||||
.footer-pane {
|
||||
.footer-link {
|
||||
@@ -446,28 +448,39 @@
|
||||
}
|
||||
}
|
||||
.search-bar__container {
|
||||
padding: 10px 8px 13px;
|
||||
padding: 0;
|
||||
height: 45px;
|
||||
background: $primary-color;
|
||||
color: #fff;
|
||||
&.focused {
|
||||
.sidebar__collapse {
|
||||
@include translateX(-45px);
|
||||
}
|
||||
.search__form {
|
||||
padding-left: 10px;
|
||||
padding-right: 67px;
|
||||
}
|
||||
.search__clear {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.search__form {
|
||||
border: none;
|
||||
padding: 0 60px 0 35px;
|
||||
padding: 7px 20px 0 49px;
|
||||
height: 45px;
|
||||
position: relative;
|
||||
@include single-transition(all, 0.2s, linear);
|
||||
.form-control {
|
||||
line-height: normal;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0 10px 0 31px;
|
||||
background: rgba(black, 0.2);
|
||||
@include border-radius(3px);
|
||||
color: #fff;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid #FFF;
|
||||
border-bottom: 1px solid rgba(#fff, 0.4);
|
||||
&:focus {
|
||||
border-bottom: 1px solid rgba(#fff, 0.8);
|
||||
}
|
||||
}
|
||||
input[type=text] {
|
||||
@include input-placeholder {
|
||||
@include input-placeholder {
|
||||
color: #fff;
|
||||
color: rgba(#fff, 0.6);
|
||||
color: rgba(#fff, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,11 +561,6 @@
|
||||
.sidebar--right__close {
|
||||
display: none;
|
||||
}
|
||||
.search__form {
|
||||
.glyphicon {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.inner__wrap {
|
||||
&.move--right {
|
||||
@@ -648,7 +656,7 @@
|
||||
display: block;
|
||||
}
|
||||
.access__report {
|
||||
margin: 0 0 15px 15px;
|
||||
margin: 0 0 15px 15px;
|
||||
}
|
||||
.access__date {
|
||||
div {
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
.search-bar__container {
|
||||
padding: 8px 8px 8px 0;
|
||||
}
|
||||
.sidebar__collapse {
|
||||
width: auto;
|
||||
height: auto;
|
||||
.search__clear {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: 15px;
|
||||
cursor: pointer;
|
||||
padding: 1em 0;
|
||||
right: 0;
|
||||
line-height: 45px;
|
||||
margin-right: 13px;
|
||||
z-index: 5;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sidebar__collapse {
|
||||
cursor: pointer;
|
||||
z-index: 5;
|
||||
fill: #FFF;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
font-size: 35px;
|
||||
width: 49px;
|
||||
@include single-transition(all, 0.2s, linear);
|
||||
@include translateX(0px);
|
||||
text-align: center;
|
||||
padding-left: 1px;
|
||||
line-height: 40px;
|
||||
display: none;
|
||||
}
|
||||
.sidebar__search-icon {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 18px;
|
||||
font-size: 16px;
|
||||
@include opacity(0.8);
|
||||
top: 15px;
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
color: rgba(#fff, 0.5);
|
||||
display: none;
|
||||
}
|
||||
.search__form {
|
||||
@@ -30,9 +44,8 @@
|
||||
.sidebar--right & {
|
||||
width: 100%;
|
||||
}
|
||||
.search-bar-box {
|
||||
.search-bar {
|
||||
height: 40px;
|
||||
border: 1px solid #ddd;
|
||||
padding-right: 30px;
|
||||
box-shadow: none;
|
||||
.search-bar__container & {
|
||||
|
||||
@@ -9,65 +9,108 @@
|
||||
max-width: 380px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
&.padding--less {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5em;
|
||||
margin-bottom: 0.8em;
|
||||
letter-spacing: -0.5px;
|
||||
font-size: em(30px);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 600;
|
||||
margin: 0 0 1.3em 0;
|
||||
font-size: 1.5em;
|
||||
&.extra-margin {
|
||||
margin-bottom: 2.5em;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: em(20px);
|
||||
font-weight: 600;
|
||||
margin-bottom: 1em;
|
||||
&.text--light {
|
||||
font-weight: 300;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: em(16px);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1em;
|
||||
.black, &.black {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.inner__content {
|
||||
padding: 0 15px;
|
||||
margin: 30px 0 20px;
|
||||
}
|
||||
|
||||
.block--gray {
|
||||
background: #f2f2f2;
|
||||
display: inline-block;
|
||||
padding: 0.85em 1.2em;
|
||||
font-weight: 600;
|
||||
@include border-radius(3px);
|
||||
}
|
||||
|
||||
form {
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
.form__hint {
|
||||
font-size: 0.95em;
|
||||
color: #999;
|
||||
margin: 10px 0;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
.external-link {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
.signup-team-confirm__container {
|
||||
padding: 100px 0px 100px 0px;
|
||||
}
|
||||
|
||||
.signup-team-logo {
|
||||
display: none;
|
||||
width: 210px;
|
||||
margin: 0 0 2em 0;
|
||||
}
|
||||
|
||||
.signup-team-login {
|
||||
padding-bottom: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.signup-team__name {
|
||||
margin: 0.5em 0 0;
|
||||
font-size: 2.2em;
|
||||
font-weight: 600;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.signup-team__subdomain {
|
||||
margin: 0.2em 0 1.2em;
|
||||
font-size: 1.5em;
|
||||
padding-left: 1rem;
|
||||
font-weight: 300;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.signup-team__subdomain {
|
||||
font-size: 1.5em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
height: em(38px);
|
||||
}
|
||||
|
||||
.or__container {
|
||||
height: 1px;
|
||||
background: #dddddd;
|
||||
@@ -84,6 +127,12 @@
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: em(7px) em(15px);
|
||||
font-weight: 600;
|
||||
@@ -121,8 +170,8 @@
|
||||
}
|
||||
.glyphicon {
|
||||
&.glyphicon-ok, &.glyphicon-refresh {
|
||||
margin-right: 0.3em;
|
||||
left: -5px;
|
||||
margin-right: 0.5em;
|
||||
left: -2px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
&.glyphicon-chevron-right {
|
||||
@@ -137,6 +186,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.has-error {
|
||||
.control-label {
|
||||
background: #f2f2f2;
|
||||
@@ -148,13 +198,14 @@
|
||||
color: #999;
|
||||
width: 100%;
|
||||
&:before {
|
||||
@extend .fa;
|
||||
content: "\f071";
|
||||
margin-right: 4px;
|
||||
color: #aaa;
|
||||
@extend .fa;
|
||||
content: "\f071";
|
||||
margin-right: 4px;
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reset-form {
|
||||
@include border-radius(3px);
|
||||
position: relative;
|
||||
@@ -163,19 +214,49 @@
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.signup-team-confirm__container {
|
||||
padding: 100px 0px 100px 0px;
|
||||
}
|
||||
// Modifier Styles
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
&.margin--top-none {
|
||||
margin-top: 0;
|
||||
}
|
||||
&.margin--bottom-none {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
&.margin--less {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
&.sub-heading {
|
||||
font-weight: 400;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
&.color--light {
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
||||
.signup-team-logo {
|
||||
display: none;
|
||||
width: 210px;
|
||||
margin: 0 0 2em 0;
|
||||
}
|
||||
p {
|
||||
&.margin--extra {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
&.margin--less {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
.black, &.black {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.color--light {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.margin--extra {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
.margin--extra-2x {
|
||||
margin-top: 6em;
|
||||
}
|
||||
|
||||
.signup-team-login {
|
||||
padding-bottom: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="signup-team__container">
|
||||
<img class="signup-team-logo" src="/static/images/logo.png" />
|
||||
<h2>All team communication in one place, searchable and accessible anywhere</h2>
|
||||
<h4 class="text--light">{{ .SiteName }} is free for an unlimited time, for unlimited users </h4 class="text--light">
|
||||
<h1>Mattermost</h1>
|
||||
<h4 class="color--light">All team communication in one place, searchable and accesible anywhere</h4>
|
||||
<div id="signup-team"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.setup_signup_team_complete_page('{{.Props.Email}}', '{{.Props.DisplayName}}', '{{.Props.Data}}', '{{.Props.Hash}}');
|
||||
window.setup_signup_team_complete_page('{{.Props.Email}}', '{{.Props.Data}}', '{{.Props.Hash}}');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="inner__wrap">
|
||||
<div class="row content">
|
||||
<div class="col-sm-12">
|
||||
<div class="signup-team__container">
|
||||
<div class="signup-team__container padding--less">
|
||||
<div id="signup-user-complete"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -219,7 +219,6 @@ func signupTeamComplete(c *api.Context, w http.ResponseWriter, r *http.Request)
|
||||
|
||||
page := NewHtmlTemplatePage("signup_team_complete", "Complete Team Sign Up")
|
||||
page.Props["Email"] = props["email"]
|
||||
page.Props["DisplayName"] = props["display_name"]
|
||||
page.Props["Data"] = data
|
||||
page.Props["Hash"] = hash
|
||||
page.Render(c, w)
|
||||
|
||||
Reference in New Issue
Block a user