[NEW] Setup Wizard (#10523)

* welcome

* .

* stylelint

* new ilustration

* new layout

* .

* implements dicts

* added all setup wizard settings to wizard

* fix some setup wizard css

* fix setup wizard js linter errors

* remove old setup wizard templaates

* setup wizard has just one main tag now

* setup wizard registration fields filter is more readable

* add register server page to setup wizard

* fix setup wizard progress bar on RTL

* setup wizard is registering users

* Add setup wizard tests, routes and fix batch

* fix setup wizard tests

* add api test back

* comment rocketchat:google-natural-language package and remove logs

* add some translation keys for setup wizard

* remove old setup wizard template

* fix sort code on setup wizard

* fix getWizardSetting method

* new migration for setupwizard

* setup wizard setting migration

* fix setupwizard migration

* Update versions

* fix some setup wizard code logic

* fix setup wizard registerServer setting

* rever package-lock.json

* rever google-natural-language .npm folder

* rever meteor packages file and add setup wizard

* remove some default values from setup wizard settings

* add advocacy option on setup wizard industry setting

* change key name to setting to make the filter more readable on setup wizard

* change key name to setting to make the filter more readable on setup wizard

* add findWizardSettings on models Settings and handle errors of getWizardSettings method

* change setting to key to make the filter more readable on setup wizard

* fix setup wizard settings filter map

* remove serverHasAdminUser method on setup wizard

* fix setup wizard tests

* fix setup wizard final step workspace link

* fix setup wizard tests
pull/10673/head^2
Karl Prieb 7 years ago committed by Rodrigo Nascimento
parent 66f719e5c1
commit 08149ebebb
  1. 1
      .eslintrc
  2. 1
      .meteor/packages
  3. 1
      .meteor/versions
  4. 16
      client/routes/router.js
  5. 2
      client/startup/userSetUtcOffset.js
  6. 7
      packages/rocketchat-assets/server/assets.js
  7. 297
      packages/rocketchat-i18n/i18n/en.i18n.json
  8. 4
      packages/rocketchat-lib/server/models/Settings.js
  9. 1206
      packages/rocketchat-lib/server/startup/settings.js
  10. 192
      packages/rocketchat-setup-wizard/client/setupWizard.html
  11. 272
      packages/rocketchat-setup-wizard/client/setupWizard.js
  12. 17
      packages/rocketchat-setup-wizard/package.js
  13. 9
      packages/rocketchat-setup-wizard/server/lib/getWizardSettings.js
  14. 38
      packages/rocketchat-statistics/server/functions/get.js
  15. 465
      packages/rocketchat-theme/client/imports/components/setup-wizard.css
  16. 4
      packages/rocketchat-theme/client/imports/forms/input.css
  17. 10
      packages/rocketchat-theme/client/imports/forms/select.css
  18. 1
      packages/rocketchat-theme/client/main.css
  19. 11
      packages/rocketchat-ui-admin/client/admin.js
  20. 66
      packages/rocketchat-ui-master/client/main.html
  21. 12
      packages/rocketchat-ui-master/client/main.js
  22. 1
      public/images/logo/logo-black.svg
  23. BIN
      public/images/setup-wizard-intro.png
  24. 15
      server/startup/migrations/v117.js
  25. 78
      tests/end-to-end/ui/00-login.js
  26. 36
      tests/pageobjects/setup-wizard.page.js

@ -131,6 +131,7 @@
"parentCall" : false,
"Promise" : false,
"Random" : false,
"ReactiveDict" : false,
"ReactiveVar" : false,
"Reload" : false,
"RocketChat" : true,

@ -112,6 +112,7 @@ rocketchat:push-notifications
rocketchat:reactions
rocketchat:apps
rocketchat:sandstorm
rocketchat:setup-wizard
rocketchat:slackbridge
rocketchat:slashcommands-archive
rocketchat:slashcommands-asciiarts

@ -202,6 +202,7 @@ rocketchat:push-notifications@0.0.1
rocketchat:reactions@0.0.1
rocketchat:sandstorm@0.0.1
rocketchat:search@0.0.1
rocketchat:setup-wizard@0.0.1
rocketchat:slackbridge@0.0.1
rocketchat:slashcommands-archive@0.0.1
rocketchat:slashcommands-asciiarts@0.0.1

@ -149,6 +149,22 @@ FlowRouter.route('/register/:hash', {
}
});
FlowRouter.route('/setup-wizard', {
name: 'setup-wizard',
action() {
BlazeLayout.render('setupWizard');
}
});
FlowRouter.route('/setup-wizard/final', {
name: 'setup-wizard-final',
action() {
BlazeLayout.render('setupWizardFinal');
}
});
FlowRouter.notFound = {
action() {
BlazeLayout.render('pageNotFound');

@ -2,7 +2,7 @@ import moment from 'moment';
Meteor.startup(function() {
Tracker.autorun(function() {
const user = Meteor.user();
const user = RocketChat.models.Users.findOne({_id: Meteor.userId()}, {fields: {statusConnection: 1, utcOffset: 1}});
if (user && user.statusConnection === 'online') {
const utcOffset = moment().utcOffset() / 60;
if (user.utcOffset !== utcOffset) {

@ -22,6 +22,10 @@ const assets = {
extensions: ['svg', 'png', 'jpg', 'jpeg'],
width: undefined,
height: undefined
},
wizard: {
step: 3,
order: 2
}
},
favicon_ico: {
@ -296,7 +300,8 @@ function addAssetToSetting(key, value) {
fileConstraints: value.constraints,
i18nLabel: value.label,
asset: key,
public: true
public: true,
wizard: value.wizard
});
}

@ -184,7 +184,9 @@
"additional_integrations_Zapier": "Are you looking to integrate other software and applications with Rocket.Chat but you don't have the time to manually do it? Then we suggest using Zapier which we fully support. Read more about it on our documentation. <a href='https://rocket.chat/docs/administrator-guides/integrations/zapier/using-zaps/' target='_blank'>https://rocket.chat/docs/administrator-guides/integrations/zapier/using-zaps/</a>",
"additional_integrations_Bots": "If you are looking for how to integrate your own bot, then look no further than our Hubot adapter. <a href='https://github.com/RocketChat/hubot-rocketchat' target='_blank'>https://github.com/RocketChat/hubot-rocketchat</a>",
"Administration": "Administration",
"Admin_Info": "Admin Info",
"Adult_images_are_not_allowed": "Adult images are not allowed",
"Advocacy": "Advocacy",
"After_OAuth2_authentication_users_will_be_redirected_to_this_URL": "After OAuth2 authentication, users will be redirected to this URL",
"Agent": "Agent",
"Agent_added": "Agent added",
@ -340,6 +342,7 @@
"ban-user_description": "Permission to ban a user from a channel",
"Beta_feature_Depends_on_Video_Conference_to_be_enabled": "Beta feature. Depends on Video Conference to be enabled.",
"Block_User": "Block User",
"Blockchain": "Blockchain",
"Body": "Body",
"bold": "bold",
"bot_request": "Bot request",
@ -488,12 +491,16 @@
"Collapse_Embedded_Media_By_Default": "Collapse Embedded Media by Default",
"Color": "Color",
"Contains_Security_Fixes": "Contains Security Fixes",
"Continue": "Continue",
"Commands": "Commands",
"Comment_to_leave_on_closing_session": "Comment to Leave on Closing Session",
"Common_Access": "Common Access",
"Community": "Community",
"Compact": "Compact",
"Computer": "Computer",
"Confirm_password": "Confirm your password",
"Consulting": "Consulting",
"Consumer_Goods": "Consumer Goods",
"Content": "Content",
"Conversation": "Conversation",
"Conversation_closed": "Conversation closed: __comment__.",
@ -504,6 +511,7 @@
"Copy_to_clipboard": "Copy to clipboard",
"COPY_TO_CLIPBOARD": "COPY TO CLIPBOARD",
"Count": "Count",
"Country": "Country",
"Cozy": "Cozy",
"Create": "Create",
"create-c": "Create Public Channels",
@ -661,6 +669,7 @@
"edited": "edited",
"Editing_room": "Editing room",
"Editing_user": "Editing user",
"Education": "Education",
"Email": "Email",
"Email_address_to_send_offline_messages": "Email Address to Send Offline Messages",
"Email_already_exists": "Email already exists",
@ -698,6 +707,8 @@
"Enter_name_here": "Enter name here",
"Enter_Normal": "Normal mode (send with Enter)",
"Enter_to": "Enter to",
"Entertainment": "Entertainment",
"Enterprise": "Enterprise",
"Error": "Error",
"Error_404": "Error:404",
"error-action-not-allowed": "__action__ is not allowed",
@ -840,6 +851,7 @@
"FileUpload_Storage_Type": "Storage Type",
"First_Channel_After_Login": "First Channel After Login",
"Flags": "Flags",
"Financial_Services": "Financial Services",
"Follow_social_profiles": "Follow our social profiles, fork us on github and share your thoughts about the rocket.chat app on our trello board.",
"Fonts": "Fonts",
"Food_and_Drink": "Food & Drink",
@ -867,6 +879,7 @@
"From": "From",
"From_Email": "From Email",
"From_email_warning": "<b>Warning</b>: The field <b>From</b> is subject to your mail server settings.",
"Gaming": "Gaming",
"General": "General",
"github_no_public_email": "You don't have any email as public email in your GitHub account",
"Give_a_unique_name_for_the_custom_oauth": "Give a unique name for the custom oauth",
@ -893,6 +906,8 @@
"GoogleVision_Type_Properties": "Properties (Color) Detection",
"GoogleVision_Type_SafeSearch": "SafeSearch Detection",
"GoogleVision_Type_Similar": "Search Similar Images",
"Go_to_your_workspace": "Go to your workspace",
"Government": "Government",
"Group_by_Type": "Group by Type",
"Group_favorites": "Group favorites",
"Group_mentions_only": "Group mentions only",
@ -900,7 +915,9 @@
"Hash": "Hash",
"Header": "Header",
"Header_and_Footer": "Header and Footer",
"Healthcare_and_Pharmaceutical": "Healthcare/Pharmaceutical",
"Helpers": "Helpers",
"Help_Center": "Help Center",
"Hex_Color_Preview": "Hex Color Preview",
"Hidden": "Hidden",
"Hide_Avatars": "Hide Avatars",
@ -973,6 +990,7 @@
"Importer_Source_File": "Source File Selection",
"Incoming_Livechats": "Incoming Livechats",
"Incoming_WebHook": "Incoming WebHook",
"Industry": "Industry",
"initials_avatar": "Initials Avatar",
"inline_code": "inline code",
"Install_Extension": "Install Extension",
@ -985,6 +1003,7 @@
"Installed_at": "Installed at",
"Instance_Record": "Instance Record",
"Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message",
"Insurance": "Insurance",
"Integration_added": "Integration has been added",
"Integration_Advanced_Settings": "Advanced Settings",
"Integration_disabled": "Integration disabled",
@ -1086,6 +1105,7 @@
"italics": "italics",
"Jitsi_Chrome_Extension": "Chrome Extension Id",
"Jitsi_Enable_Channels": "Enable in Channels",
"Job_Title": "Job Title",
"join": "Join",
"join-without-join-code": "Join Without Join Code",
"join-without-join-code_description": "Permission to bypass the join code in channels with join code enabled",
@ -1129,6 +1149,7 @@
"Last_login": "Last login",
"Last_Message_At": "Last Message At",
"Last_seen": "Last seen",
"Launched_successfully": "Launched successfully",
"Layout": "Layout",
"Layout_Home_Body": "Home Body",
"Layout_Home_Title": "Home Title",
@ -1270,6 +1291,7 @@
"Logged_out_of_other_clients_successfully": "Logged out of other clients successfully",
"Login": "Login",
"Login_with": "Login with %s",
"Logistics": "Logistics",
"Logout": "Logout",
"Logout_Others": "Logout From Other Logged In Locations",
"mail-messages": "Mail Messages",
@ -1303,6 +1325,7 @@
"Manager_removed": "Manager removed",
"Managing_assets": "Managing assets",
"Managing_integrations": "Managing integrations",
"Manufacturing": "Manufacturing",
"MapView_Enabled": "Enable Mapview",
"MapView_Enabled_Description": "Enabling mapview will display a location share button on the left of the chat input field.",
"MapView_GMapsAPIKey": "Google Static Maps API Key",
@ -1320,6 +1343,7 @@
"Markdown_SupportSchemesForLink": "Markdown Support Schemes for Link",
"Markdown_SupportSchemesForLink_Description": "Comma-separated list of allowed schemes",
"Max_length_is": "Max length is %s",
"Media": "Media",
"Members_List": "Members List",
"mention-all": "Mention All",
"mention-all_description": "Permission to use the @all mention",
@ -1476,6 +1500,7 @@
"Nobody_available": "Nobody available",
"Node_version": "Node Version",
"None": "None",
"Nonprofit": "Nonprofit",
"Normal": "Normal",
"Not_authorized": "Not authorized",
"Not_Available": "Not Available",
@ -1538,6 +1563,10 @@
"Oops_page_not_found": "Oops, page not found",
"Or_talk_as_anonymous": "Or talk as anonymous",
"Order": "Order",
"Organization_Email": "Organization Email",
"Organization_Info": "Organization Info",
"Organization_Name": "Organization Name",
"Organization_Type": "Organization Type",
"Original": "Original",
"OS_Arch": "OS Arch",
"OS_Cpus": "OS CPU Count",
@ -1548,6 +1577,7 @@
"OS_Totalmem": "OS Total Memory",
"OS_Type": "OS Type",
"OS_Uptime": "OS Uptime",
"Other": "Other",
"others": "others",
"OTR": "OTR",
"OTR_is_only_available_when_both_users_are_online": "OTR is only available when both users are online",
@ -1617,12 +1647,15 @@
"Private_Group": "Private Group",
"Private_Groups": "Private Groups",
"Private_Groups_list": "List of Private Groups",
"Private_Team": "Private Team",
"Profile": "Profile",
"Profile_details": "Profile Details",
"Profile_picture": "Profile Picture",
"Profile_saved_successfully": "Profile saved successfully",
"Public": "Public",
"Public_Channel": "Public Channel",
"Public_Community": "Public Community",
"Public_Relations": "Public Relations",
"Push": "Push",
"Push_apn_cert": "APN Cert",
"Push_apn_dev_cert": "APN Dev Cert",
@ -1658,6 +1691,7 @@
"Read_only_group": "Read Only Group",
"Reason_To_Join": "Reason to Join",
"RealName_Change_Disabled": "Your Rocket.Chat administrator has disabled the changing of names",
"Real_Estate": "Real Estate",
"Receive_alerts": "Receive alerts",
"Receive_Group_Mentions": "Receive @all and @here mentions",
"Record": "Record",
@ -1667,11 +1701,13 @@
"Refresh_your_page_after_install_to_enable_screen_sharing": "Refresh your page after install to enable screen sharing",
"Regenerate_codes": "Regenerate codes",
"Register": "Register a new account",
"Register_Server": "Register Server",
"Registration": "Registration",
"Registration_Succeeded": "Registration Succeeded",
"Registration_via_Admin": "Registration via Admin",
"Regular_Expressions": "Regular Expressions",
"Release": "Release",
"Religious": "Religious",
"Reload": "Reload",
"Reload_Pages": "Reload Pages",
"Remove": "Remove",
@ -1702,6 +1738,7 @@
"Reset_section_settings": "Reset Section Settings",
"Restart": "Restart",
"Restart_the_server": "Restart the server",
"Retail": "Retail",
"Retry_Count": "Retry Count",
"Apps": "Apps",
"App_Information": "App Information",
@ -1774,6 +1811,8 @@
"Saving": "Saving",
"Scan_QR_code": "Using an authenticator app like Google Authenticator, Authy or Duo, scan the QR code. It will display a 6 digit code which you need to enter below.",
"Scan_QR_code_alternative_s": "If you can't scan the QR code, you may enter code manually instead: __code__",
"Setup_Wizard": "Setup Wizard",
"Setup_Wizard_Info": "We’ll guide you through setting up your first admin user, configuring your organisation and registering your server to receive free push notifications and more.",
"Scope": "Scope",
"Screen_Share": "Screen Share",
"Script_Enabled": "Script Enabled",
@ -1820,6 +1859,8 @@
"Sending": "Sending...",
"Sent_an_attachment": "Sent an attachment",
"Served_By": "Served By",
"Server_Info": "Server Info",
"Server_Type": "Server Type",
"Service": "Service",
"Service_account_key": "Service account key",
"set-moderator": "Set Moderator",
@ -1861,6 +1902,7 @@
"Site_Name": "Site Name",
"Site_Url": "Site URL",
"Site_Url_Description": "Example: https://chat.domain.com/",
"Size": "Size",
"Skip": "Skip",
"SlackBridge_error": "SlackBridge got an error while importing your messages at %s: %s",
"SlackBridge_finish": "SlackBridge has finished importing the messages at %s. Please reload to view all messages.",
@ -1901,6 +1943,7 @@
"Snippet_Added": "Created on %s",
"Snippet_Messages": "Snippet Messages",
"Snippeted_a_message": "Created a snippet __snippetLink__",
"Social_Network": "Social Network",
"Sorry_page_you_requested_does_not_exists_or_was_deleted": "Sorry, page you requested does not exists or was deleted!",
"Sort_by_activity": "Sort by Activity",
"Sound": "Sound",
@ -1941,6 +1984,7 @@
"Stats_Total_Rooms": "Total Rooms",
"Stats_Total_Users": "Total Users",
"Status": "Status",
"Step": "Step",
"Stop_Recording": "Stop Recording",
"Store_Last_Message": "Store Last Message",
"Store_Last_Message_Sent_per_Room": "Store last message sent on each room.",
@ -1965,7 +2009,10 @@
"Take_it": "Take it!",
"TargetRoom": "Target Room",
"TargetRoom_Description": "The room where messages will be sent which are a result of this event being fired. Only one target room is allowed and it must exist.",
"Telecom": "Telecom",
"Team": "Team",
"Technology_Provider": "Technology Provider",
"Technology_Services": "Technology Services",
"Test_Connection": "Test Connection",
"Test_Desktop_Notifications": "Test Desktop Notifications",
"Thank_you_exclamation_mark": "Thank you!",
@ -2059,6 +2106,7 @@
"Tokens_Required_Input_Error": "Invalid typed tokens.",
"Tokens_Required_Input_Placeholder": "Tokens asset names",
"Topic": "Topic",
"Tourism": "Tourism",
"Transcript_Enabled": "Ask Visitor if They Would Like a Transcript After Chat Closed",
"Transcript_message": "Message to Show When Asking About Transcript",
"Transcript_of_your_livechat_conversation": "Transcript of your livechat conversation.",
@ -2079,9 +2127,12 @@
"Two-factor_authentication_native_mobile_app_warning": "WARNING: Once you enable this, you will not be able to login on the native mobile apps (Rocket.Chat+) using your password until they implement the 2FA.",
"Type": "Type",
"Type_your_email": "Type your email",
"Type_your_job_title": "Type your job title",
"Type_your_message": "Type your message",
"Type_your_name": "Type your name",
"Type_your_new_password": "Type your new password",
"Type_your_password": "Type your password",
"Type_your_username": "Type your username",
"UI_Allow_room_names_with_special_chars": "Allow Special Characters in Room Names",
"UI_Click_Direct_Message": "Click to Create Direct Message",
"UI_Click_Direct_Message_Description": "Skip opening profile tab, instead go straight to conversation",
@ -2344,5 +2395,247 @@
"your_message": "your message",
"your_message_optional": "your message (optional)",
"Your_password_is_wrong": "Your password is wrong!",
"Your_push_was_sent_to_s_devices": "Your push was sent to %s devices"
}
"Your_push_was_sent_to_s_devices": "Your push was sent to %s devices",
"Your_server_link": "Your server link",
"Your_workspace_is_ready": "Your workspace is ready to use 🎉",
"Worldwide": "Worldwide",
"Country_Afghanistan": "Afghanistan",
"Country_Albania": "Albania",
"Country_Algeria": "Algeria",
"Country_American_Samoa": "American Samoa",
"Country_Andorra": "Andorra",
"Country_Angola": "Angola",
"Country_Anguilla": "Anguilla",
"Country_Antarctica": "Antarctica",
"Country_Antigua_and_Barbuda": "Antigua and Barbuda",
"Country_Argentina": "Argentina",
"Country_Armenia": "Armenia",
"Country_Aruba": "Aruba",
"Country_Australia": "Australia",
"Country_Austria": "Austria",
"Country_Azerbaijan": "Azerbaijan",
"Country_Bahamas": "Bahamas",
"Country_Bahrain": "Bahrain",
"Country_Bangladesh": "Bangladesh",
"Country_Barbados": "Barbados",
"Country_Belarus": "Belarus",
"Country_Belgium": "Belgium",
"Country_Belize": "Belize",
"Country_Benin": "Benin",
"Country_Bermuda": "Bermuda",
"Country_Bhutan": "Bhutan",
"Country_Bolivia": "Bolivia",
"Country_Bosnia_and_Herzegovina": "Bosnia and Herzegovina",
"Country_Botswana": "Botswana",
"Country_Bouvet_Island": "Bouvet Island",
"Country_Brazil": "Brazil",
"Country_British_Indian_Ocean_Territory": "British Indian Ocean Territory",
"Country_Brunei_Darussalam": "Brunei Darussalam",
"Country_Bulgaria": "Bulgaria",
"Country_Burkina_Faso": "Burkina Faso",
"Country_Burundi": "Burundi",
"Country_Cambodia": "Cambodia",
"Country_Cameroon": "Cameroon",
"Country_Canada": "Canada",
"Country_Cape_Verde": "Cape Verde",
"Country_Cayman_Islands": "Cayman Islands",
"Country_Central_African_Republic": "Central African Republic",
"Country_Chad": "Chad",
"Country_Chile": "Chile",
"Country_China": "China",
"Country_Christmas_Island": "Christmas Island",
"Country_Cocos_Keeling_Islands": "Cocos (Keeling) Islands",
"Country_Colombia": "Colombia",
"Country_Comoros": "Comoros",
"Country_Congo": "Congo",
"Country_Congo_The_Democratic_Republic_of_The": "Congo, The Democratic Republic of The",
"Country_Cook_Islands": "Cook Islands",
"Country_Costa_Rica": "Costa Rica",
"Country_Cote_Divoire": "Cote D'ivoire",
"Country_Croatia": "Croatia",
"Country_Cuba": "Cuba",
"Country_Cyprus": "Cyprus",
"Country_Czech_Republic": "Czech Republic",
"Country_Denmark": "Denmark",
"Country_Djibouti": "Djibouti",
"Country_Dominica": "Dominica",
"Country_Dominican_Republic": "Dominican Republic",
"Country_Ecuador": "Ecuador",
"Country_Egypt": "Egypt",
"Country_El_Salvador": "El Salvador",
"Country_Equatorial_Guinea": "Equatorial Guinea",
"Country_Eritrea": "Eritrea",
"Country_Estonia": "Estonia",
"Country_Ethiopia": "Ethiopia",
"Country_Falkland_Islands_Malvinas": "Falkland Islands (Malvinas)",
"Country_Faroe_Islands": "Faroe Islands",
"Country_Fiji": "Fiji",
"Country_Finland": "Finland",
"Country_France": "France",
"Country_French_Guiana": "French Guiana",
"Country_French_Polynesia": "French Polynesia",
"Country_French_Southern_Territories": "French Southern Territories",
"Country_Gabon": "Gabon",
"Country_Gambia": "Gambia",
"Country_Georgia": "Georgia",
"Country_Germany": "Germany",
"Country_Ghana": "Ghana",
"Country_Gibraltar": "Gibraltar",
"Country_Greece": "Greece",
"Country_Greenland": "Greenland",
"Country_Grenada": "Grenada",
"Country_Guadeloupe": "Guadeloupe",
"Country_Guam": "Guam",
"Country_Guatemala": "Guatemala",
"Country_Guinea": "Guinea",
"Country_Guinea_bissau": "Guinea-bissau",
"Country_Guyana": "Guyana",
"Country_Haiti": "Haiti",
"Country_Heard_Island_and_Mcdonald_Islands": "Heard Island and Mcdonald Islands",
"Country_Holy_See_Vatican_City_State": "Holy See (Vatican City State)",
"Country_Honduras": "Honduras",
"Country_Hong_Kong": "Hong Kong",
"Country_Hungary": "Hungary",
"Country_Iceland": "Iceland",
"Country_India": "India",
"Country_Indonesia": "Indonesia",
"Country_Iran_Islamic_Republic_of": "Iran, Islamic Republic of",
"Country_Iraq": "Iraq",
"Country_Ireland": "Ireland",
"Country_Israel": "Israel",
"Country_Italy": "Italy",
"Country_Jamaica": "Jamaica",
"Country_Japan": "Japan",
"Country_Jordan": "Jordan",
"Country_Kazakhstan": "Kazakhstan",
"Country_Kenya": "Kenya",
"Country_Kiribati": "Kiribati",
"Country_Korea_Democratic_Peoples_Republic_of": "Korea, Democratic People's Republic of",
"Country_Korea_Republic_of": "Korea, Republic of",
"Country_Kuwait": "Kuwait",
"Country_Kyrgyzstan": "Kyrgyzstan",
"Country_Lao_Peoples_Democratic_Republic": "Lao People's Democratic Republic",
"Country_Latvia": "Latvia",
"Country_Lebanon": "Lebanon",
"Country_Lesotho": "Lesotho",
"Country_Liberia": "Liberia",
"Country_Libyan_Arab_Jamahiriya": "Libyan Arab Jamahiriya",
"Country_Liechtenstein": "Liechtenstein",
"Country_Lithuania": "Lithuania",
"Country_Luxembourg": "Luxembourg",
"Country_Macao": "Macao",
"Country_Macedonia_The_Former_Yugoslav_Republic_of": "Macedonia, The Former Yugoslav Republic of",
"Country_Madagascar": "Madagascar",
"Country_Malawi": "Malawi",
"Country_Malaysia": "Malaysia",
"Country_Maldives": "Maldives",
"Country_Mali": "Mali",
"Country_Malta": "Malta",
"Country_Marshall_Islands": "Marshall Islands",
"Country_Martinique": "Martinique",
"Country_Mauritania": "Mauritania",
"Country_Mauritius": "Mauritius",
"Country_Mayotte": "Mayotte",
"Country_Mexico": "Mexico",
"Country_Micronesia_Federated_States_of": "Micronesia, Federated States of",
"Country_Moldova_Republic_of": "Moldova, Republic of",
"Country_Monaco": "Monaco",
"Country_Mongolia": "Mongolia",
"Country_Montserrat": "Montserrat",
"Country_Morocco": "Morocco",
"Country_Mozambique": "Mozambique",
"Country_Myanmar": "Myanmar",
"Country_Namibia": "Namibia",
"Country_Nauru": "Nauru",
"Country_Nepal": "Nepal",
"Country_Netherlands": "Netherlands",
"Country_Netherlands_Antilles": "Netherlands Antilles",
"Country_New_Caledonia": "New Caledonia",
"Country_New_Zealand": "New Zealand",
"Country_Nicaragua": "Nicaragua",
"Country_Niger": "Niger",
"Country_Nigeria": "Nigeria",
"Country_Niue": "Niue",
"Country_Norfolk_Island": "Norfolk Island",
"Country_Northern_Mariana_Islands": "Northern Mariana Islands",
"Country_Norway": "Norway",
"Country_Oman": "Oman",
"Country_Pakistan": "Pakistan",
"Country_Palau": "Palau",
"Country_Palestinian_Territory_Occupied": "Palestinian Territory, Occupied",
"Country_Panama": "Panama",
"Country_Papua_New_Guinea": "Papua New Guinea",
"Country_Paraguay": "Paraguay",
"Country_Peru": "Peru",
"Country_Philippines": "Philippines",
"Country_Pitcairn": "Pitcairn",
"Country_Poland": "Poland",
"Country_Portugal": "Portugal",
"Country_Puerto_Rico": "Puerto Rico",
"Country_Qatar": "Qatar",
"Country_Reunion": "Reunion",
"Country_Romania": "Romania",
"Country_Russian_Federation": "Russian Federation",
"Country_Rwanda": "Rwanda",
"Country_Saint_Helena": "Saint Helena",
"Country_Saint_Kitts_and_Nevis": "Saint Kitts and Nevis",
"Country_Saint_Lucia": "Saint Lucia",
"Country_Saint_Pierre_and_Miquelon": "Saint Pierre and Miquelon",
"Country_Saint_Vincent_and_The_Grenadines": "Saint Vincent and The Grenadines",
"Country_Samoa": "Samoa",
"Country_San_Marino": "San Marino",
"Country_Sao_Tome_and_Principe": "Sao Tome and Principe",
"Country_Saudi_Arabia": "Saudi Arabia",
"Country_Senegal": "Senegal",
"Country_Serbia_and_Montenegro": "Serbia and Montenegro",
"Country_Seychelles": "Seychelles",
"Country_Sierra_Leone": "Sierra Leone",
"Country_Singapore": "Singapore",
"Country_Slovakia": "Slovakia",
"Country_Slovenia": "Slovenia",
"Country_Solomon_Islands": "Solomon Islands",
"Country_Somalia": "Somalia",
"Country_South_Africa": "South Africa",
"Country_South_Georgia_and_The_South_Sandwich_Islands": "South Georgia and The South Sandwich Islands",
"Country_Spain": "Spain",
"Country_Sri_Lanka": "Sri Lanka",
"Country_Sudan": "Sudan",
"Country_Suriname": "Suriname",
"Country_Svalbard_and_Jan_Mayen": "Svalbard and Jan Mayen",
"Country_Swaziland": "Swaziland",
"Country_Sweden": "Sweden",
"Country_Switzerland": "Switzerland",
"Country_Syrian_Arab_Republic": "Syrian Arab Republic",
"Country_Taiwan_Province_of_China": "Taiwan, Province of China",
"Country_Tajikistan": "Tajikistan",
"Country_Tanzania_United_Republic_of": "Tanzania, United Republic of",
"Country_Thailand": "Thailand",
"Country_Timor_leste": "Timor-leste",
"Country_Togo": "Togo",
"Country_Tokelau": "Tokelau",
"Country_Tonga": "Tonga",
"Country_Trinidad_and_Tobago": "Trinidad and Tobago",
"Country_Tunisia": "Tunisia",
"Country_Turkey": "Turkey",
"Country_Turkmenistan": "Turkmenistan",
"Country_Turks_and_Caicos_Islands": "Turks and Caicos Islands",
"Country_Tuvalu": "Tuvalu",
"Country_Uganda": "Uganda",
"Country_Ukraine": "Ukraine",
"Country_United_Arab_Emirates": "United Arab Emirates",
"Country_United_Kingdom": "United Kingdom",
"Country_United_States": "United States",
"Country_United_States_Minor_Outlying_Islands": "United States Minor Outlying Islands",
"Country_Uruguay": "Uruguay",
"Country_Uzbekistan": "Uzbekistan",
"Country_Vanuatu": "Vanuatu",
"Country_Venezuela": "Venezuela",
"Country_Viet_Nam": "Viet Nam",
"Country_Virgin_Islands_British": "Virgin Islands, British",
"Country_Virgin_Islands_US": "Virgin Islands, U.S.",
"Country_Wallis_and_Futuna": "Wallis and Futuna",
"Country_Western_Sahara": "Western Sahara",
"Country_Yemen": "Yemen",
"Country_Zambia": "Zambia",
"Country_Zimbabwe": "Zimbabwe"
}

@ -92,6 +92,10 @@ class ModelSettings extends RocketChat.models._Base {
});
}
findSetupWizardSettings() {
return this.find({ wizard: { '$exists': true, '$ne': null } });
}
// UPDATE
updateValueById(_id, value) {
const query = {

File diff suppressed because it is too large Load Diff

@ -0,0 +1,192 @@
<template name="setupWizardFinal">
<div class="setup-wizard">
<div class="setup-wizard-final">
<header class="setup-wizard-info__header setup-wizard-final__header">
<img class="setup-wizard-info__header-logo" src="images/logo/logo-black.svg">
</header>
<main class="setup-wizard-final__box">
<span class="setup-wizard-forms__header-step">{{_ "Launched_successfully"}}</span>
<h1 class="setup-wizard-info__content-title setup-wizard-final__box-title">{{_ "Your_workspace_is_ready"}}</h1>
<span class="setup-wizard-final__link-text">{{_ "Your_server_link"}}</span>
<span class="setup-wizard-final__link">{{siteUrl}}</span>
<button class="rc-button rc-button--primary js-finish">
<span>{{_ "Go_to_your_workspace"}}</span>
</button>
</main>
</div>
</div>
</template>
<template name="setupWizard">
<div class="setup-wizard">
<section class="setup-wizard-info">
<header class="setup-wizard-info__header">
<img class="setup-wizard-info__header-logo" src="images/logo/logo-black.svg">
<span class="setup-wizard-info__header-tag">{{_ "Setup_Wizard"}}</span>
</header>
<div class="setup-wizard-info__content">
<h1 class="setup-wizard-info__content-title">{{_ "Setup_Wizard"}}</h1>
<p class="setup-wizard-info__content-text">{{_ "Setup_Wizard_Info"}}</p>
<ol class="setup-wizard-info__steps">
{{#unless hasAdmin}}<li class="setup-wizard-info__steps-item {{itemModifier 1}}">{{headerTitle 1}}</li>{{/unless}}
<li class="setup-wizard-info__steps-item {{itemModifier 2}}">{{headerTitle 2}}{{#unless hasAdmin}}<span class="setup-wizard-info__steps-item-bonding"></span>{{/unless}}</li>
<li class="setup-wizard-info__steps-item {{itemModifier 3}}">{{headerTitle 3}}<span class="setup-wizard-info__steps-item-bonding"></span></li>
{{#unless hasAdmin}}<li class="setup-wizard-info__steps-item {{itemModifier 4}}">{{headerTitle 4}}<span class="setup-wizard-info__steps-item-bonding"></span></li>{{/unless}}
</ol>
</div>
</section>
<section class="setup-wizard-forms">
<div class="setup-wizard-forms__wrapper">
<div class="setup-wizard-forms__box">
<header class="setup-wizard-forms__header">
<span class="setup-wizard-forms__header-step">{{_ "Step"}} {{currentStep}}</span>
<h1 class="setup-wizard-forms__header-title">{{headerTitle}}</h1>
</header>
<main class="setup-wizard-forms__content">
<div class="setup-wizard-forms__content-step {{#if $eq currentStep 1}}setup-wizard-forms__content-step--active{{/if}}">
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Name"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon block="rc-input__icon-sv" icon="user"}}
</div>
<input type="text" class="rc-input__element js-setting-data" name="registration-name" placeholder="{{_ 'Type_your_name'}}" value="{{getValue 'registration-name'}}">
</div>
</label>
</div>
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Username"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon block="rc-input__icon-sv" icon="at"}}
</div>
<input type="text" class="rc-input__element js-setting-data" name="registration-username" placeholder="{{_ 'Type_your_username'}}" value="{{getValue 'registration-username'}}">
</div>
</label>
</div>
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Organization_Email"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon block="rc-input__icon-sv" icon="mail"}}
</div>
<input type="email" class="rc-input__element js-setting-data" name="registration-email" placeholder="{{_ 'Type_your_email'}}" value="{{getValue 'registration-email'}}">
</div>
</label>
{{#if invalidEmail}}
<div class="rc-input__error">
<div class="rc-input__error-icon">
{{> icon block="rc-input__error-icon" icon="warning" classes="rc-input__error-icon-svg"}}
</div>
<div class="rc-input__error-message">{{_ "Invalid_email"}}</div>
</div>
{{/if}}
</div>
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Password"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon block="rc-input__icon-sv" icon="key"}}
</div>
<input type="password" class="rc-input__element js-setting-data" name="registration-pass" placeholder="{{_ 'Type_your_password'}}">
</div>
</label>
</div>
</div>
<div class="setup-wizard-forms__content-step {{showStep}}">
{{#each getSettings currentStep}}
{{#if $eq type 'select'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-select">
<select class="rc-select__element js-setting-data" name="{{_id}}">
{{#each values}}
<option class="rc-select__option" value="{{key}}" selected="{{selectedValue ../_id key}}">{{_ i18nLabel}}</option>
{{/each}}
</select>
{{> icon block="rc-select__arrow" icon="arrow-down" }}
</div>
</label>
</div>
{{/if}}
{{#if $eq type 'string'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-input__wrapper">
<input type="text" class="rc-input__element js-setting-data" name="{{_id}}" value="{{getValue _id}}">
</div>
</label>
</div>
{{/if}}
{{#if $eq type 'language'}}
<div class="rc-input">
<label class="rc-input__label">
<div class="rc-input__title">{{_ i18nLabel}}</div>
<div class="rc-select">
<select class="rc-select__element js-setting-data" name="{{_id}}">
{{#each languages}}
<option class="rc-select__option" value="{{key}}" selected="{{selectedValue ../_id key}}" dir="auto">{{name}}</option>
{{/each}}
</select>
{{> icon block="rc-select__arrow" icon="arrow-down" }}
</div>
</label>
</div>
{{/if}}
{{/each}}
</div>
<div class="setup-wizard-forms__content-step {{#if $eq currentStep 4}}setup-wizard-forms__content-step--active{{/if}}">
<p class="setup-wizard-forms__content-text">To receive free Rocket.Chat supplied features you need to register your server.</p>
<form class="setup-wizard-forms__content-register">
<label class="setup-wizard-forms__content-register-option">
<div class="setup-wizard-forms__content-register-radio">
<input type="radio" name="registerServer" value="true" class="setup-wizard-forms__content-register-radio-element js-setting-data" checked>
<span class="setup-wizard-forms__content-register-radio-fake"></span>
<span class="setup-wizard-forms__content-register-radio-text">Registered Server</span>
</div>
<ul>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="check"}}Mobile push notifications</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="check"}}Omnichannel proxy</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="check"}}Social Network oAuth proxy</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="check"}}Apps Marketplace</li>
</ul>
</label>
<label class="setup-wizard-forms__content-register-option">
<div class="setup-wizard-forms__content-register-radio">
<input type="radio" name="registerServer" value="false" class="setup-wizard-forms__content-register-radio-element js-setting-data">
<span class="setup-wizard-forms__content-register-radio-fake"></span>
<span class="setup-wizard-forms__content-register-radio-text">Standalone Server</span>
</div>
<ul>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="cross"}}Mobile push notifications</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="cross"}}Omnichannel proxy</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="cross"}}Social Network oAuth proxy</li>
<li class="setup-wizard-forms__content-register-item">{{> icon block="setup-wizard-forms__content-register-radio-icon" icon="cross"}}Apps Marketplace</li>
</ul>
</label>
</form>
</div>
</main>
<footer class="setup-wizard-forms__footer">
{{#if showBackButton}}
<button class="rc-button rc-button--secondary setup-wizard-forms__footer-back">
<span>{{_ "Back"}}</span>
</button>
{{/if}}
<button class="rc-button rc-button--primary setup-wizard-forms__footer-next" {{isDisabled}}>
<span>{{_ "Continue"}}</span>
</button>
</footer>
</div>
</div>
</section>
</div>
</template>

@ -0,0 +1,272 @@
import s from 'underscore.string';
const setSettingsAndGo = (settings, registerServer = true) => {
const settingsFilter = Object.entries(settings)
.filter(([key]) => !/registration-|registerServer|currentStep/.test(key))
.map(([_id, value]) => ({_id, value}));
settingsFilter.push({
_id: 'Statistics_reporting',
value: registerServer
});
RocketChat.settings.batchSet(settingsFilter, function(err) {
if (err) {
return handleError(err);
}
localStorage.setItem('wizardFinal', true);
FlowRouter.go('setup-wizard-final');
});
};
Template.setupWizard.onCreated(function() {
if (localStorage.getItem('wizardFinal')) {
FlowRouter.go('setup-wizard-final');
}
this.hasAdmin = new ReactiveVar(false);
this.state = new ReactiveDict();
this.wizardSettings = new ReactiveVar([]);
this.invalidEmail = new ReactiveVar(false);
const storage = JSON.parse(localStorage.getItem('wizard'));
if (storage) {
Object.entries(storage).forEach(([key, value]) => {
this.state.set(key, value);
});
}
Tracker.autorun(() => {
const user = Meteor.user();
if (user) {
if (!this.hasAdmin.get()) {
if (user.roles && user.roles.includes('admin')) {
this.state.set('currentStep', 2);
this.hasAdmin.set(true);
} else {
this.hasAdmin.set(false);
}
}
Meteor.call('getWizardSettings', (error, result) => {
if (error) {
return handleError(error);
}
this.wizardSettings.set(result);
});
} else {
this.state.set('currentStep', 1);
}
if (RocketChat.settings.get('Show_Setup_Wizard') === false) {
FlowRouter.go('home');
}
const states = this.state.all();
states['registration-pass'] = '';
localStorage.setItem('wizard', JSON.stringify(states));
});
});
Template.setupWizard.onRendered(function() {
$('#initial-page-loading').remove();
});
Template.setupWizard.events({
'click .setup-wizard-forms__footer-next'(e, t) {
const currentStep = t.state.get('currentStep');
const hasAdmin = t.hasAdmin.get();
if (!hasAdmin && currentStep === 1) {
const emailValue = t.state.get('registration-email');
const invalidEmail = !/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+\b/i.test(emailValue);
t.invalidEmail.set(invalidEmail);
if (invalidEmail) {
return false;
}
const state = t.state.all();
const registration = Object.entries(state).filter(([key]) => /registration-/.test(key));
const registrationData = Object.assign(...registration.map(d => ({[d[0].replace('registration-', '')]: d[1]})));
Meteor.call('registerUser', registrationData, error => {
if (error) {
return handleError(error);
}
RocketChat.callbacks.run('userRegistered');
Meteor.loginWithPassword(s.trim(registrationData.email), registrationData.pass, error => {
if (error && error.error === 'error-invalid-email') {
toastr.success(t('We_have_sent_registration_email'));
return false;
}
Session.set('forceLogin', false);
Meteor.call('setUsername', registrationData.username, error => {
if (error) {
return handleError(error);
}
RocketChat.callbacks.run('usernameSet');
});
});
});
}
if (hasAdmin && currentStep === 3) {
setSettingsAndGo(t.state.all());
return false;
}
if (currentStep === 4) {
setSettingsAndGo(t.state.all(), JSON.parse(t.state.get('registerServer') || true));
return false;
}
t.state.set('currentStep', currentStep + 1);
},
'click .setup-wizard-forms__footer-back'(e, t) {
t.state.set('currentStep', t.state.get('currentStep') - 1);
},
'input .js-setting-data'(e, t) {
t.state.set(e.currentTarget.name, e.currentTarget.value);
}
});
Template.setupWizard.helpers({
currentStep() {
return Template.instance().state.get('currentStep');
},
itemModifier(step) {
const current = Template.instance().state.get('currentStep');
if (current === step) {
return 'setup-wizard-info__steps-item--active';
}
if (current > step) {
return 'setup-wizard-info__steps-item--past';
}
return '';
},
getValue(name) {
return Template.instance().state.get(name);
},
selectedValue(setting, optionValue) {
return Template.instance().state.get(setting) === optionValue;
},
isDisabled() {
const user = Meteor.user();
if (user && user.roles && !user.roles.includes('admin')) {
return 'disabled';
}
if (Template.instance().state.get('currentStep') === 1) {
const state = Template.instance().state.all();
if (Object.entries(state).filter(([key, value]) => /registration-/.test(key) && !value).length) {
return 'disabled';
}
}
return '';
},
headerTitle(step) {
if (!step) {
step = Template.instance().state.get('currentStep');
}
switch (step) {
case 1: return t('Admin_Info');
case 2: return t('Organization_Info');
case 3: return t('Server_Info');
case 4: return t('Register_Server');
}
},
showStep() {
const currentStep = Template.instance().state.get('currentStep');
if (currentStep === 2 || currentStep === 3) {
return 'setup-wizard-forms__content-step--active';
}
return '';
},
getSettings(step) {
return Template.instance().wizardSettings.get()
.filter(setting => setting.wizard.step === step)
.sort((a, b) => a.wizard.order - b.wizard.order);
},
languages() {
const languages = TAPi18n.getLanguages();
const result = Object.entries(languages).map(language => {
const obj = language[1];
obj.key = language[0];
return obj;
}).sort((a, b) => a.key - b.key);
result.unshift({
'name': 'Default',
'en': 'Default',
'key': ''
});
return result;
},
hasAdmin() {
return Template.instance().hasAdmin.get();
},
invalidEmail() {
return Template.instance().invalidEmail.get();
},
showBackButton() {
if (Template.instance().hasAdmin.get()) {
if (Template.instance().state.get('currentStep') > 2) {
return true;
}
return false;
}
if (Template.instance().state.get('currentStep') > 1) {
return true;
}
return false;
}
});
Template.setupWizardFinal.onCreated(function() {
Tracker.autorun(() => {
if (RocketChat.settings.get('Show_Setup_Wizard') === false) {
FlowRouter.go('home');
}
});
});
Template.setupWizardFinal.onRendered(function() {
$('#initial-page-loading').remove();
});
Template.setupWizardFinal.events({
'click .js-finish'() {
RocketChat.settings.set('Show_Setup_Wizard', false, function() {
localStorage.removeItem('wizard');
localStorage.removeItem('wizardFinal');
FlowRouter.go('home');
});
}
});
Template.setupWizardFinal.helpers({
siteUrl() {
return RocketChat.settings.get('Site_Url');
}
});

@ -0,0 +1,17 @@
Package.describe({
name: 'rocketchat:setup-wizard',
version: '0.0.1',
summary: '',
git: ''
});
Package.onUse(function(api) {
api.use('ecmascript');
api.use('templating', 'client');
api.use('rocketchat:theme');
api.addFiles('client/setupWizard.html', 'client');
api.addFiles('client/setupWizard.js', 'client');
api.addFiles('server/lib/getWizardSettings.js', 'server');
});

@ -0,0 +1,9 @@
Meteor.methods({
getWizardSettings() {
if (RocketChat.authz.hasRole(Meteor.userId(), 'admin') && RocketChat.models && RocketChat.models.Settings) {
return RocketChat.models.Settings.findSetupWizardSettings().fetch();
}
throw new Meteor.Error('settings-are-not-ready', 'Settings are not ready');
}
});

@ -5,6 +5,44 @@ import os from 'os';
RocketChat.statistics.get = function _getStatistics() {
const statistics = {};
// Setup Wizard
statistics.wizard = {};
if (RocketChat.models.Settings.findOne('Organization_Type')) {
statistics.wizard.organizationType = RocketChat.models.Settings.findOne('Organization_Type').value;
}
if (RocketChat.models.Settings.findOne('Organization_Name')) {
statistics.wizard.organizationName = RocketChat.models.Settings.findOne('Organization_Name').value;
}
if (RocketChat.models.Settings.findOne('Industry')) {
statistics.wizard.industry = RocketChat.models.Settings.findOne('Industry').value;
}
if (RocketChat.models.Settings.findOne('Size')) {
statistics.wizard.size = RocketChat.models.Settings.findOne('Size').value;
}
if (RocketChat.models.Settings.findOne('Country')) {
statistics.wizard.country = RocketChat.models.Settings.findOne('Country').value;
}
if (RocketChat.models.Settings.findOne('Website')) {
statistics.wizard.website = RocketChat.models.Settings.findOne('Website').value;
}
if (RocketChat.models.Settings.findOne('Site_Name')) {
statistics.wizard.siteName = RocketChat.models.Settings.findOne('Site_Name').value;
}
if (RocketChat.models.Settings.findOne('Language')) {
statistics.wizard.siteName = RocketChat.models.Settings.findOne('Site_Name').value;
}
if (RocketChat.models.Settings.findOne('Server_Type')) {
statistics.wizard.serverType = RocketChat.models.Settings.findOne('Server_Type').value;
}
// Version
statistics.uniqueId = RocketChat.settings.get('uniqueID');
if (RocketChat.models.Settings.findOne('uniqueID')) {

@ -0,0 +1,465 @@
.setup-wizard {
display: flex;
width: 100%;
height: 100%;
background-color: #f7f8fa;
justify-content: center;
&-info {
flex: 0 0 350px;
margin: 55px 65px 0 80px;
&__header{
display: flex;
margin: 0 -0.375rem 3rem;
align-items: center;
&-logo {
margin: 0 0.375rem;
}
&-tag {
margin: 0 0.375rem;
padding: 4px 8px;
letter-spacing: 0.05rem;
text-transform: uppercase;
color: #ffffff;
border-radius: 50px;
background: #2f343d;
font-size: 10px;
line-height: 1rem;
}
}
&__content {
&-title {
margin-bottom: 1rem;
letter-spacing: 0.03rem;
color: #2f343d;
font-size: 2rem;
font-weight: 600;
line-height: 2.6rem;
}
&-text {
margin-bottom: 3rem;
color: #9ea2a8;
font-size: 1rem;
font-weight: 500;
line-height: 1.5rem;
}
}
&__steps {
counter-reset: steps;
&-item {
position: relative;
margin: 0 -0.5rem;
counter-increment: steps;
color: #d3d5d9;
font-size: 0.875rem;
font-weight: 500;
&:not(:last-child) {
margin-bottom: 2rem;
&::after {
position: absolute;
bottom: -1rem;
left: 1.2rem;
display: block;
width: 1px;
height: 1rem;
content: "";
background-color: #d3d5d9;
}
}
&::before {
display: inline-flex;
width: 1.5rem;
height: 1.5rem;
margin: 0 0.5rem;
content: counter(steps);
color: #d3d5d9;
border: 1px solid #d3d5d9;
border-radius: 50px;
font-size: 0.75rem;
align-items: center;
justify-content: center;
}
&--active {
color: #1d74f5;
&::before {
color: #1d74f5;
border-color: #1d74f5;
}
}
&--past {
color: #2f343d;
&::before {
color: #ffffff;
background-color: #1d74f5;
}
&::after {
background-color: #1d74f5 !important;
}
& .setup-wizard-info__steps-item-bonding {
background-color: #1d74f5;
}
}
&-bonding {
position: absolute;
top: -1rem;
left: 1.2rem;
display: block;
width: 1px;
height: 1rem;
background-color: currentColor;
}
}
}
}
&-forms {
flex: 1 1 auto;
&__wrapper {
display: flex;
overflow-y: auto;
width: calc(100% - 1rem);
height: calc(100% - 2rem);
margin: 1rem 1rem 1rem 0;
padding: 3rem;
border-radius: 2px;
background: #ffffff;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08);
justify-content: center;
}
&__box {
display: flex;
flex-direction: column;
width: 350px;
}
&__header {
margin-bottom: 2rem;
&-step {
display: block;
margin-bottom: 3px;
letter-spacing: 0.05rem;
text-transform: uppercase;
color: #caced1;
font-size: 0.75rem;
line-height: 1.125rem;
}
&-title {
letter-spacing: 0.05rem;
color: #1f2329;
font-size: 1.25rem;
font-weight: 500;
line-height: 1.75rem;
}
}
&__content {
margin-bottom: 2rem;
&-step {
display: none;
&--active {
display: block;
}
}
&-text {
margin-bottom: 2rem;
color: #9ea2a8;
font-size: 1rem;
font-weight: 500;
line-height: 1.5rem;
}
&-register {
display: flex;
flex-direction: column;
&-option {
display: block;
padding: 1.5rem;
cursor: pointer;
color: #2f343d;
border: 1px solid #e7ebf2;
border-radius: 2px;
font-size: 0.875rem;
line-height: 1.25rem;
&:first-child {
margin-bottom: 1rem;
}
}
&-radio {
position: relative;
display: flex;
margin: 0 -0.5rem 1rem;
&-element {
position: absolute;
z-index: -1;
top: 0;
left: 0;
width: 0;
height: 0;
&:checked + .setup-wizard-forms__content-register-radio-fake {
position: relative;
border-color: #1d74f5;
&::before {
position: absolute;
top: 3px;
left: 3px;
width: 12px;
height: 12px;
content: "";
border-radius: 50%;
background-color: #1d74f5;
}
}
}
&-fake {
display: block;
width: 20px;
height: 20px;
margin: 0 0.5rem;
border: 1px solid #cfd8e6;
border-radius: 50px;
}
&-text {
font-weight: 500;
}
}
&-item {
display: flex;
margin: 0 -0.5rem 0.5rem;
align-items: center;
&:last-child {
margin-bottom: 0;
}
& .setup-wizard-forms__content-register-radio-icon {
margin: 0 calc(4px + 0.5rem);
font-size: 10px;
}
& .setup-wizard-forms__content-register-radio-icon--check {
color: #1d74f5;
}
}
}
}
&__footer {
display: flex;
margin: 0 -0.5rem;
& .rc-button {
margin: 0 0.5rem;
}
}
}
&-final {
width: 930px;
padding-top: 5rem;
&__header {
margin-bottom: 5rem;
}
&__box {
padding: 5rem 6rem;
border-radius: 2px;
background: #ffffff;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08);
&-title {
margin-bottom: 3.25rem;
}
}
&__link {
display: block;
margin-bottom: 1.5rem;
letter-spacing: 0;
color: #1d74f5;
font-size: 1rem;
line-height: 1.5rem;
&-text {
display:block;
letter-spacing: 0.03rem;
text-transform:uppercase;
color: #2f343d;
font-size: 0.625rem;
line-height: 1rem;
}
}
}
& .rc-input {
&:not(:last-child) {
margin-bottom: 1.5rem;
}
&__title {
letter-spacing: 0.03rem;
text-transform: uppercase;
color: #9ea2a8;
font-size: 0.625rem;
line-height: 1rem;
}
&__element {
color: #030c1a;
font-weight: 500;
}
}
& .rc-select {
&__element {
color: #030c1a;
font-size: 0.875rem;
font-weight: 500;
}
}
}
.rtl {
& .setup-wizard-info {
margin: 55px 80px 0 65px;
}
& .setup-wizard-forms__wrapper {
margin: 1rem 0 1rem 1rem;
}
& .setup-wizard-info__steps-item {
&:not(:last-child)::after,
&-bonding {
right: 1.2rem;
left: auto;
}
}
}

@ -187,6 +187,10 @@
display: none;
}
&__description {
font-size: 0.875rem;
color: var(--color-gray);
}
}
select.rc-input {

@ -25,28 +25,28 @@
&__arrow {
position: absolute;
z-index: -1;
margin: 0 -5px;
pointer-events: none;
color: var(--color-gray-light);
font-size: 20px;
}
&__element {
width: 100%;
padding: 0.75rem 2rem 0.75rem 1rem;
text-transform: capitalize;
border: none;
appearance: none;
width: 100%;
line-height: 1rem !important;
appearance: none;
&::-ms-expand {
display: none;
}

@ -25,6 +25,7 @@
@import 'imports/components/sidebar/rooms-list.css';
/* Main */
@import 'imports/components/setup-wizard.css';
@import 'imports/components/flex-nav.css';
@import 'imports/components/header.css';
@import 'imports/components/memberlist.css';

@ -84,17 +84,18 @@ Template.admin.helpers({
languages() {
const languages = TAPi18n.getLanguages();
let result = Object.keys(languages).map(key => {
const language = languages[key];
return _.extend(language, { key });
});
const result = Object.entries(languages).map(language => {
const obj = language[1];
obj.key = language[0];
return obj;
}).sort((a, b) => a.key - b.key);
result = _.sortBy(result, 'key');
result.unshift({
'name': 'Default',
'en': 'Default',
'key': ''
});
return result;
},
appLanguage(key) {

@ -24,43 +24,45 @@
<template name="main">
{{#if subsReady}}
{{#unless logged}}
<div class="rc-old connection-status">
{{> status}}
</div>
{{#if useIframe}}
{{#if iframeUrl}}
<iframe src="{{iframeUrl}}" style="height: 100%; width: 100%;"></iframe>
{{#unless showSetupWizard}}
{{#unless logged}}
<div class="rc-old connection-status">
{{> status}}
</div>
{{#if useIframe}}
{{#if iframeUrl}}
<iframe src="{{iframeUrl}}" style="height: 100%; width: 100%;"></iframe>
{{/if}}
{{else}}
{{> loginLayout center="loginForm"}}
{{/if}}
{{ CustomScriptLoggedOut }}
{{else}}
{{> loginLayout center="loginForm"}}
{{/if}}
{{ CustomScriptLoggedOut }}
{{else}}
{{#unless hasUsername}}
{{> username}}
{{else}}
{{#if requirePasswordChange}}
{{> loginLayout center="resetPassword"}}
{{#unless hasUsername}}
{{> username}}
{{else}}
{{> videoCall overlay=true}}
<div id="user-card-popover"></div>
<div id="rocket-chat" class="{{embeddedVersion}} menu-nav">
{{#unless modal}}
{{> sideNav }}
{{/unless}}
<div class="rc-old main-content content-background-color {{readReceiptsEnabled}} {{#if modal}}main-modal{{/if}}">
{{> Template.dynamic template=center}}
{{#if requirePasswordChange}}
{{> loginLayout center="resetPassword"}}
{{else}}
{{> videoCall overlay=true}}
<div id="user-card-popover"></div>
<div id="rocket-chat" class="{{embeddedVersion}} menu-nav">
{{#unless modal}}
{{> sideNav }}
{{/unless}}
<div class="rc-old main-content content-background-color {{readReceiptsEnabled}} {{#if modal}}main-modal{{/if}}">
{{> Template.dynamic template=center}}
</div>
</div>
</div>
<div class="rc-old connection-status">
{{> status}}
</div>
{{> audioNotification }}
{{/if}}
<div class="rc-old connection-status">
{{> status}}
</div>
{{> audioNotification }}
{{/if}}
{{/unless}}
{{ CustomScriptLoggedIn }}
{{> photoswipe}}
{{/unless}}
{{ CustomScriptLoggedIn }}
{{> photoswipe}}
{{/unless}}
{{else}}
{{> loading}}

@ -170,6 +170,13 @@ Template.main.helpers({
if (RocketChat.Layout.isEmbedded()) {
return 'embedded-view';
}
},
showSetupWizard() {
if (RocketChat.settings.get('Show_Setup_Wizard') === false) {
return false;
}
return true;
}
});
@ -191,6 +198,11 @@ Template.main.onRendered(function() {
});
return Tracker.autorun(function() {
const user = Meteor.user();
if (RocketChat.settings.get('Show_Setup_Wizard')) {
FlowRouter.go('setup-wizard');
}
if (RocketChat.getUserPreference(user, 'hideUsernames')) {
$(document.body).on('mouseleave', 'button.thumb', function() {
return RocketChat.tooltip.hide();

@ -0,0 +1 @@
<svg width="123" height="24" viewBox="0 0 123 24" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><g fill="#1F2329"><path d="M40.353 10.944c0 1.2-.447 1.987-1.306 2.363l1.235 4.689c.053.215-.054.322-.25.322H38.17c-.178 0-.268-.09-.304-.25l-1.198-4.546h-1.235v4.51c0 .18-.107.286-.286.286h-1.86c-.18 0-.287-.107-.287-.286V4.286c0-.179.107-.286.286-.286h4.49c1.682 0 2.577.895 2.577 2.577v4.367zm-3.149.215c.465 0 .716-.25.716-.716V7.078c0-.465-.25-.715-.716-.715h-1.77v4.796h1.77zM42 6.577C42 4.895 42.894 4 44.576 4h2.004c1.682 0 2.576.895 2.576 2.577v9.164c0 1.682-.894 2.577-2.576 2.577h-2.004c-1.682 0-2.576-.895-2.576-2.577V6.577zm4.133 9.432c.465 0 .715-.233.715-.716V7.025c0-.465-.25-.716-.715-.716h-1.038c-.465 0-.715.25-.715.716v8.268c0 .483.25.716.715.716h1.038zM58.174 8.51c0 .18-.107.286-.286.286H56.1c-.197 0-.286-.107-.286-.286V7.078c0-.465-.25-.715-.715-.715h-.93c-.484 0-.716.25-.716.715v8.162c0 .483.25.715.715.715h.93c.466 0 .716-.232.716-.715v-1.432c0-.18.09-.286.286-.286h1.79c.178 0 .285.107.285.286v1.933c0 1.682-.913 2.577-2.576 2.577h-2.004c-1.681 0-2.594-.895-2.594-2.577V6.577C51 4.895 51.913 4 53.594 4h2.004c1.664 0 2.576.895 2.576 2.577V8.51zM65.761 18.318c-.215 0-.34-.09-.412-.268l-2.254-5.316-.662 1.27v3.956c0 .233-.125.358-.357.358h-1.718c-.233 0-.358-.125-.358-.358V4.358c0-.232.125-.358.358-.358h1.718c.232 0 .357.125.357.358v5.548l2.755-5.638c.09-.178.215-.268.412-.268h1.878c.269 0 .376.18.25.43l-3.04 6.246 3.237 7.23c.126.233.018.412-.268.412h-1.896zM76.139 6.076c0 .18-.072.304-.287.304H71.38v3.58h3.417c.18 0 .286.107.286.304v1.772c0 .197-.107.304-.286.304H71.38v3.615h4.472c.215 0 .287.09.287.287v1.79c0 .179-.072.285-.287.285H69.27c-.162 0-.269-.107-.269-.285V4.286c0-.179.107-.286.269-.286h6.583c.215 0 .287.107.287.286v1.79zM84.87 4c.196 0 .286.107.286.286v1.79c0 .18-.09.287-.287.287h-2.075v11.669c0 .196-.09.285-.286.285h-1.86c-.18 0-.287-.089-.287-.285V6.362h-2.075c-.18 0-.286-.107-.286-.286v-1.79c0-.179.107-.286.286-.286h6.583zM85 16.358c0-.233.125-.358.358-.358h1.628c.233 0 .358.125.358.358v1.646c0 .233-.125.358-.358.358h-1.628c-.233 0-.358-.125-.358-.358v-1.646zM96.174 8.51c0 .18-.107.286-.286.286H94.1c-.197 0-.286-.107-.286-.286V7.078c0-.465-.25-.715-.715-.715h-.93c-.484 0-.716.25-.716.715v8.162c0 .483.25.715.715.715h.93c.466 0 .716-.232.716-.715v-1.432c0-.18.09-.286.286-.286h1.79c.178 0 .285.107.285.286v1.933c0 1.682-.912 2.577-2.576 2.577h-2.004c-1.681 0-2.594-.895-2.594-2.577V6.577C89 4.895 89.913 4 91.594 4h2.004c1.664 0 2.576.895 2.576 2.577V8.51zM102.723 4.286c0-.179.107-.286.286-.286h1.843c.214 0 .303.107.303.286v13.746c0 .179-.089.285-.303.285h-1.843c-.18 0-.286-.107-.286-.285V12.34h-2.29v5.692c0 .18-.108.286-.286.286h-1.843c-.215 0-.304-.107-.304-.286V4.286c0-.179.09-.286.304-.286h1.843c.18 0 .286.107.286.286v5.692h2.29V4.286zM112.903 18.318c-.161 0-.25-.09-.287-.25l-.5-2.613h-3.185l-.483 2.612c-.036.162-.125.251-.286.251h-1.914c-.197 0-.286-.107-.233-.304l2.97-13.763c.036-.18.143-.251.304-.251h2.487c.161 0 .269.072.304.25l2.97 13.764c.036.197-.036.304-.25.304h-1.897zm-2.38-11.186l-1.145 6.246h2.29l-1.145-6.246zM121.869 4c.196 0 .286.107.286.286v1.79c0 .18-.09.287-.286.287h-2.075v11.669c0 .196-.09.285-.286.285h-1.861c-.179 0-.286-.089-.286-.285V6.362h-2.075c-.18 0-.286-.107-.286-.286v-1.79c0-.179.107-.286.286-.286h6.583z"/></g><path d="M28 11.98c0-1.416-.42-2.773-1.25-4.036-.746-1.133-1.79-2.137-3.103-2.982-2.536-1.632-5.869-2.531-9.385-2.531-1.174 0-2.332.1-3.454.298a11.433 11.433 0 0 0-2.375-1.715C3.823-1.236 0 .961 0 .961s3.554 2.942 2.976 5.52C1.386 8.07.524 9.986.524 11.98v.038c0 1.995.862 3.911 2.452 5.5C3.554 20.097 0 23.039 0 23.039s3.823 2.197 8.433-.053a11.45 11.45 0 0 0 2.375-1.715c1.123.198 2.28.298 3.454.298 3.516 0 6.85-.899 9.385-2.53 1.314-.846 2.357-1.849 3.103-2.983.83-1.262 1.25-2.62 1.25-4.037V12v-.02z" fill="#C1272D"/><path d="M14 4c6.627 0 12 3.416 12 7.629 0 4.213-5.373 7.629-12 7.629a18.23 18.23 0 0 1-4.195-.48c-1.327 1.589-4.246 3.798-7.081 3.084.922-.986 2.288-2.652 1.996-5.397-1.7-1.316-2.72-3-2.72-4.836C2 7.415 7.373 4 14 4" fill="#FFF"/><g transform="translate(7 11)" fill="#C1272D"><ellipse cx="7.615" cy="1.368" rx="1.615" ry="1.368"/><ellipse cx="12.615" cy="1.368" rx="1.615" ry="1.368"/><ellipse cx="1.614" cy="1.368" rx="1.614" ry="1.368"/></g><path d="M14.144 18.353c-1.459 0-2.855-.144-4.146-.405-1.157 1.184-3.542 2.775-6.014 2.717-.325.484-.68.88-.984 1.2 2.802.696 5.687-1.455 6.998-3.002a18.26 18.26 0 0 0 4.146.467C20.64 19.33 25.916 16.057 26 12c-.084 3.516-5.36 6.353-11.856 6.353z" fill="#CCC"/></g></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,15 @@
RocketChat.Migrations.add({
version: 117,
up() {
if (RocketChat &&
RocketChat.authz &&
RocketChat.authz.getUsersInRole('admin').count() &&
RocketChat.models &&
RocketChat.models.Settings) {
RocketChat.models.Settings.upsert(
{ _id: 'Show_Setup_Wizard' },
{ $set: { value: false }}
);
}
}
});

@ -1,6 +1,84 @@
/* eslint-env mocha */
import loginPage from '../../pageobjects/login.page';
import setupWizard from '../../pageobjects/setup-wizard.page';
describe('[Setup Wizard]', () => {
before(()=>{
setupWizard.open();
setupWizard.organizationType.waitForVisible(15000);
});
describe('[Render - Step 1]', () => {
it('it should show organization type', () => {
setupWizard.organizationType.isVisible().should.be.true;
});
it('it should show organization name', () => {
setupWizard.organizationName.isVisible().should.be.true;
});
it('it should show industry', () => {
setupWizard.industry.isVisible().should.be.true;
});
it('it should show size', () => {
setupWizard.size.isVisible().should.be.true;
});
it('it should show country', () => {
setupWizard.country.isVisible().should.be.true;
});
it('it should show website', () => {
setupWizard.website.isVisible().should.be.true;
});
after(() => {
setupWizard.goNext();
});
});
describe('[Render - Step 2]', () => {
it('it should show site name', () => {
setupWizard.siteName.isVisible().should.be.true;
});
it('it should show language', () => {
setupWizard.language.isVisible().should.be.true;
});
it('it should server type', () => {
setupWizard.serverType.isVisible().should.be.true;
});
after(() => {
setupWizard.goNext();
});
});
describe('[Render - Final Step]', () => {
it('it should render "Go to your workspace button', () => {
setupWizard.goToWorkspace.waitForVisible(15000);
setupWizard.goToWorkspace.isVisible().should.be.true;
});
after(() => {
setupWizard.goToHome();
});
});
after(() => {
browser.execute(function() {
const user = Meteor.user();
Meteor.logout(() => {
RocketChat.callbacks.run('afterLogoutCleanUp', user);
Meteor.call('logoutCleanUp', user);
FlowRouter.go('home');
});
});
});
});
describe('[Login]', () => {
before(()=>{

@ -0,0 +1,36 @@
import Page from './Page';
import {adminEmail, adminPassword} from '../data/user';
class SetupWizard extends Page {
get nextButton() { return browser.element('.setup-wizard-forms__footer-next:enabled'); }
get goToWorkspace() { return browser.element('button.js-finish'); }
get organizationType() { return browser.element('select[name="Organization_Type"]'); }
get organizationName() { return browser.element('input[name="Organization_Name"]'); }
get industry() { return browser.element('select[name="Industry"]'); }
get size() { return browser.element('select[name="Size"]'); }
get country() { return browser.element('select[name="Country"]'); }
get website() { return browser.element('input[name="Website"]'); }
get siteName() { return browser.element('input[name="Site_Name"]'); }
get language() { return browser.element('select[name="Language"]'); }
get serverType() { return browser.element('select[name="Server_Type"]'); }
open() {
super.open('setup-wizard');
browser.execute(function(email, password) {
Meteor.loginWithPassword(email, password, () => {});
}, adminEmail, adminPassword);
}
goNext() {
this.nextButton.waitForVisible(5000);
this.nextButton.click();
}
goToHome() {
this.goToWorkspace.waitForVisible(5000);
this.goToWorkspace.click();
}
}
module.exports = new SetupWizard();
Loading…
Cancel
Save