├── tests ├── _data │ └── .gitkeep ├── _output │ └── .gitignore ├── acceptance │ ├── _bootstrap.php │ ├── AboutCest.php │ ├── HomeCest.php │ ├── LoginCest.php │ └── ContactCest.php ├── functional │ ├── _bootstrap.php │ └── LoginFormCest.php ├── unit │ ├── _bootstrap.php │ └── models │ │ ├── UserTest.php │ │ ├── LoginFormTest.php │ │ └── ContactFormTest.php ├── _bootstrap.php ├── unit.suite.yml ├── acceptance.suite.yml.example ├── functional.suite.yml ├── bin │ ├── yii.bat │ └── yii └── _support │ ├── FunctionalTester.php │ ├── UnitTester.php │ └── AcceptanceTester.php ├── vue ├── src │ ├── core │ │ ├── components │ │ │ ├── index.js │ │ │ ├── org-chart │ │ │ │ └── src │ │ │ │ │ ├── lib │ │ │ │ │ └── lodash.js │ │ │ │ │ └── index.js │ │ │ ├── pages │ │ │ │ └── NotFoundComponent.vue │ │ │ ├── PageFooter.vue │ │ │ ├── NoDataAvailable.vue │ │ │ ├── sidebar │ │ │ │ ├── MenuService.js │ │ │ │ ├── SidebarItemContent.vue │ │ │ │ └── MenuItem.js │ │ │ ├── NoData.vue │ │ │ ├── PhotoVideoInput.vue │ │ │ ├── DropdownButtons.vue │ │ │ ├── ContentSpinner.vue │ │ │ ├── LikeUnlikeButton.vue │ │ │ ├── PageHeader.vue │ │ │ ├── sided-nav-layout │ │ │ │ └── SidedNavLayout.vue │ │ │ ├── navbar │ │ │ │ └── components │ │ │ │ │ └── SidebarToggle.vue │ │ │ └── SubmitButton.vue │ │ ├── scss │ │ │ ├── bootstrap │ │ │ │ ├── index.scss │ │ │ │ └── override │ │ │ │ │ └── nav.scss │ │ │ ├── mixins │ │ │ │ ├── callouts.scss │ │ │ │ ├── tooltips.scss │ │ │ │ ├── size.scss │ │ │ │ ├── outline.scss │ │ │ │ ├── forms.scss │ │ │ │ ├── panels.scss │ │ │ │ ├── dropdowns.scss │ │ │ │ ├── vendor-prefixes.scss │ │ │ │ ├── tables.scss │ │ │ │ ├── popovers.scss │ │ │ │ ├── navbar.scss │ │ │ │ ├── buttons.scss │ │ │ │ └── switches.scss │ │ │ ├── index.scss │ │ │ ├── main.scss │ │ │ └── mixins.scss │ │ ├── filters │ │ │ ├── index.js │ │ │ ├── dateFilter.js │ │ │ └── bytesFilter.js │ │ ├── index.js │ │ └── services │ │ │ ├── event-bus.js │ │ │ ├── dateService.js │ │ │ ├── userService.js │ │ │ └── fileService.js │ ├── plugins │ │ ├── font-awesome │ │ │ └── index.js │ │ ├── ckeditor.js │ │ ├── bootstrap-vue │ │ │ └── index.js │ │ ├── vue-clipboard2 │ │ │ └── index.js │ │ ├── index.js │ │ ├── vee-validate │ │ │ ├── custom-rules.js │ │ │ └── index.js │ │ ├── notification.js │ │ ├── confirm-dialog.js │ │ ├── alert-dialog.js │ │ ├── axios │ │ │ └── index.js │ │ ├── toaster.js │ │ └── bootstrap │ │ │ └── bootstrap.scss │ ├── store │ │ ├── modules │ │ │ ├── user │ │ │ │ ├── types.d.ts │ │ │ │ ├── getters.js │ │ │ │ ├── mutation-types.js │ │ │ │ ├── state.js │ │ │ │ ├── index.js │ │ │ │ ├── mutations.js │ │ │ │ └── actions.js │ │ │ ├── employee │ │ │ │ ├── index.js │ │ │ │ ├── state.js │ │ │ │ ├── mutation-types.js │ │ │ │ └── mutations.js │ │ │ ├── setup │ │ │ │ ├── index.js │ │ │ │ ├── state.js │ │ │ │ └── mutation-types.js │ │ │ └── workspaces │ │ │ │ ├── index.js │ │ │ │ └── state.js │ │ └── setup │ │ │ └── getters.js │ ├── index.scss │ ├── modules │ │ ├── index.js │ │ ├── Workspace │ │ │ ├── workspaceModule.js │ │ │ ├── components │ │ │ │ └── comment │ │ │ │ │ ├── AddCommentModel.js │ │ │ │ │ ├── DeleteComment.vue │ │ │ │ │ ├── ChildCommentItem.vue │ │ │ │ │ ├── AddComment.vue │ │ │ │ │ └── CommentItem.vue │ │ │ ├── invite │ │ │ │ └── WorkspaceInviteModel.js │ │ │ ├── view │ │ │ │ ├── files │ │ │ │ │ └── FolderFormModel.js │ │ │ │ ├── articles │ │ │ │ │ ├── ArticleFormModel.js │ │ │ │ │ └── ArticleView.vue │ │ │ │ ├── timeline │ │ │ │ │ └── TimelineFormModel.js │ │ │ │ └── about │ │ │ │ │ └── WorkspaceAbout.vue │ │ │ └── WorkspaceFormModel.js │ │ ├── setup │ │ │ ├── Setup.vue │ │ │ ├── countries │ │ │ │ ├── CountryModel.js │ │ │ │ ├── departments │ │ │ │ │ ├── DepartmentModel.js │ │ │ │ │ └── DepartmentListGroup.vue │ │ │ │ └── CountryModal.vue │ │ │ ├── invitations │ │ │ │ └── UserInvitationFormModel.js │ │ │ ├── employees │ │ │ │ ├── RoleModel.js │ │ │ │ ├── employeesService.js │ │ │ │ ├── UserDepartmentModel.js │ │ │ │ ├── EmployeeModel.js │ │ │ │ └── EmployeeList.vue │ │ │ └── setupModule.js │ │ ├── Orgchart │ │ │ ├── Orgchart.module.js │ │ │ ├── OrgchartService.js │ │ │ ├── Orgchart.vue │ │ │ └── OrgchartBody.vue │ │ ├── Dashboard │ │ │ ├── Dashboard.module.js │ │ │ └── Dashboard.vue │ │ ├── Auth │ │ │ ├── PasswordReset │ │ │ │ ├── RequestPasswordResetModel.js │ │ │ │ └── ResetPasswordModel.js │ │ │ ├── LoginModel.js │ │ │ └── RegisterModel.js │ │ └── User │ │ │ ├── PasswordResetModel.js │ │ │ └── UserModel.js │ ├── constants.js │ ├── shared │ │ ├── AppSettings.js │ │ └── i18n.js │ ├── icons.js │ ├── main.js │ └── App.vue ├── babel.config.js ├── public │ ├── favicon.ico │ ├── assets │ │ ├── logo.png │ │ └── img │ │ │ ├── apollo11-white.png │ │ │ ├── product_logo.png │ │ │ └── avatar.svg │ └── index.html ├── .env.example ├── .gitignore └── Dockerfile ├── runtime └── .gitignore ├── web ├── assets │ └── .gitignore ├── robots.txt ├── storage │ └── .gitignore ├── favicon.ico ├── .htaccess ├── index.php └── index-test.php ├── .bowerrc ├── vagrant ├── config │ ├── .gitignore │ └── vagrant-local.example.yml ├── nginx │ ├── log │ │ └── .gitignore │ └── app.conf └── provision │ ├── always-as-root.sh │ └── once-as-vagrant.sh ├── env.php ├── config ├── params.php ├── test_db.php ├── db.php ├── test.php ├── common.php └── console.php ├── migrate ├── modules └── v1 │ ├── users │ ├── UserModule.php │ ├── resources │ │ └── UserProfileResource.php │ └── controllers │ │ └── UserController.php │ ├── workspaces │ ├── WorkspaceModule.php │ ├── controllers │ │ ├── UserLikeController.php │ │ ├── UserCommentController.php │ │ └── WorkspaceActivityController.php │ ├── resources │ │ ├── WorkspaceActivityResource.php │ │ ├── UserLikeResource.php │ │ ├── UserWorkspaceResource.php │ │ ├── UserCommentResource.php │ │ └── FolderResource.php │ ├── models │ │ └── query │ │ │ ├── WorkspaceActivityQuery.php │ │ │ ├── TimelinePostQuery.php │ │ │ ├── ArticleQuery.php │ │ │ ├── WorkspaceQuery.php │ │ │ ├── UserLikeQuery.php │ │ │ ├── UserWorkspaceQuery.php │ │ │ └── UserCommentQuery.php │ └── workspaceBehaviours │ │ └── UrlAnchorBehaviour.php │ ├── V1Module.php │ └── setup │ ├── SetupModule.php │ ├── controllers │ ├── SiteController.php │ ├── CountryController.php │ └── DepartmentController.php │ ├── models │ ├── query │ │ ├── CountryQuery.php │ │ ├── UserDepartmentQuery.php │ │ ├── DepartmentQuery.php │ │ └── InvitationQuery.php │ └── search │ │ └── DepartmentSearch.php │ └── resources │ ├── UserDepartmentResource.php │ └── CountryResource.php ├── rest ├── Controller.php ├── ActiveController.php ├── ValidationException.php ├── ControllerAuthTrait.php └── ControllerTrait.php ├── docker ├── php │ ├── www.conf │ ├── install-composer.sh │ ├── php.ini │ └── Dockerfile └── vhost.conf ├── .env.example ├── views └── site │ ├── about.php │ ├── error.php │ └── login.php ├── mail ├── reset_password.php ├── invitation_accepted.php ├── user_invitation.php └── layouts │ └── html.php ├── .editorconfig ├── .gitignore ├── yii.bat ├── migrations ├── m201220_195317_alter_body_column_on_folders_table.php ├── m200915_131155_add_expire_date_column_to_users_table.php ├── m201120_161339_add_data_column_to_user_activity_table.php ├── m201228_165822_drop_abbreviation_column_from_workspace_table.php ├── m201008_150226_add_access_token_expire_date_column_to_users_table.php ├── m201215_112037_change_workspace_activity_data_column_into_longtext.php ├── m201113_112426_delete_file_path_column_to_timeline_posts_table.php ├── m201214_175912_drop_description_column_from_workspace_activity_table.php ├── m201201_110159_add_parent_identity_column_to_workspace_activity_table.php ├── m201215_111820_drop_parent_identity_column_from_workspace_activity_table.php ├── m201005_132829_add_favourites_columns_to_users_table.php ├── m201013_125848_add_action_column_to_timeline_posts_table.php ├── m200904_114621_add_demo_users.php ├── m201109_113741_alter_table_timeline_posts_add_column_workspace_id.php ├── m201119_094300_create_user_activity_table.php └── m201127_100743_create_workspace_activity_table.php ├── helpers.php ├── autocompletion.php ├── yii ├── assets └── AppAsset.php ├── components └── AsyncComponent.php ├── base └── ConsoleController.php ├── codeception.yml ├── commands └── HelloController.php ├── docker-compose.yml ├── helpers └── ModelHelper.php ├── LICENSE.md └── create-database.php /tests/_data/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vue/src/core/components/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/acceptance/_bootstrap.php: -------------------------------------------------------------------------------- 1 | load(); -------------------------------------------------------------------------------- /vue/src/core/scss/mixins/callouts.scss: -------------------------------------------------------------------------------- 1 | @mixin callout-variant($bg, $border-color){ 2 | border-color: $border-color; 3 | background-color: $bg; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /vue/src/core/components/org-chart/src/lib/lodash.js: -------------------------------------------------------------------------------- 1 | import merge from 'lodash/merge' 2 | 3 | export const mergeOptions = (obj, src) => { 4 | return merge(obj, src) 5 | } 6 | -------------------------------------------------------------------------------- /vue/.env.example: -------------------------------------------------------------------------------- 1 | VUE_APP_API_HOST=https://api.agoraintra.net/ 2 | #VUE_APP_API_HOST=https://api.demo.agoraintra.net/ 3 | VUE_APP_TWITTER_FEED_URL=https://twitter.com/test?ref_src=test -------------------------------------------------------------------------------- /vue/src/modules/index.js: -------------------------------------------------------------------------------- 1 | import './Dashboard/Dashboard.module'; 2 | import './setup/setupModule'; 3 | import './Workspace/workspaceModule'; 4 | import './Orgchart/Orgchart.module' 5 | -------------------------------------------------------------------------------- /vue/src/plugins/bootstrap-vue/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import BootstrapVue from 'bootstrap-vue' 4 | 5 | Vue.use(BootstrapVue); 6 | 7 | export default BootstrapVue; -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 5 | 'senderEmail' => 'noreply@example.com', 6 | 'senderName' => 'Example.com mailer', 7 | ]; 8 | -------------------------------------------------------------------------------- /vue/src/core/scss/mixins/tooltips.scss: -------------------------------------------------------------------------------- 1 | /*Author : $arboshiki*/ 2 | @mixin tooltip-variant($bg, $color: #FFF){ 3 | background-color: $bg; 4 | color: $color; 5 | border-color: $bg; 6 | } -------------------------------------------------------------------------------- /vue/src/plugins/vue-clipboard2/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueClipboard from 'vue-clipboard2' 3 | 4 | VueClipboard.config.autoSetContainer = true // add this line 5 | Vue.use(VueClipboard) -------------------------------------------------------------------------------- /vue/src/store/modules/user/getters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 4 | * @param { UserState } state 5 | * @return { object } 6 | */ 7 | export function getUser(state) { 8 | return state.user; 9 | } 10 | -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 |
14 | This is the About page. You may modify the following file to customize its content: 15 |
16 | 17 |= __FILE__ ?>
18 | = $user->username ?>,
11 | 12 |
13 |
14 |
15 | password_reset_token") ?>
16 |
21 | The above error occurred while the Web server was processing your request. 22 |
23 |24 | Please contact us if you think this is a server error. Thank you. 25 |
26 | 27 |14 | $model->createdBy->email 17 | ]) 18 | ?> 19 |
20 |21 | $model->email, 24 | ]) 25 | ?> 26 |
27 |28 | 29 |
30 | -------------------------------------------------------------------------------- /migrations/m201008_150226_add_access_token_expire_date_column_to_users_table.php: -------------------------------------------------------------------------------- 1 | addColumn('{{%users}}', 'access_token_expire_date', $this->integer(11)->after('access_token')); 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function safeDown() 22 | { 23 | $this->dropColumn('{{%users}}', 'access_token_expire_date'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /migrations/m201215_112037_change_workspace_activity_data_column_into_longtext.php: -------------------------------------------------------------------------------- 1 | alterColumn('{{%workspace_activity}}', 'data', 'LONGTEXT'); 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function safeDown() 22 | { 23 | $this->alterColumn('{{%workspace_activity}}', 'data', $this->text()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vue/src/modules/Auth/LoginModel.js: -------------------------------------------------------------------------------- 1 | import BaseModel from "../../core/components/input-widget/BaseModel"; 2 | import i18n from '../../shared/i18n'; 3 | 4 | export default class LoginModel extends BaseModel { 5 | email = null; 6 | password = null; 7 | 8 | rules = { 9 | email: [ 10 | {rule: 'required'}, 11 | {rule: 'email', message: i18n.t('This must be valid email')}, 12 | ], 13 | password: 'required', 14 | }; 15 | 16 | attributeLabels = { 17 | email: i18n.t('Email'), 18 | password: i18n.t('Password') 19 | }; 20 | 21 | constructor(email = '', password = '') { 22 | super(); 23 | this.email = email; 24 | this.password = password; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vue/src/modules/Workspace/view/articles/ArticleFormModel.js: -------------------------------------------------------------------------------- 1 | import BaseModel from "@/core/components/input-widget/BaseModel"; 2 | import i18n from "../../../../shared/i18n"; 3 | 4 | export default class ArticleFormModel extends BaseModel { 5 | id = null; 6 | title = ''; 7 | workspace_id = null; 8 | body = ''; 9 | 10 | rules = { 11 | title: 'required', 12 | body: '', 13 | }; 14 | 15 | attributeLabels = { 16 | title: i18n.t('Title'), 17 | body: i18n.t('Body'), 18 | }; 19 | 20 | constructor(data = {}) { 21 | super(); 22 | data.created_at = data.created_at / 1000; 23 | data.updated_at = data.updated_at / 1000; 24 | Object.assign(this, {...data}); 25 | } 26 | } -------------------------------------------------------------------------------- /vue/src/modules/setup/employees/RoleModel.js: -------------------------------------------------------------------------------- 1 | import BaseModel from "../../../core/components/input-widget/BaseModel"; 2 | import i18n from "../../../shared/i18n"; 3 | 4 | export default class RoleModel extends BaseModel { 5 | id = null; 6 | role = ''; 7 | workspace_id = null; 8 | 9 | rules = { 10 | id: [ 11 | {rule: 'required'} 12 | ], 13 | role: [ 14 | {rule: 'required'} 15 | ], 16 | workspace_id: [ 17 | {rule: 'required'} 18 | ] 19 | } 20 | 21 | attributeLabels = { 22 | role: i18n.t('Role'), 23 | workspace_id: i18n.t('Workspace'), 24 | }; 25 | 26 | constructor(data) { 27 | super(); 28 | Object.assign(this, {...data}) 29 | } 30 | } -------------------------------------------------------------------------------- /migrations/m201113_112426_delete_file_path_column_to_timeline_posts_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('{{%timeline_posts}}', 'file_path'); 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function safeDown() 22 | { 23 | $this->addColumn('{{%timeline_posts}}', 'file_path', $this->string(1024)->after('description')); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /migrations/m201214_175912_drop_description_column_from_workspace_activity_table.php: -------------------------------------------------------------------------------- 1 | dropColumn('{{%workspace_activity}}', 'description'); 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function safeDown() 22 | { 23 | $this->addColumn('{{%workspace_activity}}', 'description', 'LONGTEXT AFTER `action`'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vue/src/core/filters/bytesFilter.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | Vue.filter('prettyBytes', function (num) { 4 | if (typeof num !== 'number' || isNaN(num)) { 5 | return '-'; 6 | } 7 | 8 | let exponent; 9 | let unit; 10 | let neg = num < 0; 11 | let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; 12 | 13 | if (neg) { 14 | num = -num; 15 | } 16 | 17 | if (num < 1) { 18 | return (neg ? '-' : '') + num + ' B'; 19 | } 20 | 21 | exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1); 22 | num = (num / Math.pow(1000, exponent)).toFixed(1) * 1; 23 | unit = units[exponent]; 24 | 25 | return (neg ? '-' : '') + num + ' ' + unit; 26 | }); -------------------------------------------------------------------------------- /yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 24 | exit($exitCode); 25 | -------------------------------------------------------------------------------- /migrations/m201201_110159_add_parent_identity_column_to_workspace_activity_table.php: -------------------------------------------------------------------------------- 1 | addColumn('{{%workspace_activity}}', 'parent_identity', $this->text()->after('data')); 16 | } 17 | 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function safeDown() 22 | { 23 | $this->dropColumn('{{%workspace_activity}}', 'parent_identity'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vue/src/store/modules/user/mutations.js: -------------------------------------------------------------------------------- 1 | import {SET_USER, SET_PROFILE_LOADING, SET_PASSWORD_FORM_LOADING} from './mutation-types'; 2 | 3 | export default { 4 | /** 5 | * 6 | * @param { UserState } state 7 | * @param { array } userProfile 8 | */ 9 | [SET_USER](state, userProfile) { 10 | state.currentUser.data = userProfile; 11 | state.currentUser.loaded = true; 12 | }, 13 | 14 | /** 15 | * 16 | * @param { UserState } state 17 | * @param { boolean } loading 18 | */ 19 | [SET_PROFILE_LOADING](state, loading) { 20 | state.currentUser.loading = loading; 21 | }, 22 | [SET_PASSWORD_FORM_LOADING](state, loading) { 23 | state.passwordForm.loading = loading; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /rest/ValidationException.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |$model->email]) ?>
11 |12 | Yii::$app->name, 14 | 'inviterName' => $model->createdBy->getDisplayName() 15 | ]) ?> 16 |
17 |
18 |
19 |
20 | token") ?>
21 |
11 | 12 | {{ comment.updated_at | relativeDate }} 13 |
14 |Please fill out the following fields to login:
17 | 18 | 'login-form', 20 | 'layout' => 'horizontal', 21 | 'fieldConfig' => [ 22 | 'template' => "{label}\napp\models\User::$users.
46 | 17 | 18 | {{ comment.updated_at | relativeDate }} 19 |
20 |