├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── doc_improvement.md
│ └── enhancement.md
├── codeql
│ └── codeql-config.yml
└── workflows
│ ├── ci.yml
│ ├── codeql-analysis.yml
│ ├── dev-release.yml
│ ├── lint-server.yml
│ ├── prod-release.yml
│ └── scorecards-analysis.yml
├── .gitignore
├── .gitlab-ci.yml
├── .gitpod.yml
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile.build
├── LICENSE.txt
├── Makefile
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── app-config.json
├── config.json
├── docker-testing
├── docker-compose-mariadb.yml
├── docker-compose-mysql.yml
└── docker-compose-postgres.yml
├── docker
├── Dockerfile
├── README.md
├── config.json
├── docker-compose-db-nginx.yml
├── docker-compose.yml
└── server_config.json
├── docs
├── README.md
├── _config.yml
├── board-metrics.md
├── code-review.md
├── contribution-checklist.md
├── contributions-without-ticket.md
├── core-committers.md
├── create-new-board.md
├── dev-tips.md
├── focalboard-dev-guide.md
├── focalboard-plugin-end-user-guide.md
├── get-started-with-board-templates.md
├── group-filter-sort-boards.md
├── import-export-backup-data.md
├── index.md
├── link-boards-to-mattermost-channels.md
├── manage-boards.md
├── manage-plugin-preferences.md
├── plugin-data-being-collected.md
├── share-collaborate.md
├── work-with-board-views.md
└── work-with-cards.md
├── experiments
└── webext
│ ├── .gitignore
│ ├── .parcelrc
│ ├── README.md
│ ├── icons
│ ├── 19.png
│ ├── 38.png
│ ├── 48.png
│ └── 96.png
│ ├── manifest.json
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ ├── utils
│ │ ├── Board.ts
│ │ ├── networking.ts
│ │ └── settings.ts
│ └── views
│ │ ├── OptionsApp.scss
│ │ ├── OptionsApp.tsx
│ │ ├── PopupApp.scss
│ │ ├── PopupApp.tsx
│ │ ├── options.html
│ │ ├── options.tsx
│ │ ├── popup.html
│ │ └── popup.tsx
│ └── tsconfig.json
├── import
├── README.md
├── asana
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── README.md
│ ├── asana.ts
│ ├── importAsana.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── tsconfig.json
│ └── utils.ts
├── jira
│ ├── .gitignore
│ ├── README.md
│ ├── importJira.ts
│ ├── jiraImporter.test.ts
│ ├── jiraImporter.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── test
│ │ └── jira-export.xml
│ ├── tsconfig.json
│ └── utils.ts
├── nextcloud-deck
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── deck.ts
│ ├── importDeck.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── tsconfig.json
│ └── utils.ts
├── notion
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── importNotion.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── tsconfig.json
│ └── utils.ts
├── todoist
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── importTodoist.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── todoist.ts
│ ├── tsconfig.json
│ └── utils.ts
├── trello
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── README.md
│ ├── importTrello.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── trello.ts
│ ├── tsconfig.json
│ └── utils.ts
└── util
│ └── archive.ts
├── linux
├── Makefile
├── config.json
├── go.mod
├── go.sum
├── main.go
├── pack
└── webapp
├── mac
├── Focalboard.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Focalboard.xcscheme
├── Focalboard.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Focalboard
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── focalboard-1024.png
│ │ │ └── focalboard-512.png
│ │ └── Contents.json
│ ├── AutoSaveWindowController.swift
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── CustomWKWebView.swift
│ ├── DownloadHandler.swift
│ ├── Focalboard.entitlements
│ ├── Globals.swift
│ ├── Info.plist
│ ├── Inherit.entitlements
│ ├── PortUtils.swift
│ ├── ViewController.swift
│ ├── WhatsNewViewController.swift
│ └── whatsnew.txt
├── FocalboardTests
│ ├── FocalboardTests.swift
│ └── Info.plist
├── FocalboardUITests
│ ├── FocalboardUITests.swift
│ └── Info.plist
├── README.md
└── export.plist
├── modd-servertest.conf
├── modd.conf
├── noticegen
├── Readme.md
└── config.yaml
├── pull_request_template.md
├── responsible_disclosure_policy.md
├── server-config.json
├── server
├── .golangci.yml
├── admin-scripts
│ └── reset-password.sh
├── api
│ ├── admin.go
│ ├── api.go
│ ├── api_test.go
│ ├── archive.go
│ ├── audit.go
│ ├── auth.go
│ ├── blocks.go
│ ├── boards.go
│ ├── boards_and_blocks.go
│ ├── cards.go
│ ├── categories.go
│ ├── channels.go
│ ├── compliance.go
│ ├── config.go
│ ├── content_blocks.go
│ ├── context.go
│ ├── files.go
│ ├── members.go
│ ├── onboarding.go
│ ├── search.go
│ ├── sharing.go
│ ├── statistics.go
│ ├── subscriptions.go
│ ├── system.go
│ ├── system_test.go
│ ├── teams.go
│ ├── templates.go
│ └── users.go
├── app
│ ├── app.go
│ ├── app_test.go
│ ├── auth.go
│ ├── auth_test.go
│ ├── blocks.go
│ ├── blocks_test.go
│ ├── boards.go
│ ├── boards_and_blocks.go
│ ├── boards_test.go
│ ├── cards.go
│ ├── cards_test.go
│ ├── category.go
│ ├── category_boards.go
│ ├── category_boards_test.go
│ ├── category_test.go
│ ├── clientConfig.go
│ ├── clientConfig_test.go
│ ├── compliance.go
│ ├── content_blocks.go
│ ├── content_blocks_test.go
│ ├── export.go
│ ├── files.go
│ ├── files_test.go
│ ├── helper_test.go
│ ├── import.go
│ ├── import_test.go
│ ├── initialize.go
│ ├── onboarding.go
│ ├── onboarding_test.go
│ ├── permissions.go
│ ├── server_metadata.go
│ ├── server_metadata_test.go
│ ├── sharing.go
│ ├── sharing_test.go
│ ├── statistics.go
│ ├── subscriptions.go
│ ├── teams.go
│ ├── teams_test.go
│ ├── templates.boardarchive
│ ├── templates.go
│ ├── templates_test.go
│ ├── user.go
│ └── user_test.go
├── assets
│ ├── assets.go
│ ├── build-template-archive
│ │ └── main.go
│ ├── templates-boardarchive
│ │ ├── b7wnw9awd4pnefryhq51apbzb4c
│ │ │ └── board.jsonl
│ │ ├── bbkpwdj8x17bdpdqd176n8ctoua
│ │ │ └── board.jsonl
│ │ ├── bbn1888mprfrm5fjw9f1je9x3xo
│ │ │ ├── 76fwrj36hptg6dywka4k5mt3sph.png
│ │ │ └── board.jsonl
│ │ ├── bc41mwxg9ybb69pn9j5zna6d36c
│ │ │ └── board.jsonl
│ │ ├── bcm39o11e4ib8tye8mt6iyuec9o
│ │ │ └── board.jsonl
│ │ ├── bd65qbzuqupfztpg31dgwgwm5ga
│ │ │ └── board.jsonl
│ │ ├── bgi1yqiis8t8xdqxgnet8ebutky
│ │ │ ├── 7b9xk9boj3fbqfm3umeaaizp8qr.png
│ │ │ ├── 7tmfu5iqju3n1mdfwi5gru89qmw.png
│ │ │ └── board.jsonl
│ │ ├── bh4pkixqsjift58e1qy6htrgeay
│ │ │ └── board.jsonl
│ │ ├── bkqk6hpfx7pbsucue7jan5n1o1o
│ │ │ └── board.jsonl
│ │ ├── brs9cdimfw7fodyi7erqt747rhc
│ │ │ ├── 7y5kr8x8ybpnwdykjfuz57rggrh.png
│ │ │ └── board.jsonl
│ │ ├── bsjd59qtpbf888mqez3ge77domw
│ │ │ └── board.jsonl
│ │ ├── bui5izho7dtn77xg3thkiqprc9r
│ │ │ ├── 77pe9r4ckbin438ph3f18bpatua.png
│ │ │ ├── 7pbp4qg415pbstc6enzeicnu3qh.png
│ │ │ └── board.jsonl
│ │ ├── buixxjic3xjfkieees4iafdrznc
│ │ │ ├── 74nt9eqzea3ydjjpgjtsxcjgrxc.gif
│ │ │ ├── 74uia99m9btr8peydw7oexn37tw.gif
│ │ │ ├── 78jws5m1myf8pufewzkaa6i11sc.gif
│ │ │ ├── 7d6hrtig3zt8f9cnbo1um5oxx3y.gif
│ │ │ ├── 7dybb6t8fj3nrdft7nerhuf784y.png
│ │ │ ├── 7ek6wbpp19jfoujs1goh6kttbby.gif
│ │ │ ├── 7iw4rxx7jj7bypmdotd9z469cyh.png
│ │ │ ├── 7knxbyuiedtdafcgmropgkrtybr.gif
│ │ │ └── board.jsonl
│ │ └── version.json
│ └── templates.boardarchive
├── auth
│ ├── auth.go
│ ├── auth_test.go
│ └── mocks
│ │ └── mockauth_interface.go
├── client
│ └── client.go
├── go.mod
├── go.sum
├── go.tools.mod
├── go.tools.sum
├── integrationtests
│ ├── blocks_test.go
│ ├── board_test.go
│ ├── boards_and_blocks_test.go
│ ├── cards_test.go
│ ├── clienttestlib.go
│ ├── compliance_test.go
│ ├── content_blocks_test.go
│ ├── export_test.go
│ ├── file_test.go
│ ├── permissions_test.go
│ ├── pluginteststore.go
│ ├── sharing_test.go
│ ├── sidebar_test.go
│ ├── subscriptions_test.go
│ ├── teststore.go
│ ├── user_test.go
│ └── work_template_test.go
├── main
│ ├── doc.go
│ └── main.go
├── model
│ ├── auth.go
│ ├── block.go
│ ├── block_test.go
│ ├── blockid.go
│ ├── blocktype.go
│ ├── board.go
│ ├── board_statistics.go
│ ├── boards_and_blocks.go
│ ├── boards_and_blocks_test.go
│ ├── card.go
│ ├── card_test.go
│ ├── category.go
│ ├── category_boards.go
│ ├── clientConfig.go
│ ├── cloud.go
│ ├── compliance.go
│ ├── database.go
│ ├── error.go
│ ├── errorResponse.go
│ ├── file.go
│ ├── import_export.go
│ ├── log_level.go
│ ├── mocks
│ │ ├── mockservicesapi.go
│ │ └── propValueResolverMock.go
│ ├── notification.go
│ ├── permission.go
│ ├── properties.go
│ ├── properties_test.go
│ ├── services_api.go
│ ├── sharing.go
│ ├── subscription.go
│ ├── team.go
│ ├── user.go
│ ├── util.go
│ └── version.go
├── server
│ ├── initHandlers.go
│ ├── params.go
│ └── server.go
├── services
│ ├── audit
│ │ ├── audit.go
│ │ ├── record.go
│ │ └── record_test.go
│ ├── auth
│ │ ├── email.go
│ │ ├── password.go
│ │ ├── password_test.go
│ │ ├── request_parser.go
│ │ └── request_parser_test.go
│ ├── config
│ │ └── config.go
│ ├── metrics
│ │ ├── metrics.go
│ │ └── service.go
│ ├── notify
│ │ ├── notifylogger
│ │ │ └── logger_backend.go
│ │ ├── notifymentions
│ │ │ ├── app_api.go
│ │ │ ├── delivery.go
│ │ │ ├── extract.go
│ │ │ ├── extract_test.go
│ │ │ ├── mentions.go
│ │ │ ├── mentions_backend.go
│ │ │ └── mentions_test.go
│ │ ├── notifysubscriptions
│ │ │ ├── app_api.go
│ │ │ ├── delivery.go
│ │ │ ├── diff.go
│ │ │ ├── diff2markdown.go
│ │ │ ├── diff2markdown_test.go
│ │ │ ├── diff2slackattachments.go
│ │ │ ├── notifier.go
│ │ │ ├── subscriptions_backend.go
│ │ │ └── util.go
│ │ ├── plugindelivery
│ │ │ ├── mention_deliver.go
│ │ │ ├── message.go
│ │ │ ├── plugin_delivery.go
│ │ │ ├── subscription_deliver.go
│ │ │ ├── user.go
│ │ │ └── user_test.go
│ │ └── service.go
│ ├── permissions
│ │ ├── localpermissions
│ │ │ ├── helpers_test.go
│ │ │ ├── localpermissions.go
│ │ │ └── localpermissions_test.go
│ │ ├── mmpermissions
│ │ │ ├── helpers_test.go
│ │ │ ├── mmpermissions.go
│ │ │ ├── mmpermissions_test.go
│ │ │ └── mocks
│ │ │ │ └── mockpluginapi.go
│ │ ├── mocks
│ │ │ └── mockstore.go
│ │ └── permissions.go
│ ├── scheduler
│ │ ├── scheduler.go
│ │ └── scheduler_test.go
│ ├── store
│ │ ├── generators
│ │ │ ├── main.go
│ │ │ └── transactional_store.go.tmpl
│ │ ├── mattermostauthlayer
│ │ │ ├── mattermostauthlayer.go
│ │ │ └── mattermostauthlayer_test.go
│ │ ├── mockstore
│ │ │ └── mockstore.go
│ │ ├── sqlstore
│ │ │ ├── blocks.go
│ │ │ ├── board.go
│ │ │ ├── boards_and_blocks.go
│ │ │ ├── category.go
│ │ │ ├── category_boards.go
│ │ │ ├── cloud.go
│ │ │ ├── compliance.go
│ │ │ ├── data_migrations.go
│ │ │ ├── data_migrations_test.go
│ │ │ ├── data_retention.go
│ │ │ ├── file.go
│ │ │ ├── helpers_test.go
│ │ │ ├── legacy_blocks.go
│ │ │ ├── migrate.go
│ │ │ ├── migrations
│ │ │ │ ├── 000001_init.down.sql
│ │ │ │ ├── 000001_init.up.sql
│ │ │ │ ├── 000002_system_settings_table.down.sql
│ │ │ │ ├── 000002_system_settings_table.up.sql
│ │ │ │ ├── 000003_blocks_rootid.down.sql
│ │ │ │ ├── 000003_blocks_rootid.up.sql
│ │ │ │ ├── 000004_auth_table.down.sql
│ │ │ │ ├── 000004_auth_table.up.sql
│ │ │ │ ├── 000005_blocks_modifiedby.down.sql
│ │ │ │ ├── 000005_blocks_modifiedby.up.sql
│ │ │ │ ├── 000006_sharing_table.down.sql
│ │ │ │ ├── 000006_sharing_table.up.sql
│ │ │ │ ├── 000007_workspaces_table.down.sql
│ │ │ │ ├── 000007_workspaces_table.up.sql
│ │ │ │ ├── 000008_teams.down.sql
│ │ │ │ ├── 000008_teams.up.sql
│ │ │ │ ├── 000009_blocks_history.down.sql
│ │ │ │ ├── 000009_blocks_history.up.sql
│ │ │ │ ├── 000010_blocks_created_by.down.sql
│ │ │ │ ├── 000010_blocks_created_by.up.sql
│ │ │ │ ├── 000011_match_collation.down.sql
│ │ │ │ ├── 000011_match_collation.up.sql
│ │ │ │ ├── 000012_match_column_collation.down.sql
│ │ │ │ ├── 000012_match_column_collation.up.sql
│ │ │ │ ├── 000013_millisecond_timestamps.down.sql
│ │ │ │ ├── 000013_millisecond_timestamps.up.sql
│ │ │ │ ├── 000014_add_not_null_constraint.down.sql
│ │ │ │ ├── 000014_add_not_null_constraint.up.sql
│ │ │ │ ├── 000015_blocks_history_no_nulls.down.sql
│ │ │ │ ├── 000015_blocks_history_no_nulls.up.sql
│ │ │ │ ├── 000016_subscriptions_table.down.sql
│ │ │ │ ├── 000016_subscriptions_table.up.sql
│ │ │ │ ├── 000017_add_file_info.down.sql
│ │ │ │ ├── 000017_add_file_info.up.sql
│ │ │ │ ├── 000018_add_teams_and_boards.down.sql
│ │ │ │ ├── 000018_add_teams_and_boards.up.sql
│ │ │ │ ├── 000019_populate_categories.down.sql
│ │ │ │ ├── 000019_populate_categories.up.sql
│ │ │ │ ├── 000020_populate_category_blocks.down.sql
│ │ │ │ ├── 000020_populate_category_blocks.up.sql
│ │ │ │ ├── 000021_create_boards_members_history.down.sql
│ │ │ │ ├── 000021_create_boards_members_history.up.sql
│ │ │ │ ├── 000022_create_default_board_role.down.sql
│ │ │ │ ├── 000022_create_default_board_role.up.sql
│ │ │ │ ├── 000023_persist_category_collapsed_state.down.sql
│ │ │ │ ├── 000023_persist_category_collapsed_state.up.sql
│ │ │ │ ├── 000024_mark_existsing_categories_collapsed.down.sql
│ │ │ │ ├── 000024_mark_existsing_categories_collapsed.up.sql
│ │ │ │ ├── 000025_indexes_update.down.sql
│ │ │ │ ├── 000025_indexes_update.up.sql
│ │ │ │ ├── 000026_create_preferences_table.down.sql
│ │ │ │ ├── 000026_create_preferences_table.up.sql
│ │ │ │ ├── 000027_migrate_user_props_to_preferences.down.sql
│ │ │ │ ├── 000027_migrate_user_props_to_preferences.up.sql
│ │ │ │ ├── 000028_remove_template_channel_link.down.sql
│ │ │ │ ├── 000028_remove_template_channel_link.up.sql
│ │ │ │ ├── 000029_add_category_type_field.down.sql
│ │ │ │ ├── 000029_add_category_type_field.up.sql
│ │ │ │ ├── 000030_add_category_sort_order.down.sql
│ │ │ │ ├── 000030_add_category_sort_order.up.sql
│ │ │ │ ├── 000031_add_category_boards_sort_order.down.sql
│ │ │ │ ├── 000031_add_category_boards_sort_order.up.sql
│ │ │ │ ├── 000032_move_boards_category_to_end.down.sql
│ │ │ │ ├── 000032_move_boards_category_to_end.up.sql
│ │ │ │ ├── 000033_remove_deleted_category_boards.down.sql
│ │ │ │ ├── 000033_remove_deleted_category_boards.up.sql
│ │ │ │ ├── 000034_category_boards_remove_unused_delete_at_column.down.sql
│ │ │ │ ├── 000034_category_boards_remove_unused_delete_at_column.up.sql
│ │ │ │ ├── 000035_add_hidden_board_column.down.sql
│ │ │ │ ├── 000035_add_hidden_board_column.up.sql
│ │ │ │ ├── 000036_category_board_add_unique_constraint.down.sql
│ │ │ │ ├── 000036_category_board_add_unique_constraint.up.sql
│ │ │ │ ├── 000037_hidden_boards_from_preferences.down.sql
│ │ │ │ ├── 000037_hidden_boards_from_preferences.up.sql
│ │ │ │ ├── 000038_delete_hiddenBoardIDs_from_preferences.down.sql
│ │ │ │ ├── 000038_delete_hiddenBoardIDs_from_preferences.up.sql
│ │ │ │ ├── 000039_add_path_to_file_info.down.sql
│ │ │ │ ├── 000039_add_path_to_file_info.up.sql
│ │ │ │ ├── 000040_fix_fileinfo_soft_deletes.down.sql
│ │ │ │ ├── 000040_fix_fileinfo_soft_deletes.up.sql
│ │ │ │ └── README.md
│ │ │ ├── migrationstests
│ │ │ │ ├── boards_migrator_test.go
│ │ │ │ ├── de_duplicate_category_boards_migration_test.go
│ │ │ │ ├── fixtures
│ │ │ │ │ ├── deletedMembershipBoardsMigrationFixtures.sql
│ │ │ │ │ ├── test18AddTeamsAndBoardsSQLMigrationFixtures.sql
│ │ │ │ │ ├── test27MigrateUserPropsToPreferences.sql
│ │ │ │ │ ├── test28RemoveTemplateChannelLink.sql
│ │ │ │ │ ├── test33_with_deleted_data.sql
│ │ │ │ │ ├── test33_with_no_deleted_data.sql
│ │ │ │ │ ├── test34_drop_delete_at_column.sql
│ │ │ │ │ ├── test35_add_hidden_column.sql
│ │ │ │ │ ├── test36_add_unique_constraint.sql
│ │ │ │ │ ├── test37_valid_data.sql
│ │ │ │ │ ├── test37_valid_data_no_hidden_boards.sql
│ │ │ │ │ ├── test37_valid_data_preference_but_no_hidden_board.sql
│ │ │ │ │ ├── test37_valid_data_sqlite.sql
│ │ │ │ │ ├── test37_valid_data_sqlite_preference_but_no_hidden_board.sql
│ │ │ │ │ ├── test38_add_plugin_preferences.sql
│ │ │ │ │ ├── test38_add_standalone_preferences.sql
│ │ │ │ │ ├── test40FixFileinfoSoftDeletes.sql
│ │ │ │ │ └── testDeDuplicateCategoryBoardsMigration.sql
│ │ │ │ ├── helpers_test.go
│ │ │ │ ├── migrate_34_test.go
│ │ │ │ ├── migration35_test.go
│ │ │ │ ├── migration36_test.go
│ │ │ │ ├── migration37_test.go
│ │ │ │ ├── migration38_test.go
│ │ │ │ ├── migration_27_test.go
│ │ │ │ ├── migration_28_test.go
│ │ │ │ └── migration_33_test.go
│ │ │ ├── notificationhints.go
│ │ │ ├── params.go
│ │ │ ├── public_methods.go
│ │ │ ├── schema_table_migration.go
│ │ │ ├── schema_table_migration_test.go
│ │ │ ├── session.go
│ │ │ ├── sharing.go
│ │ │ ├── sqlite.go
│ │ │ ├── sqlstore.go
│ │ │ ├── sqlstore_test.go
│ │ │ ├── subscriptions.go
│ │ │ ├── system.go
│ │ │ ├── team.go
│ │ │ ├── templates.go
│ │ │ ├── user.go
│ │ │ └── util.go
│ │ ├── store.go
│ │ └── storetests
│ │ │ ├── blocks.go
│ │ │ ├── boards.go
│ │ │ ├── boards_and_blocks.go
│ │ │ ├── category.go
│ │ │ ├── categoryBoards.go
│ │ │ ├── cloud.go
│ │ │ ├── compliance.go
│ │ │ ├── data_retention.go
│ │ │ ├── files.go
│ │ │ ├── helpers.go
│ │ │ ├── notificationhints.go
│ │ │ ├── session.go
│ │ │ ├── sharing.go
│ │ │ ├── subscriptions.go
│ │ │ ├── system.go
│ │ │ ├── teams.go
│ │ │ ├── users.go
│ │ │ └── util.go
│ ├── telemetry
│ │ ├── mocks
│ │ │ └── ServerIface.go
│ │ ├── telemetry.go
│ │ └── telemetry_test.go
│ └── webhook
│ │ ├── webhook.go
│ │ └── webhook_test.go
├── swagger
│ ├── README.md
│ ├── docs
│ │ └── html
│ │ │ ├── .openapi-generator-ignore
│ │ │ ├── .openapi-generator
│ │ │ └── VERSION
│ │ │ └── index.html
│ └── swagger.yml
├── utils
│ ├── callbackqueue.go
│ ├── callbackqueue_test.go
│ ├── debug.go
│ ├── links.go
│ ├── testUtils.go
│ └── utils.go
├── web
│ ├── webserver.go
│ └── webserver_test.go
└── ws
│ ├── adapter.go
│ ├── common.go
│ ├── helpers_test.go
│ ├── mocks
│ ├── mockpluginapi.go
│ └── mockstore.go
│ ├── plugin_adapter.go
│ ├── plugin_adapter_client.go
│ ├── plugin_adapter_cluster.go
│ ├── plugin_adapter_test.go
│ ├── server.go
│ └── server_test.go
├── webapp
├── .eslintignore
├── .eslintrc.json
├── .nvmrc
├── .prettierignore
├── .prettierrc.json
├── .stylelintrc.json
├── NOTICE.txt
├── __mocks__
│ ├── fileMock.js
│ └── styleMock.js
├── cypress.json
├── cypress
│ ├── config.json
│ ├── global.d.ts
│ ├── integration
│ │ ├── cardBadges.ts
│ │ ├── cardURLProperty.ts
│ │ ├── createBoard.ts
│ │ ├── groupByProperty.ts
│ │ ├── loginActions.ts
│ │ └── manageGroups.ts
│ ├── plugins
│ │ └── index.js
│ ├── support
│ │ ├── api_commands.ts
│ │ ├── index.ts
│ │ └── ui_commands.ts
│ └── tsconfig.json
├── html-templates
│ ├── deveditor.ejs
│ └── page.ejs
├── i18n
│ ├── ar.json
│ ├── ars.json
│ ├── ca.json
│ ├── de.json
│ ├── el.json
│ ├── en.json
│ ├── en_AU.json
│ ├── es.json
│ ├── et.json
│ ├── fa.json
│ ├── fr.json
│ ├── he.json
│ ├── hr.json
│ ├── hu.json
│ ├── id.json
│ ├── it.json
│ ├── ja.json
│ ├── ka.json
│ ├── kab.json
│ ├── kk.json
│ ├── ko.json
│ ├── lt.json
│ ├── ml.json
│ ├── nb_NO.json
│ ├── nl.json
│ ├── oc.json
│ ├── pl.json
│ ├── pt.json
│ ├── pt_BR.json
│ ├── ru.json
│ ├── sk.json
│ ├── sl.json
│ ├── sv.json
│ ├── tr.json
│ ├── uk.json
│ ├── vi.json
│ ├── zh_Hans.json
│ └── zh_Hant.json
├── package-lock.json
├── package.json
├── src
│ ├── app.tsx
│ ├── archiver.ts
│ ├── blockIcons.ts
│ ├── blocks
│ │ ├── __snapshots__
│ │ │ ├── block.test.ts.snap
│ │ │ └── board.test.ts.snap
│ │ ├── attachmentBlock.tsx
│ │ ├── block.test.ts
│ │ ├── block.ts
│ │ ├── board.test.ts
│ │ ├── board.ts
│ │ ├── boardView.test.ts
│ │ ├── boardView.ts
│ │ ├── card.ts
│ │ ├── checkboxBlock.ts
│ │ ├── commentBlock.ts
│ │ ├── contentBlock.ts
│ │ ├── dividerBlock.ts
│ │ ├── filterClause.test.ts
│ │ ├── filterClause.ts
│ │ ├── filterGroup.ts
│ │ ├── h1Block.tsx
│ │ ├── h2Block.tsx
│ │ ├── h3Block.tsx
│ │ ├── imageBlock.ts
│ │ ├── sharing.ts
│ │ ├── team.ts
│ │ ├── textBlock.ts
│ │ └── workspace.ts
│ ├── boardCloudLimits
│ │ └── index.ts
│ ├── boardUtils.ts
│ ├── boardsCloudLimits
│ │ └── index.ts
│ ├── cardFilter.test.ts
│ ├── cardFilter.ts
│ ├── components
│ │ ├── __snapshots__
│ │ │ ├── addContentMenuItem.test.tsx.snap
│ │ │ ├── blockIconSelector.test.tsx.snap
│ │ │ ├── cardBadges.test.tsx.snap
│ │ │ ├── cardDialog.test.tsx.snap
│ │ │ ├── centerPanel.test.tsx.snap
│ │ │ ├── confirmAddUserForNotifications.test.tsx.snap
│ │ │ ├── confirmationDialogBox.test.tsx.snap
│ │ │ ├── contentBlock.test.tsx.snap
│ │ │ ├── dialog.test.tsx.snap
│ │ │ ├── flashMessages.test.tsx.snap
│ │ │ ├── markdownEditor.test.tsx.snap
│ │ │ ├── modal.test.tsx.snap
│ │ │ ├── personSelector.test.tsx.snap
│ │ │ ├── propertyValueElement.test.tsx.snap
│ │ │ ├── rootPortal.test.tsx.snap
│ │ │ ├── topBar.test.tsx.snap
│ │ │ ├── viewMenu.test.tsx.snap
│ │ │ ├── viewTitle.test.tsx.snap
│ │ │ └── workspace.test.tsx.snap
│ │ ├── addContentMenuItem.test.tsx
│ │ ├── addContentMenuItem.tsx
│ │ ├── blockIconSelector.test.tsx
│ │ ├── blockIconSelector.tsx
│ │ ├── blocksEditor
│ │ │ ├── __snapshots__
│ │ │ │ ├── blockContent.test.tsx.snap
│ │ │ │ ├── blocksEditor.test.tsx.snap
│ │ │ │ ├── editor.test.tsx.snap
│ │ │ │ └── rootInput.test.tsx.snap
│ │ │ ├── blockContent.scss
│ │ │ ├── blockContent.test.tsx
│ │ │ ├── blockContent.tsx
│ │ │ ├── blocks
│ │ │ │ ├── attachment
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── attachment.test.tsx.snap
│ │ │ │ │ ├── attachment.scss
│ │ │ │ │ ├── attachment.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── checkbox
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── checkbox.test.tsx.snap
│ │ │ │ │ ├── checkbox.scss
│ │ │ │ │ ├── checkbox.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── divider
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── divider.test.tsx.snap
│ │ │ │ │ ├── divider.scss
│ │ │ │ │ ├── divider.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── h1
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── h1.test.tsx.snap
│ │ │ │ │ ├── h1.scss
│ │ │ │ │ ├── h1.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── h2
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── h2.test.tsx.snap
│ │ │ │ │ ├── h2.scss
│ │ │ │ │ ├── h2.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── h3
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── h3.test.tsx.snap
│ │ │ │ │ ├── h3.scss
│ │ │ │ │ ├── h3.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── image
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── image.test.tsx.snap
│ │ │ │ │ ├── image.scss
│ │ │ │ │ ├── image.test.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── list-item
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── list-item.test.tsx.snap
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── list-item.scss
│ │ │ │ │ └── list-item.test.tsx
│ │ │ │ ├── quote
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── quote.test.tsx.snap
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── quote.scss
│ │ │ │ │ └── quote.test.tsx
│ │ │ │ ├── text-dev
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── text.scss
│ │ │ │ ├── text
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ │ └── text.test.tsx.snap
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── text.scss
│ │ │ │ │ └── text.test.tsx
│ │ │ │ ├── types.tsx
│ │ │ │ └── video
│ │ │ │ │ ├── __snapshots__
│ │ │ │ │ └── video.test.tsx.snap
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── video.scss
│ │ │ │ │ └── video.test.tsx
│ │ │ ├── blocksEditor.test.tsx
│ │ │ ├── blocksEditor.tsx
│ │ │ ├── devmain.scss
│ │ │ ├── devmain.tsx
│ │ │ ├── editor.scss
│ │ │ ├── editor.test.tsx
│ │ │ ├── editor.tsx
│ │ │ ├── rootInput.test.tsx
│ │ │ └── rootInput.tsx
│ │ ├── boardIconSelector.tsx
│ │ ├── boardTemplateSelector
│ │ │ ├── __snapshots__
│ │ │ │ ├── boardTemplateSelector.test.tsx.snap
│ │ │ │ ├── boardTemplateSelectorItem.test.tsx.snap
│ │ │ │ └── boardTemplateSelectorPreview.test.tsx.snap
│ │ │ ├── boardTemplateSelector.scss
│ │ │ ├── boardTemplateSelector.test.tsx
│ │ │ ├── boardTemplateSelector.tsx
│ │ │ ├── boardTemplateSelectorItem.scss
│ │ │ ├── boardTemplateSelectorItem.test.tsx
│ │ │ ├── boardTemplateSelectorItem.tsx
│ │ │ ├── boardTemplateSelectorPreview.scss
│ │ │ ├── boardTemplateSelectorPreview.test.tsx
│ │ │ └── boardTemplateSelectorPreview.tsx
│ │ ├── boardsSwitcher
│ │ │ ├── boardsSwitcher.scss
│ │ │ └── boardsSwitcher.tsx
│ │ ├── boardsSwitcherDialog
│ │ │ ├── __snapshots__
│ │ │ │ └── boardSwitcherDialog.test.tsx.snap
│ │ │ ├── boardSwitcherDialog.scss
│ │ │ ├── boardSwitcherDialog.test.tsx
│ │ │ └── boardSwitcherDialog.tsx
│ │ ├── calculations
│ │ │ ├── __snapshots__
│ │ │ │ ├── calculation.test.tsx.snap
│ │ │ │ └── options.test.tsx.snap
│ │ │ ├── calculation.scss
│ │ │ ├── calculation.test.tsx
│ │ │ ├── calculation.tsx
│ │ │ ├── calculations.test.tsx
│ │ │ ├── calculations.ts
│ │ │ ├── options.test.tsx
│ │ │ └── options.tsx
│ │ ├── calendar
│ │ │ ├── __snapshots__
│ │ │ │ └── fullCalendar.test.tsx.snap
│ │ │ ├── fullCalendar.test.tsx
│ │ │ ├── fullCalendar.tsx
│ │ │ └── fullcalendar.scss
│ │ ├── cardActionsMenu
│ │ │ ├── __snapshots__
│ │ │ │ └── cardActionsMenu.test.tsx.snap
│ │ │ ├── cardActionsMenu.test.tsx
│ │ │ ├── cardActionsMenu.tsx
│ │ │ ├── cardActionsMenuIcon.scss
│ │ │ └── cardActionsMenuIcon.tsx
│ │ ├── cardBadges.scss
│ │ ├── cardBadges.test.tsx
│ │ ├── cardBadges.tsx
│ │ ├── cardDetail
│ │ │ ├── __snapshots__
│ │ │ │ ├── cardDetail.test.tsx.snap
│ │ │ │ ├── cardDetailContents.test.tsx.snap
│ │ │ │ ├── cardDetailContentsMenu.test.tsx.snap
│ │ │ │ ├── cardDetailProperties.test.tsx.snap
│ │ │ │ ├── comment.test.tsx.snap
│ │ │ │ └── commentsList.test.tsx.snap
│ │ │ ├── attachment.scss
│ │ │ ├── attachment.tsx
│ │ │ ├── cardDetail.scss
│ │ │ ├── cardDetail.test.tsx
│ │ │ ├── cardDetail.tsx
│ │ │ ├── cardDetailContents.test.tsx
│ │ │ ├── cardDetailContents.tsx
│ │ │ ├── cardDetailContentsMenu.test.tsx
│ │ │ ├── cardDetailContentsMenu.tsx
│ │ │ ├── cardDetailContentsUtility.test.ts
│ │ │ ├── cardDetailContentsUtility.ts
│ │ │ ├── cardDetailContext.tsx
│ │ │ ├── cardDetailProperties.test.tsx
│ │ │ ├── cardDetailProperties.tsx
│ │ │ ├── comment.scss
│ │ │ ├── comment.test.tsx
│ │ │ ├── comment.tsx
│ │ │ ├── commentsList.scss
│ │ │ ├── commentsList.test.tsx
│ │ │ ├── commentsList.tsx
│ │ │ └── imagePaste.tsx
│ │ ├── cardDialog.scss
│ │ ├── cardDialog.test.tsx
│ │ ├── cardDialog.tsx
│ │ ├── cardLimitNotification.scss
│ │ ├── cardLimitNotification.tsx
│ │ ├── centerPanel.scss
│ │ ├── centerPanel.test.tsx
│ │ ├── centerPanel.tsx
│ │ ├── confirmAddUserForNotifications.scss
│ │ ├── confirmAddUserForNotifications.test.tsx
│ │ ├── confirmAddUserForNotifications.tsx
│ │ ├── confirmationDialogBox.scss
│ │ ├── confirmationDialogBox.test.tsx
│ │ ├── confirmationDialogBox.tsx
│ │ ├── content
│ │ │ ├── __snapshots__
│ │ │ │ ├── attachmentElement.test.tsx.snap
│ │ │ │ ├── checkboxElement.test.tsx.snap
│ │ │ │ ├── contentElement.test.tsx.snap
│ │ │ │ ├── dividerElement.test.tsx.snap
│ │ │ │ ├── imageElement.test.tsx.snap
│ │ │ │ └── textElement.test.tsx.snap
│ │ │ ├── archivedFile
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── archivedFile.test.tsx.snap
│ │ │ │ ├── archivedFile.scss
│ │ │ │ ├── archivedFile.test.tsx
│ │ │ │ └── archivedFile.tsx
│ │ │ ├── attachmentElement.scss
│ │ │ ├── attachmentElement.test.tsx
│ │ │ ├── attachmentElement.tsx
│ │ │ ├── checkboxElement.scss
│ │ │ ├── checkboxElement.test.tsx
│ │ │ ├── checkboxElement.tsx
│ │ │ ├── contentElement.test.tsx
│ │ │ ├── contentElement.tsx
│ │ │ ├── contentRegistry.test.tsx
│ │ │ ├── contentRegistry.tsx
│ │ │ ├── dividerElement.scss
│ │ │ ├── dividerElement.test.tsx
│ │ │ ├── dividerElement.tsx
│ │ │ ├── imageElement.test.tsx
│ │ │ ├── imageElement.tsx
│ │ │ ├── textElement.scss
│ │ │ ├── textElement.test.tsx
│ │ │ └── textElement.tsx
│ │ ├── contentBlock.scss
│ │ ├── contentBlock.test.tsx
│ │ ├── contentBlock.tsx
│ │ ├── createCategory
│ │ │ ├── __snapshots__
│ │ │ │ └── createCategory.test.tsx.snap
│ │ │ ├── createCategory.scss
│ │ │ ├── createCategory.test.tsx
│ │ │ └── createCategory.tsx
│ │ ├── dialog.scss
│ │ ├── dialog.test.tsx
│ │ ├── dialog.tsx
│ │ ├── flashMessages.scss
│ │ ├── flashMessages.test.tsx
│ │ ├── flashMessages.tsx
│ │ ├── gallery
│ │ │ ├── __snapshots__
│ │ │ │ ├── gallery.test.tsx.snap
│ │ │ │ └── galleryCard.test.tsx.snap
│ │ │ ├── gallery.scss
│ │ │ ├── gallery.test.tsx
│ │ │ ├── gallery.tsx
│ │ │ ├── galleryCard.scss
│ │ │ ├── galleryCard.test.tsx
│ │ │ └── galleryCard.tsx
│ │ ├── globalHeader
│ │ │ ├── __snapshots__
│ │ │ │ ├── globalHeader.test.tsx.snap
│ │ │ │ └── globalHeaderSettingsMenu.test.tsx.snap
│ │ │ ├── globalHeader.scss
│ │ │ ├── globalHeader.test.tsx
│ │ │ ├── globalHeader.tsx
│ │ │ ├── globalHeaderSettingsMenu.scss
│ │ │ ├── globalHeaderSettingsMenu.test.tsx
│ │ │ └── globalHeaderSettingsMenu.tsx
│ │ ├── guestNoBoards.scss
│ │ ├── guestNoBoards.tsx
│ │ ├── hiddenCardCount
│ │ │ ├── hiddenCardCount.scss
│ │ │ └── hiddenCardCount.tsx
│ │ ├── iconSelector.scss
│ │ ├── iconSelector.tsx
│ │ ├── kanban
│ │ │ ├── __snapshots__
│ │ │ │ ├── kanban.test.tsx.snap
│ │ │ │ ├── kanbanCard.test.tsx.snap
│ │ │ │ ├── kanbanColumn.test.tsx.snap
│ │ │ │ ├── kanbanColumnHeader.test.tsx.snap
│ │ │ │ └── kanbanHiddenColumnItem.test.tsx.snap
│ │ │ ├── calculation
│ │ │ │ ├── __snapshots__
│ │ │ │ │ ├── calculation.test.tsx.snap
│ │ │ │ │ ├── calculationOptions.test.tsx.snap
│ │ │ │ │ └── kanbanOption.test.tsx.snap
│ │ │ │ ├── calculation.scss
│ │ │ │ ├── calculation.test.tsx
│ │ │ │ ├── calculation.tsx
│ │ │ │ ├── calculationOption.scss
│ │ │ │ ├── calculationOptions.test.tsx
│ │ │ │ ├── calculationOptions.tsx
│ │ │ │ ├── kanbanOption.test.tsx
│ │ │ │ └── kanbanOption.tsx
│ │ │ ├── kanban.scss
│ │ │ ├── kanban.test.tsx
│ │ │ ├── kanban.tsx
│ │ │ ├── kanbanCard.scss
│ │ │ ├── kanbanCard.test.tsx
│ │ │ ├── kanbanCard.tsx
│ │ │ ├── kanbanColumn.scss
│ │ │ ├── kanbanColumn.test.tsx
│ │ │ ├── kanbanColumn.tsx
│ │ │ ├── kanbanColumnHeader.test.tsx
│ │ │ ├── kanbanColumnHeader.tsx
│ │ │ ├── kanbanHiddenColumnItem.test.tsx
│ │ │ └── kanbanHiddenColumnItem.tsx
│ │ ├── live-markdown-plugin
│ │ │ ├── block-types
│ │ │ │ ├── codeBlockStrategy.ts
│ │ │ │ └── headingBlockStrategy.ts
│ │ │ ├── inline-styles
│ │ │ │ ├── boldStyleStrategy.ts
│ │ │ │ ├── headingDelimiterStyleStrategy.ts
│ │ │ │ ├── inlineCodeStyleStrategy.ts
│ │ │ │ ├── italicStyleStrategy.ts
│ │ │ │ ├── olDelimiterStyleStrategy.ts
│ │ │ │ ├── quoteStyleStrategy.ts
│ │ │ │ ├── strikethroughStyleStrategy.ts
│ │ │ │ └── ulDelimiterStyleStrategy.ts
│ │ │ ├── liveMarkdownPlugin.ts
│ │ │ ├── pluginStrategy.ts
│ │ │ └── utils
│ │ │ │ └── findRangesWithRegex.ts
│ │ ├── markdownEditor.scss
│ │ ├── markdownEditor.test.tsx
│ │ ├── markdownEditor.tsx
│ │ ├── markdownEditorInput
│ │ │ ├── entryComponent
│ │ │ │ ├── entryComponent.scss
│ │ │ │ └── entryComponent.tsx
│ │ │ ├── markdownEditorInput.scss
│ │ │ └── markdownEditorInput.tsx
│ │ ├── messages
│ │ │ ├── versionMessage.scss
│ │ │ ├── versionMessage.test.tsx
│ │ │ └── versionMessage.tsx
│ │ ├── modal.scss
│ │ ├── modal.test.tsx
│ │ ├── modal.tsx
│ │ ├── modalWrapper.scss
│ │ ├── modalWrapper.tsx
│ │ ├── newVersionBanner.scss
│ │ ├── newVersionBanner.tsx
│ │ ├── onboardingTour
│ │ │ ├── addComments
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── addComments.test.tsx.snap
│ │ │ │ ├── addComments.test.tsx
│ │ │ │ ├── addComments.tsx
│ │ │ │ └── add_comments.scss
│ │ │ ├── addDescription
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── addDescription.test.tsx.snap
│ │ │ │ ├── addDescription.test.tsx
│ │ │ │ ├── add_description.scss
│ │ │ │ └── add_description.tsx
│ │ │ ├── addProperties
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── addProperties.test.tsx.snap
│ │ │ │ ├── addProperties.test.tsx
│ │ │ │ ├── add_properties.scss
│ │ │ │ └── add_properties.tsx
│ │ │ ├── addView
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── addView.test.tsx.snap
│ │ │ │ ├── addView.test.tsx
│ │ │ │ ├── add_view.scss
│ │ │ │ └── add_view.tsx
│ │ │ ├── copyLink
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── copyLink.test.tsx.snap
│ │ │ │ ├── copyLink.test.tsx
│ │ │ │ ├── copy_link.scss
│ │ │ │ └── copy_link.tsx
│ │ │ ├── index.ts
│ │ │ ├── manageCategories
│ │ │ │ ├── manageCategories.scss
│ │ │ │ └── manageCategories.tsx
│ │ │ ├── openCard
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── openCard.test.tsx.snap
│ │ │ │ ├── openCard.test.tsx
│ │ │ │ ├── open_card.scss
│ │ │ │ └── open_card.tsx
│ │ │ ├── searchForBoards
│ │ │ │ ├── searchForBoards.scss
│ │ │ │ └── searchForBoards.tsx
│ │ │ ├── shareBoard
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── shareBoard.test.tsx.snap
│ │ │ │ ├── shareBoard.scss
│ │ │ │ ├── shareBoard.test.tsx
│ │ │ │ └── shareBoard.tsx
│ │ │ ├── sidebarCategories
│ │ │ │ ├── sidebarCategories.scss
│ │ │ │ └── sidebarCategories.tsx
│ │ │ └── tourTipRenderer
│ │ │ │ └── tourTipRenderer.tsx
│ │ ├── permissions
│ │ │ ├── __snapshots__
│ │ │ │ └── boardPermissionGate.test.tsx.snap
│ │ │ ├── boardPermissionGate.test.tsx
│ │ │ └── boardPermissionGate.tsx
│ │ ├── personSelector.scss
│ │ ├── personSelector.test.tsx
│ │ ├── personSelector.tsx
│ │ ├── propertyValueElement.test.tsx
│ │ ├── propertyValueElement.tsx
│ │ ├── pulsating_dot
│ │ │ ├── index.tsx
│ │ │ └── pulsating_dot.scss
│ │ ├── rootPortal.test.tsx
│ │ ├── rootPortal.tsx
│ │ ├── searchDialog
│ │ │ ├── searchDialog.scss
│ │ │ └── searchDialog.tsx
│ │ ├── shareBoard
│ │ │ ├── __snapshots__
│ │ │ │ ├── shareBoard.test.tsx.snap
│ │ │ │ ├── shareBoardButton.test.tsx.snap
│ │ │ │ ├── shareBoardLoginButton.test.tsx.snap
│ │ │ │ ├── teamPermissionsRow.test.tsx.snap
│ │ │ │ └── userPermissionsRow.test.tsx.snap
│ │ │ ├── shareBoard.scss
│ │ │ ├── shareBoard.test.tsx
│ │ │ ├── shareBoard.tsx
│ │ │ ├── shareBoardButton.scss
│ │ │ ├── shareBoardButton.test.tsx
│ │ │ ├── shareBoardButton.tsx
│ │ │ ├── shareBoardLoginButton.scss
│ │ │ ├── shareBoardLoginButton.test.tsx
│ │ │ ├── shareBoardLoginButton.tsx
│ │ │ ├── teamPermissionsRow.test.tsx
│ │ │ ├── teamPermissionsRow.tsx
│ │ │ ├── userPermissionsRow.test.tsx
│ │ │ └── userPermissionsRow.tsx
│ │ ├── sidebar
│ │ │ ├── __snapshots__
│ │ │ │ ├── deleteBoardDialog.test.tsx.snap
│ │ │ │ ├── registrationLink.test.tsx.snap
│ │ │ │ ├── sidebar.test.tsx.snap
│ │ │ │ ├── sidebarBoardItem.test.tsx.snap
│ │ │ │ ├── sidebarCategory.test.tsx.snap
│ │ │ │ └── sidebarSettingsMenu.test.tsx.snap
│ │ │ ├── deleteBoardDialog.scss
│ │ │ ├── deleteBoardDialog.test.tsx
│ │ │ ├── deleteBoardDialog.tsx
│ │ │ ├── registrationLink.scss
│ │ │ ├── registrationLink.test.tsx
│ │ │ ├── registrationLink.tsx
│ │ │ ├── sidebar.scss
│ │ │ ├── sidebar.test.tsx
│ │ │ ├── sidebar.tsx
│ │ │ ├── sidebarBoardItem.scss
│ │ │ ├── sidebarBoardItem.test.tsx
│ │ │ ├── sidebarBoardItem.tsx
│ │ │ ├── sidebarCategory.scss
│ │ │ ├── sidebarCategory.test.tsx
│ │ │ ├── sidebarCategory.tsx
│ │ │ ├── sidebarSettingsMenu.scss
│ │ │ ├── sidebarSettingsMenu.test.tsx
│ │ │ ├── sidebarSettingsMenu.tsx
│ │ │ ├── sidebarUserMenu.scss
│ │ │ └── sidebarUserMenu.tsx
│ │ ├── table
│ │ │ ├── __snapshots__
│ │ │ │ ├── table.test.tsx.snap
│ │ │ │ ├── tableGroupHeaderRow.test.tsx.snap
│ │ │ │ ├── tableHeader.test.tsx.snap
│ │ │ │ ├── tableHeaderMenu.test.tsx.snap
│ │ │ │ ├── tableHeaders.test.tsx.snap
│ │ │ │ ├── tableRow.test.tsx.snap
│ │ │ │ └── tableRows.test.tsx.snap
│ │ │ ├── calculation
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── calculationRow.test.tsx.snap
│ │ │ │ ├── calculationRow.scss
│ │ │ │ ├── calculationRow.test.tsx
│ │ │ │ ├── calculationRow.tsx
│ │ │ │ └── tableCalculationOptions.tsx
│ │ │ ├── horizontalGrip.scss
│ │ │ ├── horizontalGrip.tsx
│ │ │ ├── table.scss
│ │ │ ├── table.test.tsx
│ │ │ ├── table.tsx
│ │ │ ├── tableColumnResizeContext.tsx
│ │ │ ├── tableGroup.tsx
│ │ │ ├── tableGroupHeaderRow.test.tsx
│ │ │ ├── tableGroupHeaderRow.tsx
│ │ │ ├── tableHeader.test.tsx
│ │ │ ├── tableHeader.tsx
│ │ │ ├── tableHeaderMenu.test.tsx
│ │ │ ├── tableHeaderMenu.tsx
│ │ │ ├── tableHeaders.test.tsx
│ │ │ ├── tableHeaders.tsx
│ │ │ ├── tableRow.scss
│ │ │ ├── tableRow.test.tsx
│ │ │ ├── tableRow.tsx
│ │ │ ├── tableRows.test.tsx
│ │ │ └── tableRows.tsx
│ │ ├── topBar.scss
│ │ ├── topBar.test.tsx
│ │ ├── topBar.tsx
│ │ ├── tutorial_tour_tip
│ │ │ ├── hooks.ts
│ │ │ ├── tutorial_tour_tip.scss
│ │ │ ├── tutorial_tour_tip.tsx
│ │ │ ├── tutorial_tour_tip_backdrop.tsx
│ │ │ ├── tutorial_tour_tip_manager.tsx
│ │ │ └── useElementAvailable.ts
│ │ ├── viewHeader
│ │ │ ├── __snapshots__
│ │ │ │ ├── dateFilter.test.tsx.snap
│ │ │ │ ├── emptyCardButton.test.tsx.snap
│ │ │ │ ├── filterComponent.test.tsx.snap
│ │ │ │ ├── filterEntry.test.tsx.snap
│ │ │ │ ├── filterValue.test.tsx.snap
│ │ │ │ ├── newCardButton.test.tsx.snap
│ │ │ │ ├── newCardButtonTemplateItem.test.tsx.snap
│ │ │ │ ├── viewHeader.test.tsx.snap
│ │ │ │ ├── viewHeaderActionsMenu.test.tsx.snap
│ │ │ │ ├── viewHeaderGroupByMenu.test.tsx.snap
│ │ │ │ ├── viewHeaderPropertiesMenu.test.tsx.snap
│ │ │ │ ├── viewHeaderSearch.test.tsx.snap
│ │ │ │ └── viewHeaderSortMenu.test.tsx.snap
│ │ │ ├── dateFilter.scss
│ │ │ ├── dateFilter.test.tsx
│ │ │ ├── dateFilter.tsx
│ │ │ ├── emptyCardButton.test.tsx
│ │ │ ├── emptyCardButton.tsx
│ │ │ ├── filterComponent.scss
│ │ │ ├── filterComponent.test.tsx
│ │ │ ├── filterComponent.tsx
│ │ │ ├── filterEntry.scss
│ │ │ ├── filterEntry.test.tsx
│ │ │ ├── filterEntry.tsx
│ │ │ ├── filterValue.scss
│ │ │ ├── filterValue.test.tsx
│ │ │ ├── filterValue.tsx
│ │ │ ├── multiperson.scss
│ │ │ ├── multipersonFilterValue.tsx
│ │ │ ├── newCardButton.test.tsx
│ │ │ ├── newCardButton.tsx
│ │ │ ├── newCardButtonTemplateItem.test.tsx
│ │ │ ├── newCardButtonTemplateItem.tsx
│ │ │ ├── viewHeader.scss
│ │ │ ├── viewHeader.test.tsx
│ │ │ ├── viewHeader.tsx
│ │ │ ├── viewHeaderActionsMenu.test.tsx
│ │ │ ├── viewHeaderActionsMenu.tsx
│ │ │ ├── viewHeaderDisplayByMenu.tsx
│ │ │ ├── viewHeaderGroupByMenu.test.tsx
│ │ │ ├── viewHeaderGroupByMenu.tsx
│ │ │ ├── viewHeaderPropertiesMenu.test.tsx
│ │ │ ├── viewHeaderPropertiesMenu.tsx
│ │ │ ├── viewHeaderSearch.test.tsx
│ │ │ ├── viewHeaderSearch.tsx
│ │ │ ├── viewHeaderSortMenu.test.tsx
│ │ │ └── viewHeaderSortMenu.tsx
│ │ ├── viewMenu.scss
│ │ ├── viewMenu.test.tsx
│ │ ├── viewMenu.tsx
│ │ ├── viewTitle.scss
│ │ ├── viewTitle.test.tsx
│ │ ├── viewTitle.tsx
│ │ ├── withWebSockets.tsx
│ │ ├── workspace.scss
│ │ ├── workspace.test.tsx
│ │ └── workspace.tsx
│ ├── config
│ │ └── clientConfig.ts
│ ├── constants.ts
│ ├── csvExporter.ts
│ ├── emojiList.ts
│ ├── errors.ts
│ ├── file.ts
│ ├── fileIcons.ts
│ ├── fonts
│ │ └── metropolis
│ │ │ ├── Metropolis-Light.woff2
│ │ │ ├── Metropolis-LightItalic.woff2
│ │ │ ├── Metropolis-Regular.woff2
│ │ │ ├── Metropolis-RegularItalic.woff2
│ │ │ ├── Metropolis-SemiBold.woff2
│ │ │ └── Metropolis-SemiBoldItalic.woff2
│ ├── hooks
│ │ ├── permissions.tsx
│ │ ├── sortable.tsx
│ │ ├── useGetAllTemplates.ts
│ │ └── websockets.tsx
│ ├── i18n.tsx
│ ├── insights
│ │ └── index.ts
│ ├── main.tsx
│ ├── mutator.test.ts
│ ├── mutator.ts
│ ├── nativeApp.ts
│ ├── octoClient.test.ts
│ ├── octoClient.ts
│ ├── octoUtils.test.ts
│ ├── octoUtils.tsx
│ ├── onboardingTour
│ │ └── index.ts
│ ├── pages
│ │ ├── boardPage
│ │ │ ├── backwardCompatibilityQueryParamsRedirect.tsx
│ │ │ ├── boardPage.scss
│ │ │ ├── boardPage.tsx
│ │ │ ├── setWindowTitleAndIcon.tsx
│ │ │ ├── teamToBoardAndViewRedirect.tsx
│ │ │ ├── undoRedoHotKeys.tsx
│ │ │ └── websocketConnection.tsx
│ │ ├── changePasswordPage.scss
│ │ ├── changePasswordPage.tsx
│ │ ├── errorPage.scss
│ │ ├── errorPage.tsx
│ │ ├── loginPage.scss
│ │ ├── loginPage.tsx
│ │ ├── registerPage.scss
│ │ ├── registerPage.tsx
│ │ └── welcome
│ │ │ ├── __snapshots__
│ │ │ └── welcomePage.test.tsx.snap
│ │ │ ├── welcomePage.scss
│ │ │ ├── welcomePage.test.tsx
│ │ │ └── welcomePage.tsx
│ ├── properties
│ │ ├── baseTextEditor.tsx
│ │ ├── checkbox
│ │ │ ├── checkbox.tsx
│ │ │ └── property.tsx
│ │ ├── createdBy
│ │ │ ├── __snapshots__
│ │ │ │ └── createdBy.test.tsx.snap
│ │ │ ├── createdBy.test.tsx
│ │ │ ├── createdBy.tsx
│ │ │ └── property.tsx
│ │ ├── createdTime
│ │ │ ├── createdTime.scss
│ │ │ ├── createdTime.tsx
│ │ │ └── property.tsx
│ │ ├── date
│ │ │ ├── __snapshots__
│ │ │ │ └── date.test.tsx.snap
│ │ │ ├── date.scss
│ │ │ ├── date.test.tsx
│ │ │ ├── date.tsx
│ │ │ └── property.tsx
│ │ ├── email
│ │ │ ├── email.tsx
│ │ │ └── property.tsx
│ │ ├── index.tsx
│ │ ├── multiperson
│ │ │ ├── __snapshots__
│ │ │ │ └── multiperson.test.tsx.snap
│ │ │ ├── multiperson.test.tsx
│ │ │ ├── multiperson.tsx
│ │ │ └── property.tsx
│ │ ├── multiselect
│ │ │ ├── __snapshots__
│ │ │ │ └── multiselect.test.tsx.snap
│ │ │ ├── multiselect.test.tsx
│ │ │ ├── multiselect.tsx
│ │ │ └── property.tsx
│ │ ├── number
│ │ │ ├── __snapshots__
│ │ │ │ └── number.test.tsx.snap
│ │ │ ├── number.test.tsx
│ │ │ ├── number.tsx
│ │ │ └── property.tsx
│ │ ├── person
│ │ │ ├── __snapshots__
│ │ │ │ ├── confirmPerson.test.tsx.snap
│ │ │ │ └── person.test.tsx.snap
│ │ │ ├── confirmPerson.test.tsx
│ │ │ ├── confirmPerson.tsx
│ │ │ ├── person.test.tsx
│ │ │ ├── person.tsx
│ │ │ └── property.tsx
│ │ ├── phone
│ │ │ ├── phone.tsx
│ │ │ └── property.tsx
│ │ ├── select
│ │ │ ├── __snapshots__
│ │ │ │ └── select.test.tsx.snap
│ │ │ ├── property.tsx
│ │ │ ├── select.test.tsx
│ │ │ └── select.tsx
│ │ ├── text
│ │ │ ├── property.tsx
│ │ │ └── text.tsx
│ │ ├── types.tsx
│ │ ├── unknown
│ │ │ └── property.tsx
│ │ ├── updatedBy
│ │ │ ├── __snapshots__
│ │ │ │ └── updatedBy.test.tsx.snap
│ │ │ ├── property.tsx
│ │ │ ├── updatedBy.scss
│ │ │ ├── updatedBy.test.tsx
│ │ │ └── updatedBy.tsx
│ │ ├── updatedTime
│ │ │ ├── __snapshots__
│ │ │ │ └── updatedTime.test.tsx.snap
│ │ │ ├── property.tsx
│ │ │ ├── updatedTime.scss
│ │ │ ├── updatedTime.test.tsx
│ │ │ └── updatedTime.tsx
│ │ └── url
│ │ │ ├── __snapshots__
│ │ │ └── url.test.tsx.snap
│ │ │ ├── property.tsx
│ │ │ ├── url.scss
│ │ │ ├── url.test.tsx
│ │ │ └── url.tsx
│ ├── route.tsx
│ ├── router.tsx
│ ├── statistics
│ │ └── index.ts
│ ├── store
│ │ ├── attachments.ts
│ │ ├── boards.ts
│ │ ├── cards.ts
│ │ ├── channels.ts
│ │ ├── clientConfig.ts
│ │ ├── comments.ts
│ │ ├── contents.ts
│ │ ├── globalError.ts
│ │ ├── globalTemplates.ts
│ │ ├── hooks.ts
│ │ ├── index.ts
│ │ ├── initialLoad.ts
│ │ ├── language.ts
│ │ ├── limits.ts
│ │ ├── searchText.ts
│ │ ├── sidebar.ts
│ │ ├── teams.ts
│ │ ├── users.ts
│ │ └── views.ts
│ ├── styles
│ │ ├── _markdown.scss
│ │ ├── _modifiers.scss
│ │ ├── _typography.scss
│ │ ├── _z-index.scss
│ │ ├── focalboard-variables.scss
│ │ ├── labels.scss
│ │ ├── main.scss
│ │ ├── shared-variables.scss
│ │ └── variables.scss
│ ├── svg
│ │ ├── card-skeleton.tsx
│ │ ├── error-illustration.tsx
│ │ └── search-illustration.tsx
│ ├── telemetry
│ │ ├── telemetry.ts
│ │ ├── telemetryClient.test.ts
│ │ └── telemetryClient.ts
│ ├── test
│ │ ├── fetchMock.ts
│ │ └── testBlockFactory.ts
│ ├── testUtils.tsx
│ ├── theme.ts
│ ├── tsconfig.json
│ ├── types
│ │ ├── images.d.ts
│ │ └── index.d.ts
│ ├── undoManager.test.ts
│ ├── undomanager.ts
│ ├── user.tsx
│ ├── userSettings.ts
│ ├── utils.test.ts
│ ├── utils.ts
│ ├── widgets
│ │ ├── __snapshots__
│ │ │ ├── guestBadge.test.tsx.snap
│ │ │ └── propertyMenu.test.tsx.snap
│ │ ├── adminBadge
│ │ │ ├── __snapshots__
│ │ │ │ └── adminBadge.test.tsx.snap
│ │ │ ├── adminBadge.scss
│ │ │ ├── adminBadge.test.tsx
│ │ │ └── adminBadge.tsx
│ │ ├── buttons
│ │ │ ├── button.scss
│ │ │ ├── button.tsx
│ │ │ ├── buttonWithMenu.scss
│ │ │ ├── buttonWithMenu.tsx
│ │ │ ├── iconButton.scss
│ │ │ └── iconButton.tsx
│ │ ├── editable.scss
│ │ ├── editable.tsx
│ │ ├── editableArea.scss
│ │ ├── editableArea.tsx
│ │ ├── editableDayPicker.scss
│ │ ├── editableDayPicker.tsx
│ │ ├── emojiPicker.scss
│ │ ├── emojiPicker.tsx
│ │ ├── guestBadge.scss
│ │ ├── guestBadge.test.tsx
│ │ ├── guestBadge.tsx
│ │ ├── icons
│ │ │ ├── HandRight.tsx
│ │ │ ├── Link.tsx
│ │ │ ├── add.scss
│ │ │ ├── add.tsx
│ │ │ ├── alert.tsx
│ │ │ ├── apps.tsx
│ │ │ ├── board.scss
│ │ │ ├── board.tsx
│ │ │ ├── brokenFile.tsx
│ │ │ ├── calendar.scss
│ │ │ ├── calendar.tsx
│ │ │ ├── card.scss
│ │ │ ├── card.tsx
│ │ │ ├── check.scss
│ │ │ ├── check.tsx
│ │ │ ├── checkIcon.tsx
│ │ │ ├── chevronDown.tsx
│ │ │ ├── chevronRight.tsx
│ │ │ ├── chevronUp.tsx
│ │ │ ├── close.tsx
│ │ │ ├── closeCircle.tsx
│ │ │ ├── compassIcon.tsx
│ │ │ ├── delete.scss
│ │ │ ├── delete.tsx
│ │ │ ├── disclosureTriangle.scss
│ │ │ ├── disclosureTriangle.tsx
│ │ │ ├── divider.scss
│ │ │ ├── divider.tsx
│ │ │ ├── dot.scss
│ │ │ ├── dot.tsx
│ │ │ ├── dropdown.scss
│ │ │ ├── dropdown.tsx
│ │ │ ├── duplicate.scss
│ │ │ ├── duplicate.tsx
│ │ │ ├── edit.tsx
│ │ │ ├── emoji.scss
│ │ │ ├── emoji.tsx
│ │ │ ├── focalboard_logo.scss
│ │ │ ├── focalboard_logo.tsx
│ │ │ ├── folder.tsx
│ │ │ ├── gallery.scss
│ │ │ ├── gallery.tsx
│ │ │ ├── globe.tsx
│ │ │ ├── grip.scss
│ │ │ ├── grip.tsx
│ │ │ ├── hamburger.scss
│ │ │ ├── hamburger.tsx
│ │ │ ├── help.scss
│ │ │ ├── help.tsx
│ │ │ ├── hide.scss
│ │ │ ├── hide.tsx
│ │ │ ├── hideSidebar.scss
│ │ │ ├── hideSidebar.tsx
│ │ │ ├── image.scss
│ │ │ ├── image.tsx
│ │ │ ├── link.scss
│ │ │ ├── lockOutline.tsx
│ │ │ ├── logo.scss
│ │ │ ├── logo.tsx
│ │ │ ├── logoWithName.scss
│ │ │ ├── logoWithName.tsx
│ │ │ ├── logoWithNameWhite.scss
│ │ │ ├── logoWithNameWhite.tsx
│ │ │ ├── message.tsx
│ │ │ ├── newFolder.tsx
│ │ │ ├── options.scss
│ │ │ ├── options.tsx
│ │ │ ├── random.tsx
│ │ │ ├── search.tsx
│ │ │ ├── settings.scss
│ │ │ ├── settings.tsx
│ │ │ ├── show.scss
│ │ │ ├── show.tsx
│ │ │ ├── showSidebar.scss
│ │ │ ├── showSidebar.tsx
│ │ │ ├── sortDown.scss
│ │ │ ├── sortDown.tsx
│ │ │ ├── sortUp.scss
│ │ │ ├── sortUp.tsx
│ │ │ ├── submenuTriangle.scss
│ │ │ ├── submenuTriangle.tsx
│ │ │ ├── table.scss
│ │ │ ├── table.tsx
│ │ │ ├── text.scss
│ │ │ ├── text.tsx
│ │ │ └── update.tsx
│ │ ├── label.scss
│ │ ├── label.tsx
│ │ ├── menu
│ │ │ ├── colorOption.scss
│ │ │ ├── colorOption.tsx
│ │ │ ├── index.tsx
│ │ │ ├── labelOption.scss
│ │ │ ├── labelOption.tsx
│ │ │ ├── menu.scss
│ │ │ ├── menu.tsx
│ │ │ ├── menuItem.tsx
│ │ │ ├── menuUtil.ts
│ │ │ ├── separatorOption.scss
│ │ │ ├── separatorOption.tsx
│ │ │ ├── subMenuOption.scss
│ │ │ ├── subMenuOption.tsx
│ │ │ ├── switchOption.tsx
│ │ │ ├── textInputOption.tsx
│ │ │ └── textOption.tsx
│ │ ├── menuWrapper.scss
│ │ ├── menuWrapper.tsx
│ │ ├── notificationBox
│ │ │ ├── __snapshots__
│ │ │ │ └── notificationBox.test.tsx.snap
│ │ │ ├── notificationBox.scss
│ │ │ ├── notificationBox.test.tsx
│ │ │ └── notificationBox.tsx
│ │ ├── propertyMenu.scss
│ │ ├── propertyMenu.test.tsx
│ │ ├── propertyMenu.tsx
│ │ ├── switch.scss
│ │ ├── switch.tsx
│ │ ├── tooltip.scss
│ │ ├── tooltip.tsx
│ │ ├── valueSelector.scss
│ │ └── valueSelector.tsx
│ └── wsclient.ts
├── static
│ ├── addDescription.png
│ ├── addProperty.gif
│ ├── app-bar-icon.png
│ ├── boards-screenshots.png
│ ├── boards-welcome-small.png
│ ├── boards-welcome.png
│ ├── changeViews.gif
│ ├── comment.gif
│ ├── copyLink.gif
│ ├── emoji_spirit.png
│ ├── favicon.svg
│ ├── onboardingBg.jpg
│ ├── share.gif
│ └── upgrade.png
├── tsconfig.json
├── tslint.json
├── webpack.common.js
├── webpack.dev.js
├── webpack.editor.js
└── webpack.prod.js
├── website
├── .editorconfig
├── .gitignore
├── Makefile
├── README.md
└── site
│ ├── .hugo_build.lock
│ ├── archetypes
│ └── default.md
│ ├── config.toml
│ ├── content
│ ├── blog
│ │ ├── 2021-1-7-hello.md
│ │ ├── 2021-4-21-Focalboard v0.6.5 release.md
│ │ ├── 2021-4-27-Mattermost-Focalboard-early-preview.md
│ │ ├── 2021-5-07-meeting-agenda-template.md
│ │ ├── 2021-5-13-Focalboard-the-road-to-v1.md
│ │ └── 2021-6-18-Mattermost-Focalboard-release.md
│ ├── docs
│ │ └── personal-edition
│ │ │ ├── _index.md
│ │ │ ├── desktop.md
│ │ │ ├── docker.md
│ │ │ ├── ubuntu-upgrade.md
│ │ │ └── ubuntu.md
│ ├── download
│ │ └── index.html
│ ├── feedback
│ │ └── _index.md
│ ├── fwlink
│ │ ├── doc-boards.html
│ │ ├── feedback-boards.html
│ │ ├── feedback-focalboard.html
│ │ ├── plugin-setup.html
│ │ ├── setup-536.html
│ │ ├── v1-focalboard.html
│ │ └── websocket-connect-error.html
│ └── guide
│ │ ├── admin
│ │ └── _index.md
│ │ ├── server-setup
│ │ └── _index.md
│ │ ├── user
│ │ ├── _index.md
│ │ ├── add view.png
│ │ ├── all tasks.png
│ │ ├── board sidebar menu.png
│ │ ├── by status properties.png
│ │ ├── by status.png
│ │ ├── settings menu.png
│ │ ├── share board menu.png
│ │ ├── share board.png
│ │ └── table header menu.png
│ │ └── websocket-errors
│ │ └── _index.md
│ ├── layouts
│ ├── 404.html
│ ├── _default
│ │ ├── _markup
│ │ │ └── render-link.html
│ │ ├── list.html
│ │ ├── page.html
│ │ ├── single.html
│ │ └── taxonomy.html
│ ├── blog
│ │ ├── li.html
│ │ ├── list.html
│ │ ├── single.html
│ │ └── summary.html
│ ├── index.html
│ ├── indexes
│ │ └── tag.html
│ ├── partials
│ │ ├── blogauthor.html
│ │ ├── footer.html
│ │ ├── hanchor.html
│ │ ├── head.html
│ │ ├── hero.html
│ │ ├── intro.html
│ │ ├── mailinglist.html
│ │ ├── nav.html
│ │ ├── notification.html
│ │ ├── page-edit.html
│ │ ├── series_link.html
│ │ └── sidebar.html
│ └── shortcodes
│ │ ├── baseurl.html
│ │ ├── bignumber.html
│ │ ├── blogurl.html
│ │ ├── content.html
│ │ ├── md.html
│ │ └── note.html
│ ├── static
│ ├── css
│ │ ├── bar.css
│ │ ├── bootstrap.min.css
│ │ ├── code.css
│ │ ├── markdown.css
│ │ ├── note.css
│ │ ├── partials
│ │ │ ├── banners.css
│ │ │ ├── base.css
│ │ │ ├── blog.css
│ │ │ ├── buttons.css
│ │ │ ├── fontawesome.css
│ │ │ ├── footer.css
│ │ │ ├── header.css
│ │ │ ├── homepage.css
│ │ │ ├── root.css
│ │ │ ├── sidebar.css
│ │ │ └── template-picker.css
│ │ ├── styles.css
│ │ └── tabs.css
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ ├── img
│ │ ├── 3d-icons
│ │ │ ├── development.svg
│ │ │ ├── firstbump.svg
│ │ │ ├── gasp.svg
│ │ │ ├── handshake.svg
│ │ │ ├── raisedhands.svg
│ │ │ └── rocket.svg
│ │ ├── arrow-right.svg
│ │ ├── bgroundedcenter.svg
│ │ ├── bgroundedleft.svg
│ │ ├── bgroundedright.svg
│ │ ├── bullseye.svg
│ │ ├── check.svg
│ │ ├── contribute-icon.svg
│ │ ├── developers-icon.svg
│ │ ├── download-icon.svg
│ │ ├── extend-icon.svg
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── footer-logo-black.svg
│ │ ├── footer-logo.svg
│ │ ├── hero.jpg
│ │ ├── integrate-icon.svg
│ │ ├── logo-w-mattermost.svg
│ │ ├── logo-white.svg
│ │ ├── logo.svg
│ │ ├── mac-app-store-white.svg
│ │ ├── mac-app-store.svg
│ │ ├── mentioned
│ │ │ ├── newstack.png
│ │ │ ├── producthunt.png
│ │ │ ├── techrepublic.png
│ │ │ ├── venturebeat.png
│ │ │ └── ycombinator.png
│ │ ├── mm-logo-white.svg
│ │ ├── mm-logo.svg
│ │ ├── ms-app-store.svg
│ │ ├── needhelp.svg
│ │ ├── roadmap
│ │ │ ├── analytics.png
│ │ │ ├── card-dependencies.png
│ │ │ └── standard-properties.png
│ │ ├── search-icon.svg
│ │ ├── single-users-icon.svg
│ │ ├── tabs
│ │ │ └── boards.png
│ │ ├── teams-icon.svg
│ │ ├── teams
│ │ │ ├── aig.svg
│ │ │ ├── nasa.svg
│ │ │ ├── nasdaq.svg
│ │ │ ├── qualcom.svg
│ │ │ └── samsung.svg
│ │ ├── templates
│ │ │ ├── company-goals.png
│ │ │ ├── content-calendar.png
│ │ │ ├── meeting-agenda.png
│ │ │ ├── project-tasks.png
│ │ │ ├── roadmap.png
│ │ │ └── welcome.png
│ │ ├── use-icon.svg
│ │ └── views
│ │ │ ├── boardview.png
│ │ │ ├── calendarview.png
│ │ │ ├── galleryview.png
│ │ │ └── listview.png
│ ├── js
│ │ ├── main.js
│ │ └── tabs.js
│ ├── lottie
│ │ └── intro-section.json
│ ├── robots.txt
│ └── video
│ │ ├── accelerate1.mp4
│ │ └── comment-animation.mp4
│ └── themes
│ ├── archetypes
│ └── default.md
│ ├── config.toml
│ ├── content
│ └── contribute
│ │ └── _index.md
│ └── layouts
│ ├── 404.html
│ ├── _default
│ ├── list.html
│ └── single.html
│ ├── index.html
│ └── partials
│ ├── about.html
│ ├── contact.html
│ ├── counters.html
│ ├── footer.html
│ ├── head.html
│ ├── hero.html
│ ├── intro.html
│ ├── js.html
│ ├── nav.html
│ ├── nav2.html
│ ├── services.html
│ ├── testimonials.html
│ └── work.html
└── win-wpf
├── .gitignore
├── AppxManifest.xml
├── Focalboard.sln
├── Focalboard
├── App.config
├── App.xaml
├── App.xaml.cs
├── Focalboard.csproj
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Utils.cs
├── Webview2Installer.cs
├── focalboard.ico
└── packages.config
├── README.md
├── art
├── StoreLogo.png
├── icon150.png
└── icon44.png
├── build.bat
├── package-zip.bat
└── package.bat
/.dockerignore:
--------------------------------------------------------------------------------
1 | CHANGELOG.md
2 | README.md
3 |
4 | node_modules
5 | .github/
6 | mac/
7 | win-wpf/
8 | website/
9 | linux/
10 | go.work
11 | go.work.sum
12 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org/
2 |
3 | root = true
4 |
5 | [*]
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 | charset = utf-8
10 |
11 | [*.go]
12 | indent_style = tab
13 |
14 | [*.{js,jsx,json,html}]
15 | indent_style = space
16 | indent_size = 4
17 |
18 | [{package.json,.eslintrc.json}]
19 | indent_size = 2
20 |
21 | [i18n/**.json]
22 | indent_size = 2
23 |
24 | [Makefile]
25 | indent_style = tab
26 |
27 | [*.scss]
28 | indent_style = space
29 | indent_size = 4
30 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | website/** linguist-documentation
2 | server/swagger/** linguist-generated
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/.github/CODEOWNERS
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Enhancement/Feature Idea
3 | about: Suggest a new capability
4 | title: 'Feature Idea: '
5 | labels: Enhancement, Triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## Summary
11 |
12 | What the new capability is.
13 |
14 | ## How important this is to me and why
15 |
16 | Importance: High/Medium/Low
17 |
18 | Use cases:
19 | 1.
20 | 2.
21 | 3.
22 |
23 | ## Additional context/similar features
24 |
25 | Any examples of good implementations of this capability.
26 |
--------------------------------------------------------------------------------
/.github/codeql/codeql-config.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL config"
2 |
3 | query-filters:
4 | - exclude:
5 | problem.severity:
6 | - warning
7 | - recommendation
8 | - exclude:
9 | id: go/log-injection
10 |
11 | paths-ignore:
12 | - 'server/swagger/**/*.html'
13 | - 'website/**/*.html'
14 | - '**/*_test.go'
15 | - 'webapp/cypress/**'
16 | - '**/*.test.*'
17 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - build
3 | - s3
4 |
5 | variables:
6 | BUILD: "yes"
7 | IMAGE_BUILDER: $CI_REGISTRY/mattermost/ci/images/builder:go-1.19.5-node-16.15.0-1
8 |
9 | include:
10 | - project: mattermost/ci/focalboard
11 | ref: main
12 | file: private.yml
13 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | mainConfiguration: https://github.com/mattermost/mattermost-gitpod-config
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "golang.go",
4 | "dbaeumer.vscode-eslint"
5 | ]
6 | }
--------------------------------------------------------------------------------
/app-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "serverRoot": "http://localhost:8088",
3 | "port": 8088,
4 | "dbtype": "sqlite3",
5 | "dbconfig": "./focalboard.db",
6 | "useSSL": false,
7 | "webpath": "./pack",
8 | "filespath": "./files",
9 | "telemetry": true,
10 | "localOnly": true
11 | }
12 |
--------------------------------------------------------------------------------
/docker-testing/docker-compose-mysql.yml:
--------------------------------------------------------------------------------
1 | version: '2.4'
2 | services:
3 | mysql:
4 | image: "mysql/mysql-server:8.0.32"
5 | restart: always
6 | environment:
7 | MYSQL_ROOT_HOST: "%"
8 | MYSQL_ROOT_PASSWORD: mostest
9 | MYSQL_PASSWORD: mostest
10 | MYSQL_USER: mmuser
11 | healthcheck:
12 | test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
13 | interval: 5s
14 | timeout: 10s
15 | retries: 3
16 | tmpfs: /var/lib/mysql
17 | ports:
18 | - 44446:3306
19 |
20 | start_dependencies:
21 | image: mattermost/mattermost-wait-for-dep:latest
22 | depends_on:
23 | - mysql
24 | command: mysql
25 |
26 |
--------------------------------------------------------------------------------
/docker-testing/docker-compose-postgres.yml:
--------------------------------------------------------------------------------
1 | version: '2.4'
2 | services:
3 | postgres:
4 | image: "postgres:10"
5 | restart: always
6 | environment:
7 | POSTGRES_USER: mmuser
8 | POSTGRES_PASSWORD: mostest
9 | healthcheck:
10 | test: [ "CMD", "pg_isready", "-h", "localhost" ]
11 | interval: 5s
12 | timeout: 10s
13 | retries: 3
14 | tmpfs: /var/lib/postgresql/data
15 | ports:
16 | - 44447:5432
17 |
18 | start_dependencies:
19 | image: mattermost/mattermost-wait-for-dep:latest
20 | depends_on:
21 | - postgres
22 | command: postgres:5432
23 |
24 |
--------------------------------------------------------------------------------
/docker/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "serverRoot": "http://localhost:8000",
3 | "port": 8000,
4 | "dbtype": "postgres",
5 | "dbconfig": "postgres://boardsuser:boardsuser-password@focalboard-db/boards?sslmode=disable&connect_timeout=10",
6 | "postgres_dbconfig": "dbname=boards sslmode=disable",
7 | "useSSL": false,
8 | "webpath": "./pack",
9 | "filespath": "./data/files",
10 | "telemetry": true,
11 | "prometheusaddress": ":9092",
12 | "session_expire_time": 2592000,
13 | "session_refresh_time": 18000,
14 | "localOnly": false,
15 | "enableLocalMode": true,
16 | "localModeSocketLocation": "/var/tmp/focalboard_local.socket"
17 | }
18 |
--------------------------------------------------------------------------------
/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | app:
4 | build:
5 | context: ../
6 | dockerfile: docker/Dockerfile
7 | container_name: focalboard
8 | volumes:
9 | - fbdata:/opt/focalboard/data
10 | ports:
11 | - 80:8000
12 | environment:
13 | - VIRTUAL_HOST=focalboard.local
14 | - VIRTUAL_PORT=8000
15 |
16 | volumes:
17 | fbdata:
--------------------------------------------------------------------------------
/docker/server_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "serverRoot": "http://localhost:8000",
3 | "port": 8000,
4 | "dbtype": "sqlite3",
5 | "dbconfig": "./data/focalboard.db",
6 | "postgres_dbconfig": "dbname=focalboard sslmode=disable",
7 | "useSSL": false,
8 | "webpath": "./pack",
9 | "filespath": "./data/files",
10 | "telemetry": true,
11 | "session_expire_time": 2592000,
12 | "session_refresh_time": 18000,
13 | "localOnly": false,
14 | "enableLocalMode": true,
15 | "localModeSocketLocation": "/var/tmp/focalboard_local.socket"
16 | }
17 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | title: Focalboard Developers
2 | google_analytics: UA-64458817-2
3 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/docs/manage-plugin-preferences.md:
--------------------------------------------------------------------------------
1 | # Manage plugin preferences
2 |
3 | ## Disable emojis on cards
4 |
5 | You can enable or disable random emoji icons for your board and cards by selecting the Gear icon next to your profile picture, then toggling **Random icons on or off**.
6 |
--------------------------------------------------------------------------------
/experiments/webext/.gitignore:
--------------------------------------------------------------------------------
1 | .parcel-cache
2 | web-ext-artifacts
3 |
--------------------------------------------------------------------------------
/experiments/webext/.parcelrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@parcel/config-webextension"
3 | }
4 |
--------------------------------------------------------------------------------
/experiments/webext/icons/19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/experiments/webext/icons/19.png
--------------------------------------------------------------------------------
/experiments/webext/icons/38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/experiments/webext/icons/38.png
--------------------------------------------------------------------------------
/experiments/webext/icons/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/experiments/webext/icons/48.png
--------------------------------------------------------------------------------
/experiments/webext/icons/96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/experiments/webext/icons/96.png
--------------------------------------------------------------------------------
/experiments/webext/src/utils/Board.ts:
--------------------------------------------------------------------------------
1 | interface BoardFields {
2 | isTemplate: boolean
3 | }
4 |
5 | export default interface Board {
6 | id: string
7 | title: string
8 | fields: BoardFields
9 | }
10 |
--------------------------------------------------------------------------------
/experiments/webext/src/views/PopupApp.scss:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2021-present Mattermost, Inc. All Rights Reserved. */
2 | /* See LICENSE.txt for license information. */
3 |
4 | .PopupApp {
5 | .status {
6 | .in-progress {
7 | background-color: grey;
8 | padding: 1em;
9 | }
10 |
11 | .success {
12 | background-color: lightgreen;
13 | padding: 1em;
14 | }
15 |
16 | .error {
17 | background-color: lightpink;
18 | padding: 1em;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/experiments/webext/src/views/options.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/experiments/webext/src/views/options.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from "react"
5 | import ReactDOM from "react-dom"
6 |
7 | import OptionsApp from "./OptionsApp"
8 |
9 | const app = document.getElementById("app")
10 | ReactDOM.render( , app)
11 |
--------------------------------------------------------------------------------
/experiments/webext/src/views/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/experiments/webext/src/views/popup.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2021-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from "react"
5 | import ReactDOM from "react-dom"
6 |
7 | import PopupApp from "./PopupApp"
8 |
9 | const app = document.getElementById("app")
10 | ReactDOM.render( , app)
11 |
--------------------------------------------------------------------------------
/experiments/webext/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/README.md:
--------------------------------------------------------------------------------
1 | # Import scripts
2 |
3 | This subfolder contains scripts to import data from other systems. It is at an early stage. At present, there are examples of basic importing from the following:
4 | * Trello
5 | * Asana
6 | * Notion
7 | * Jira
8 | * Todoist
9 | * Nextcloud Deck
10 |
11 | [Contribute code](https://mattermost.github.io/focalboard/) to expand this.
12 |
--------------------------------------------------------------------------------
/import/asana/.gitignore:
--------------------------------------------------------------------------------
1 | test
2 |
3 |
--------------------------------------------------------------------------------
/import/asana/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/asana/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import * as crypto from 'crypto'
4 |
5 | class Utils {
6 | static createGuid(): string {
7 | function randomDigit() {
8 | if (crypto && crypto.randomBytes) {
9 | const rands = crypto.randomBytes(1)
10 | return (rands[0] % 16).toString(16)
11 | }
12 |
13 | return (Math.floor((Math.random() * 16))).toString(16)
14 | }
15 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
16 | }
17 | }
18 |
19 | export { Utils }
20 |
--------------------------------------------------------------------------------
/import/jira/.gitignore:
--------------------------------------------------------------------------------
1 | test
--------------------------------------------------------------------------------
/import/jira/importJira.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import minimist from 'minimist'
5 | import {run} from './jiraImporter'
6 |
7 | async function main() {
8 | const args: minimist.ParsedArgs = minimist(process.argv.slice(2))
9 |
10 | const inputFile = args['i']
11 | const outputFile = args['o'] || 'archive.boardarchive'
12 |
13 | return run(inputFile, outputFile)
14 | }
15 |
16 | main()
17 |
--------------------------------------------------------------------------------
/import/jira/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/jira/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import * as crypto from 'crypto'
4 |
5 | class Utils {
6 | static createGuid(): string {
7 | function randomDigit() {
8 | if (crypto && crypto.randomBytes) {
9 | const rands = crypto.randomBytes(1)
10 | return (rands[0] % 16).toString(16)
11 | }
12 |
13 | return (Math.floor((Math.random() * 16))).toString(16)
14 | }
15 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
16 | }
17 | }
18 |
19 | export { Utils }
20 |
--------------------------------------------------------------------------------
/import/nextcloud-deck/.gitignore:
--------------------------------------------------------------------------------
1 | test
2 | output.focalboard
3 |
--------------------------------------------------------------------------------
/import/nextcloud-deck/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/nextcloud-deck/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import * as crypto from 'crypto'
4 |
5 | class Utils {
6 | static createGuid(): string {
7 | function randomDigit() {
8 | if (crypto && crypto.randomBytes) {
9 | const rands = crypto.randomBytes(1)
10 | return (rands[0] % 16).toString(16)
11 | }
12 |
13 | return (Math.floor((Math.random() * 16))).toString(16)
14 | }
15 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
16 | }
17 | }
18 |
19 | export { Utils }
20 |
--------------------------------------------------------------------------------
/import/notion/.gitignore:
--------------------------------------------------------------------------------
1 | test
2 |
--------------------------------------------------------------------------------
/import/notion/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/notion/utils.ts:
--------------------------------------------------------------------------------
1 | import * as crypto from 'crypto'
2 |
3 | class Utils {
4 | static createGuid(): string {
5 | function randomDigit() {
6 | if (crypto && crypto.randomBytes) {
7 | const rands = crypto.randomBytes(1)
8 | return (rands[0] % 16).toString(16)
9 | }
10 |
11 | return (Math.floor((Math.random() * 16))).toString(16)
12 | }
13 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
14 | }
15 | }
16 |
17 | export { Utils }
18 |
--------------------------------------------------------------------------------
/import/todoist/.gitignore:
--------------------------------------------------------------------------------
1 | test
2 |
--------------------------------------------------------------------------------
/import/todoist/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/todoist/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import * as crypto from 'crypto'
4 |
5 | class Utils {
6 | static createGuid(): string {
7 | function randomDigit() {
8 | if (crypto && crypto.randomBytes) {
9 | const rands = crypto.randomBytes(1)
10 | return (rands[0] % 16).toString(16)
11 | }
12 |
13 | return (Math.floor((Math.random() * 16))).toString(16)
14 | }
15 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
16 | }
17 | }
18 |
19 | export { Utils }
20 |
--------------------------------------------------------------------------------
/import/trello/.gitignore:
--------------------------------------------------------------------------------
1 | test
--------------------------------------------------------------------------------
/import/trello/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2019",
5 | "module": "commonjs",
6 | "esModuleInterop": true,
7 | "noImplicitAny": true,
8 | "strict": true,
9 | "strictNullChecks": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "sourceMap": true,
12 | "allowJs": true,
13 | "resolveJsonModule": true,
14 | "incremental": false,
15 | "outDir": "./dist",
16 | "moduleResolution": "node"
17 | },
18 | "include": [
19 | "."
20 | ],
21 | "exclude": [
22 | ".git",
23 | "**/node_modules/*",
24 | "dist",
25 | "pack"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/import/trello/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import * as crypto from 'crypto'
4 |
5 | class Utils {
6 | static createGuid(): string {
7 | function randomDigit() {
8 | if (crypto && crypto.randomBytes) {
9 | const rands = crypto.randomBytes(1)
10 | return (rands[0] % 16).toString(16)
11 | }
12 |
13 | return (Math.floor((Math.random() * 16))).toString(16)
14 | }
15 | return 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/x/g, randomDigit)
16 | }
17 | }
18 |
19 | export { Utils }
20 |
--------------------------------------------------------------------------------
/linux/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: run
2 |
3 | run:
4 | go run -tags "json1 sqlite3" ./main.go
5 |
6 | build:
7 | mkdir -p bin
8 | go build -tags "json1 sqlite3" -o bin/focalboard-app
9 |
--------------------------------------------------------------------------------
/linux/config.json:
--------------------------------------------------------------------------------
1 | ../config.json
--------------------------------------------------------------------------------
/linux/pack:
--------------------------------------------------------------------------------
1 | ../webapp/pack
--------------------------------------------------------------------------------
/linux/webapp:
--------------------------------------------------------------------------------
1 | ../webapp
--------------------------------------------------------------------------------
/mac/Focalboard.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mac/Focalboard.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/mac/Focalboard.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mac/Focalboard.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/mac/Focalboard/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/mac/Focalboard/Assets.xcassets/AppIcon.appiconset/focalboard-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/mac/Focalboard/Assets.xcassets/AppIcon.appiconset/focalboard-1024.png
--------------------------------------------------------------------------------
/mac/Focalboard/Assets.xcassets/AppIcon.appiconset/focalboard-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/mac/Focalboard/Assets.xcassets/AppIcon.appiconset/focalboard-512.png
--------------------------------------------------------------------------------
/mac/Focalboard/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/mac/Focalboard/AutoSaveWindowController.swift:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import Cocoa
5 |
6 | class AutoSaveWindowController: NSWindowController {
7 |
8 | override func windowDidLoad() {
9 | super.windowDidLoad()
10 |
11 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
12 | self.windowFrameAutosaveName = NSWindow.FrameAutosaveName("AutoSaveWindow")
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/mac/Focalboard/Focalboard.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-write
8 |
9 | com.apple.security.network.client
10 |
11 | com.apple.security.network.server
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/mac/Focalboard/Inherit.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.inherit
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/mac/export.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | compileBitcode
6 |
7 | method
8 | development
9 | signingStyle
10 | automatic
11 | stripSwiftSymbols
12 |
13 | thinning
14 | <none>
15 |
16 |
17 |
--------------------------------------------------------------------------------
/modd-servertest.conf:
--------------------------------------------------------------------------------
1 | **/*.go {
2 | prep: cd server && go test -tags "$FOCALBOARD_BUILD_TAGS" -race -v ./...
3 | }
4 |
--------------------------------------------------------------------------------
/modd.conf:
--------------------------------------------------------------------------------
1 | **/*.go !**/*_test.go {
2 | prep: cd server && go build -tags "$FOCALBOARD_BUILD_TAGS" -o ../bin/focalboard-server ./main
3 | daemon +sigterm: ./bin/focalboard-server $FOCALBOARDSERVER_ARGS
4 | }
5 |
6 | {
7 | daemon: cd webapp && npm run watchdev
8 | }
9 |
--------------------------------------------------------------------------------
/noticegen/config.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: "Mattermost Focalboard"
4 | copyright: "©2015-present Mattermost,Inc. All Rights Reserved. See LICENSE for license information."
5 | description: "This document includes a list of open source components used in Mattermost Focalboard, including those that have been modified."
6 | search:
7 | - "server/go.mod"
8 | - "linux/go.mod"
9 | dependencies: []
10 | devDependencies: []
11 |
12 | ...
13 |
--------------------------------------------------------------------------------
/server-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "serverRoot": "http://localhost:8000",
3 | "port": 8000,
4 | "dbtype": "sqlite3",
5 | "dbconfig": "./focalboard.db",
6 | "postgres_dbconfig": "dbname=focalboard sslmode=disable",
7 | "useSSL": false,
8 | "webpath": "./pack",
9 | "filespath": "./files",
10 | "telemetry": true,
11 | "prometheusaddress": ":9092",
12 | "session_expire_time": 2592000,
13 | "session_refresh_time": 18000,
14 | "localOnly": false,
15 | "enableLocalMode": true,
16 | "localModeSocketLocation": "/var/tmp/focalboard_local.socket"
17 | }
18 |
--------------------------------------------------------------------------------
/server/admin-scripts/reset-password.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [[ $# < 2 ]] ; then
4 | echo 'reset-password.sh '
5 | exit 1
6 | fi
7 |
8 | curl --unix-socket /var/tmp/focalboard_local.socket http://localhost/api/v2/admin/users/$1/password -X POST -H 'Content-Type: application/json' -d '{ "password": "'$2'" }'
9 |
--------------------------------------------------------------------------------
/server/app/app_test.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/mattermost/focalboard/server/services/config"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestSetConfig(t *testing.T) {
11 | th, tearDown := SetupTestHelper(t)
12 | defer tearDown()
13 |
14 | t.Run("Test Update Config", func(t *testing.T) {
15 | require.False(t, th.App.config.EnablePublicSharedBoards)
16 | newConfiguration := config.Configuration{}
17 | newConfiguration.EnablePublicSharedBoards = true
18 | th.App.SetConfig(&newConfiguration)
19 |
20 | require.True(t, th.App.config.EnablePublicSharedBoards)
21 | })
22 | }
23 |
--------------------------------------------------------------------------------
/server/app/clientConfig.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "github.com/mattermost/focalboard/server/model"
5 | )
6 |
7 | func (a *App) GetClientConfig() *model.ClientConfig {
8 | return &model.ClientConfig{
9 | Telemetry: a.config.Telemetry,
10 | TelemetryID: a.config.TelemetryID,
11 | EnablePublicSharedBoards: a.config.EnablePublicSharedBoards,
12 | TeammateNameDisplay: a.config.TeammateNameDisplay,
13 | FeatureFlags: a.config.FeatureFlags,
14 | MaxFileSize: a.config.MaxFileSize,
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/server/app/compliance.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import "github.com/mattermost/focalboard/server/model"
4 |
5 | func (a *App) GetBoardsForCompliance(opts model.QueryBoardsForComplianceOptions) ([]*model.Board, bool, error) {
6 | return a.store.GetBoardsForCompliance(opts)
7 | }
8 |
9 | func (a *App) GetBoardsComplianceHistory(opts model.QueryBoardsComplianceHistoryOptions) ([]*model.BoardHistory, bool, error) {
10 | return a.store.GetBoardsComplianceHistory(opts)
11 | }
12 |
13 | func (a *App) GetBlocksComplianceHistory(opts model.QueryBlocksComplianceHistoryOptions) ([]*model.BlockHistory, bool, error) {
14 | return a.store.GetBlocksComplianceHistory(opts)
15 | }
16 |
--------------------------------------------------------------------------------
/server/app/permissions.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | mm_model "github.com/mattermost/mattermost/server/public/model"
5 | )
6 |
7 | func (a *App) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
8 | return a.permissions.HasPermissionToBoard(userID, boardID, permission)
9 | }
10 |
--------------------------------------------------------------------------------
/server/app/sharing.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "github.com/mattermost/focalboard/server/model"
5 | )
6 |
7 | func (a *App) GetSharing(boardID string) (*model.Sharing, error) {
8 | sharing, err := a.store.GetSharing(boardID)
9 | if err != nil {
10 | return nil, err
11 | }
12 | return sharing, nil
13 | }
14 |
15 | func (a *App) UpsertSharing(sharing model.Sharing) error {
16 | return a.store.UpsertSharing(sharing)
17 | }
18 |
--------------------------------------------------------------------------------
/server/app/statistics.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | package app
5 |
6 | func (a *App) GetUsedCardsCount() (int, error) {
7 | return a.store.GetUsedCardsCount()
8 | }
9 |
--------------------------------------------------------------------------------
/server/app/templates.boardarchive:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/app/templates.boardarchive
--------------------------------------------------------------------------------
/server/assets/assets.go:
--------------------------------------------------------------------------------
1 | package assets
2 |
3 | import (
4 | _ "embed"
5 | )
6 |
7 | // DefaultTemplatesArchive is an embedded archive file containing the default
8 | // templates to be imported to team 0.
9 | // This archive is generated with `make templates-archive`
10 | //
11 | //go:embed templates.boardarchive
12 | var DefaultTemplatesArchive []byte
13 |
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/bbn1888mprfrm5fjw9f1je9x3xo/76fwrj36hptg6dywka4k5mt3sph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/bbn1888mprfrm5fjw9f1je9x3xo/76fwrj36hptg6dywka4k5mt3sph.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/bgi1yqiis8t8xdqxgnet8ebutky/7b9xk9boj3fbqfm3umeaaizp8qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/bgi1yqiis8t8xdqxgnet8ebutky/7b9xk9boj3fbqfm3umeaaizp8qr.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/bgi1yqiis8t8xdqxgnet8ebutky/7tmfu5iqju3n1mdfwi5gru89qmw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/bgi1yqiis8t8xdqxgnet8ebutky/7tmfu5iqju3n1mdfwi5gru89qmw.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/brs9cdimfw7fodyi7erqt747rhc/7y5kr8x8ybpnwdykjfuz57rggrh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/brs9cdimfw7fodyi7erqt747rhc/7y5kr8x8ybpnwdykjfuz57rggrh.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/bui5izho7dtn77xg3thkiqprc9r/77pe9r4ckbin438ph3f18bpatua.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/bui5izho7dtn77xg3thkiqprc9r/77pe9r4ckbin438ph3f18bpatua.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/bui5izho7dtn77xg3thkiqprc9r/7pbp4qg415pbstc6enzeicnu3qh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/bui5izho7dtn77xg3thkiqprc9r/7pbp4qg415pbstc6enzeicnu3qh.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/74nt9eqzea3ydjjpgjtsxcjgrxc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/74nt9eqzea3ydjjpgjtsxcjgrxc.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/74uia99m9btr8peydw7oexn37tw.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/74uia99m9btr8peydw7oexn37tw.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/78jws5m1myf8pufewzkaa6i11sc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/78jws5m1myf8pufewzkaa6i11sc.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7d6hrtig3zt8f9cnbo1um5oxx3y.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7d6hrtig3zt8f9cnbo1um5oxx3y.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7dybb6t8fj3nrdft7nerhuf784y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7dybb6t8fj3nrdft7nerhuf784y.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7ek6wbpp19jfoujs1goh6kttbby.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7ek6wbpp19jfoujs1goh6kttbby.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7iw4rxx7jj7bypmdotd9z469cyh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7iw4rxx7jj7bypmdotd9z469cyh.png
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7knxbyuiedtdafcgmropgkrtybr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates-boardarchive/buixxjic3xjfkieees4iafdrznc/7knxbyuiedtdafcgmropgkrtybr.gif
--------------------------------------------------------------------------------
/server/assets/templates-boardarchive/version.json:
--------------------------------------------------------------------------------
1 | {"version":2,"date":1643788318636}
2 |
--------------------------------------------------------------------------------
/server/assets/templates.boardarchive:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/assets/templates.boardarchive
--------------------------------------------------------------------------------
/server/go.tools.mod:
--------------------------------------------------------------------------------
1 | module github.com/mattermost/focalboard/server
2 |
3 | go 1.19
4 |
5 | require github.com/golang/mock v1.6.0
6 |
7 | require (
8 | github.com/jteeuwen/go-bindata v3.0.7+incompatible // indirect
9 | golang.org/x/mod v0.4.2 // indirect
10 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
11 | golang.org/x/tools v0.1.1 // indirect
12 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
13 | )
14 |
--------------------------------------------------------------------------------
/server/model/board_statistics.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | package model
4 |
5 | // BoardsStatistics is the representation of the statistics for the Boards server
6 | // swagger:model
7 | type BoardsStatistics struct {
8 | // The maximum number of cards on the server
9 | // required: true
10 | Boards int `json:"board_count"`
11 |
12 | // The maximum number of cards on the server
13 | // required: true
14 | Cards int `json:"card_count"`
15 | }
16 |
--------------------------------------------------------------------------------
/server/model/database.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | const (
4 | SqliteDBType = "sqlite3"
5 | PostgresDBType = "postgres"
6 | MysqlDBType = "mysql"
7 | )
8 |
--------------------------------------------------------------------------------
/server/model/errorResponse.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | // ErrorResponse is an error response
4 | // swagger:model
5 | type ErrorResponse struct {
6 | // The error message
7 | // required: false
8 | Error string `json:"error"`
9 |
10 | // The error code
11 | // required: false
12 | ErrorCode int `json:"errorCode"`
13 | }
14 |
--------------------------------------------------------------------------------
/server/model/log_level.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import "github.com/mattermost/logr/v2"
4 |
5 | var LvlFBTelemetry = logr.Level{
6 | ID: 9000,
7 | Name: "telemetry",
8 | }
9 |
--------------------------------------------------------------------------------
/server/server/initHandlers.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | func (s *Server) initHandlers() {
4 | cfg := s.config
5 | s.api.MattermostAuth = cfg.AuthMode == MattermostAuthMod
6 | }
7 |
--------------------------------------------------------------------------------
/server/services/auth/email.go:
--------------------------------------------------------------------------------
1 | package auth
2 |
3 | import "regexp"
4 |
5 | var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
6 |
7 | // IsEmailValid checks if the email provided passes the required structure and length.
8 | func IsEmailValid(e string) bool {
9 | if len(e) < 3 || len(e) > 254 {
10 | return false
11 | }
12 | return emailRegex.MatchString(e)
13 | }
14 |
--------------------------------------------------------------------------------
/server/services/notify/notifymentions/app_api.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | package notifymentions
4 |
5 | import "github.com/mattermost/focalboard/server/model"
6 |
7 | type AppAPI interface {
8 | GetMemberForBoard(boardID, userID string) (*model.BoardMember, error)
9 | AddMemberToBoard(member *model.BoardMember) (*model.BoardMember, error)
10 | }
11 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000001_init.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000002_system_settings_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000002_system_settings_table.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}system_settings (
2 | id VARCHAR(100),
3 | value TEXT,
4 | PRIMARY KEY (id)
5 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
6 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000003_blocks_rootid.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000003_blocks_rootid.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "blocks" "root_id" "varchar(36)" ""}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000004_auth_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000005_blocks_modifiedby.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000005_blocks_modifiedby.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "blocks" "modified_by" "varchar(36)" ""}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000006_sharing_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000006_sharing_table.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}sharing (
2 | id VARCHAR(36),
3 | enabled BOOLEAN,
4 | token VARCHAR(100),
5 | modified_by VARCHAR(36),
6 | update_at BIGINT,
7 | PRIMARY KEY (id)
8 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
9 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000007_workspaces_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000007_workspaces_table.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}workspaces (
2 | id VARCHAR(36),
3 | signup_token VARCHAR(100) NOT NULL,
4 | settings {{if .postgres}}JSON{{else}}TEXT{{end}},
5 | modified_by VARCHAR(36),
6 | update_at BIGINT,
7 | PRIMARY KEY (id)
8 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
9 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000008_teams.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000008_teams.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "blocks" "workspace_id" "varchar(36)" ""}}
3 |
4 | {{ addColumnIfNeeded "sharing" "workspace_id" "varchar(36)" ""}}
5 |
6 | {{ addColumnIfNeeded "sessions" "auth_service" "varchar(20)" ""}}
7 |
8 | UPDATE {{.prefix}}blocks SET workspace_id = '0' WHERE workspace_id = '' OR workspace_id IS NULL;
9 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000009_blocks_history.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000010_blocks_created_by.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000010_blocks_created_by.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint) */ -}}
2 | {{ addColumnIfNeeded "blocks" "created_by" "varchar(36)" ""}}
3 | {{ addColumnIfNeeded "blocks_history" "created_by" "varchar(36)" ""}}
4 |
5 | UPDATE {{.prefix}}blocks SET created_by =
6 | COALESCE(NULLIF((select modified_by from {{.prefix}}blocks_history where {{.prefix}}blocks_history.id = {{.prefix}}blocks.id ORDER BY {{.prefix}}blocks_history.insert_at ASC limit 1), ''), 'system')
7 | WHERE created_by IS NULL;
8 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000011_match_collation.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000011_match_collation.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* All tables have collation fixed via code at startup so this migration is no longer needed. */ -}}
2 | {{- /* See https://github.com/mattermost/focalboard/pull/4002 */ -}}
3 |
4 | SELECT 1;
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000012_match_column_collation.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000013_millisecond_timestamps.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000014_add_not_null_constraint.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000014_add_not_null_constraint.up.sql:
--------------------------------------------------------------------------------
1 | UPDATE {{.prefix}}blocks SET created_by = 'system' where created_by IS NULL;
2 | UPDATE {{.prefix}}blocks SET modified_by = 'system' where modified_by IS NULL;
3 |
4 | {{if .mysql}}
5 | ALTER TABLE {{.prefix}}blocks MODIFY created_by varchar(36) NOT NULL;
6 | ALTER TABLE {{.prefix}}blocks MODIFY modified_by varchar(36) NOT NULL;
7 | {{end}}
8 |
9 | {{if .postgres}}
10 | ALTER TABLE {{.prefix}}blocks ALTER COLUMN created_by set NOT NULL;
11 | ALTER TABLE {{.prefix}}blocks ALTER COLUMN modified_by set NOT NULL;
12 | {{end}}
13 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000015_blocks_history_no_nulls.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000016_subscriptions_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000017_add_file_info.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000017_add_file_info.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}file_info (
2 | id varchar(26) NOT NULL,
3 | create_at BIGINT NOT NULL,
4 | delete_at BIGINT,
5 | name TEXT NOT NULL,
6 | extension VARCHAR(50) NOT NULL,
7 | size BIGINT NOT NULL,
8 | archived BOOLEAN
9 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
10 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000018_add_teams_and_boards.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000019_populate_categories.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000019_populate_categories.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}categories (
2 | id varchar(36) NOT NULL,
3 | name varchar(100) NOT NULL,
4 | user_id varchar(36) NOT NULL,
5 | team_id varchar(36) NOT NULL,
6 | channel_id varchar(36),
7 | create_at BIGINT,
8 | update_at BIGINT,
9 | delete_at BIGINT,
10 | PRIMARY KEY (id)
11 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
12 |
13 | {{- /* createIndexIfNeeded tableName columns */ -}}
14 | {{ createIndexIfNeeded "categories" "user_id, team_id" }}
15 |
16 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000020_populate_category_blocks.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000020_populate_category_blocks.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}category_boards (
2 | id varchar(36) NOT NULL,
3 | user_id varchar(36) NOT NULL,
4 | category_id varchar(36) NOT NULL,
5 | board_id VARCHAR(36) NOT NULL,
6 | create_at BIGINT,
7 | update_at BIGINT,
8 | delete_at BIGINT,
9 | PRIMARY KEY (id)
10 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
11 |
12 | {{- /* createIndexIfNeeded tableName columns */ -}}
13 | {{ createIndexIfNeeded "category_boards" "category_id" }}
14 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000021_create_boards_members_history.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000022_create_default_board_role.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000022_create_default_board_role.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "boards" "minimum_role" "varchar(36)" "NOT NULL DEFAULT ''"}}
3 | {{ addColumnIfNeeded "boards_history" "minimum_role" "varchar(36)" "NOT NULL DEFAULT ''"}}
4 |
5 | UPDATE {{.prefix}}boards SET minimum_role = 'editor' WHERE minimum_role IS NULL OR minimum_role='';
6 | UPDATE {{.prefix}}boards_history SET minimum_role = 'editor' WHERE minimum_role IS NULL OR minimum_role='';
7 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000023_persist_category_collapsed_state.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000023_persist_category_collapsed_state.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "categories" "collapsed" "boolean" "default false"}}
3 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000024_mark_existsing_categories_collapsed.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000024_mark_existsing_categories_collapsed.up.sql:
--------------------------------------------------------------------------------
1 | UPDATE {{.prefix}}categories SET collapsed = true;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000025_indexes_update.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000026_create_preferences_table.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000026_create_preferences_table.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS {{.prefix}}preferences
2 | (
3 | userid VARCHAR(36) NOT NULL,
4 | category VARCHAR(32) NOT NULL,
5 | name VARCHAR(32) NOT NULL,
6 | value TEXT NULL,
7 | PRIMARY KEY (userid, category, name)
8 | ) {{if .mysql}}DEFAULT CHARACTER SET utf8mb4{{end}};
9 |
10 | {{- /* createIndexIfNeeded tableName columns */ -}}
11 | {{ createIndexIfNeeded "preferences" "category" }}
12 | {{ createIndexIfNeeded "preferences" "name" }}
13 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000027_migrate_user_props_to_preferences.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000028_remove_template_channel_link.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000028_remove_template_channel_link.up.sql:
--------------------------------------------------------------------------------
1 | UPDATE {{.prefix}}boards SET channel_id = '' WHERE is_template;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000029_add_category_type_field.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000029_add_category_type_field.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "categories" "type" "varchar(64)" ""}}
3 |
4 | UPDATE {{.prefix}}categories SET type = 'custom' WHERE type IS NULL;
5 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000030_add_category_sort_order.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000030_add_category_sort_order.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "categories" "sort_order" "BIGINT" ""}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000031_add_category_boards_sort_order.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000031_add_category_boards_sort_order.up.sql:
--------------------------------------------------------------------------------
1 | {{- /* addColumnIfNeeded tableName columnName datatype constraint */ -}}
2 | {{ addColumnIfNeeded "category_boards" "sort_order" "BIGINT" ""}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000032_move_boards_category_to_end.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000033_remove_deleted_category_boards.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000033_remove_deleted_category_boards.up.sql:
--------------------------------------------------------------------------------
1 | DELETE FROM {{.prefix}}category_boards WHERE delete_at > 0;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000034_category_boards_remove_unused_delete_at_column.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000034_category_boards_remove_unused_delete_at_column.up.sql:
--------------------------------------------------------------------------------
1 | {{ if or .postgres .mysql }}
2 | {{ dropColumnIfNeeded "category_boards" "delete_at" }}
3 | {{end}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000035_add_hidden_board_column.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000035_add_hidden_board_column.up.sql:
--------------------------------------------------------------------------------
1 | {{ addColumnIfNeeded "category_boards" "hidden" "boolean" "" }}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000036_category_board_add_unique_constraint.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000037_hidden_boards_from_preferences.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000038_delete_hiddenBoardIDs_from_preferences.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000038_delete_hiddenBoardIDs_from_preferences.up.sql:
--------------------------------------------------------------------------------
1 | {{if .plugin}}
2 | DELETE FROM Preferences WHERE category = 'focalboard' AND name = 'hiddenBoardIDs';
3 | {{else}}
4 | DELETE FROM {{.prefix}}preferences WHERE category = 'focalboard' AND name = 'hiddenBoardIDs';
5 | {{end}}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000039_add_path_to_file_info.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000039_add_path_to_file_info.up.sql:
--------------------------------------------------------------------------------
1 | {{ addColumnIfNeeded "file_info" "path" "varchar(512)" "" }}
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000040_fix_fileinfo_soft_deletes.down.sql:
--------------------------------------------------------------------------------
1 | SELECT 1;
2 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrations/000040_fix_fileinfo_soft_deletes.up.sql:
--------------------------------------------------------------------------------
1 | {{if .plugin}}
2 | UPDATE FileInfo
3 | SET DeleteAt = 0
4 | WHERE CreatorId = 'boards'
5 | AND DeleteAt != 0;
6 | {{else}}
7 | SELECT 1;
8 | {{end}}
9 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test27MigrateUserPropsToPreferences.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO focalboard_users
2 | (id, username, props)
3 | VALUES
4 | ('user-id', 'johndoe', '{"focalboard_welcomePageViewed": true, "hiddenBoardIDs": ["board1", "board2"], "focalboard_tourCategory": "onboarding", "focalboard_onboardingTourStep": 1, "focalboard_onboardingTourStarted": false, "focalboard_version72MessageCanceled": true, "focalboard_lastWelcomeVersion": 7}');
5 |
6 | INSERT INTO focalboard_preferences
7 | (UserId, Category, Name, Value)
8 | VALUES
9 | ('user-id', 'focalboard', 'onboardingTourStarted', true);
10 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test28RemoveTemplateChannelLink.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO focalboard_boards
2 | (id, title, type, is_template, channel_id, team_id)
3 | VALUES
4 | ('board-id', 'Board', 'O', false, 'linked-channel', 'team-id'),
5 | ('template-id', 'Template', 'O', true, 'linked-channel', 'team-id');
6 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test33_with_no_deleted_data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO focalboard_category_boards
2 | (id, user_id, category_id, board_id, create_at, update_at, delete_at, sort_order)
3 | values
4 | ('id-1', 'user_id-1', 'category-id-1', 'board-id-1', 1672988834402, 1672988834402, 0, 0),
5 | ('id-2', 'user_id-1', 'category-id-2', 'board-id-1', 1672988834402, 1672988834402, 0, 0),
6 | ('id-3', 'user_id-2', 'category-id-3', 'board-id-2', 1672988834402, 1672988834402, 0, 0),
7 | ('id-4', 'user_id-2', 'category-id-3', 'board-id-4', 1672988834402, 1672988834402, 0, 0),
8 | ('id-5', 'user_id-3', 'category-id-4', 'board-id-3', 1672988834402, 1672988834402, 0, 0);
9 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test34_drop_delete_at_column.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE focalboard_category_boards DROP COLUMN delete_at;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test35_add_hidden_column.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE focalboard_category_boards ADD COLUMN hidden boolean;
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test36_add_unique_constraint.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/server/services/store/sqlstore/migrationstests/fixtures/test36_add_unique_constraint.sql
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test38_add_plugin_preferences.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO Preferences VALUES
2 | ('user-id-1', 'focalboard', 'hiddenBoardIDs', '["board-id-1"]'),
3 | ('user-id-2', 'focalboard', 'hiddenBoardIDs', '["board-id-3", "board-id-4"]'),
4 | ('user-id-3', 'lorem', 'lorem', ''),
5 | ('user-id-4', 'ipsum', 'ipsum', '');
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test38_add_standalone_preferences.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO focalboard_preferences VALUES
2 | ('user-id-1', 'focalboard', 'hiddenBoardIDs', '["board-id-1"]'),
3 | ('user-id-2', 'focalboard', 'hiddenBoardIDs', '["board-id-3", "board-id-4"]'),
4 | ('user-id-2', 'lorem', 'lorem', ''),
5 | ('user-id-2', 'ipsum', 'ipsum', '');
--------------------------------------------------------------------------------
/server/services/store/sqlstore/migrationstests/fixtures/test40FixFileinfoSoftDeletes.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO FileInfo
2 | (Id, CreatorId, CreateAt, UpdateAt, DeleteAt)
3 | VALUES
4 | ('fileinfo-1', 'user-id', 1, 1, 1000),
5 | ('fileinfo-2', 'user-id', 1, 1, 1000),
6 | ('fileinfo-3', 'user-id', 1, 1, 0),
7 | ('fileinfo-4', 'boards', 1, 1, 2000),
8 | ('fileinfo-5', 'boards', 1, 1, 2000),
9 | ('fileinfo-6', 'boards', 1, 1, 0);
10 |
--------------------------------------------------------------------------------
/server/services/store/sqlstore/sqlite.go:
--------------------------------------------------------------------------------
1 | //go:build sqlite3
2 |
3 | package sqlstore
4 |
5 | import _ "github.com/mattn/go-sqlite3" // sqlite driver
6 |
--------------------------------------------------------------------------------
/server/swagger/docs/html/.openapi-generator/VERSION:
--------------------------------------------------------------------------------
1 | 6.2.1
--------------------------------------------------------------------------------
/server/utils/debug.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "os"
5 | "strings"
6 | )
7 |
8 | // IsRunningUnitTests returns true if this instance of FocalBoard is running unit or integration tests.
9 | func IsRunningUnitTests() bool {
10 | testing := os.Getenv("FOCALBOARD_UNIT_TESTING")
11 | if testing == "" {
12 | return false
13 | }
14 |
15 | switch strings.ToLower(testing) {
16 | case "1", "t", "y", "true", "yes":
17 | return true
18 | }
19 | return false
20 | }
21 |
--------------------------------------------------------------------------------
/server/utils/links.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | package utils
5 |
6 | import "fmt"
7 |
8 | // MakeCardLink creates fully qualified card links based on card id and parents.
9 | func MakeCardLink(serverRoot string, teamID string, boardID string, cardID string) string {
10 | return fmt.Sprintf("%s/team/%s/%s/0/%s", serverRoot, teamID, boardID, cardID)
11 | }
12 |
13 | func MakeBoardLink(serverRoot string, teamID string, board string) string {
14 | return fmt.Sprintf("%s/team/%s/%s", serverRoot, teamID, board)
15 | }
16 |
--------------------------------------------------------------------------------
/server/utils/testUtils.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "github.com/stretchr/testify/mock"
4 |
5 | var Anything = mock.MatchedBy(func(interface{}) bool { return true })
6 |
--------------------------------------------------------------------------------
/webapp/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/webapp/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11
2 |
--------------------------------------------------------------------------------
/webapp/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore all js/ts files:
2 | *.ts
3 | *.tsx
4 | *.js
--------------------------------------------------------------------------------
/webapp/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 4
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/.stylelintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "stylelint-config-sass-guidelines",
3 | "rules": {
4 | "indentation": 4,
5 | "selector-class-pattern": "[a-zA-Z_-]+",
6 | "max-nesting-depth": 4,
7 | "selector-max-compound-selectors": 6,
8 | "selector-max-id": 1,
9 | "selector-no-qualifying-type": null,
10 | "order/properties-alphabetical-order": null,
11 | "declaration-block-no-duplicate-properties": true,
12 | "property-disallowed-list": ["z-index"]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/__mocks__/fileMock.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | module.exports = 'test-file-stub';
4 |
--------------------------------------------------------------------------------
/webapp/__mocks__/styleMock.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | module.exports = {};
4 |
--------------------------------------------------------------------------------
/webapp/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "chromeWebSecurity": false,
3 | "baseUrl": "http://localhost:8088",
4 | "testFiles": [
5 | "**/login*.ts",
6 | "**/create*.ts",
7 | "**/manage*.ts",
8 | "**/group*.ts",
9 | "**/card*.ts"
10 | ],
11 | "env": {
12 | "username": "test-user",
13 | "password": "test-password",
14 | "email": "test@mail.com"
15 | },
16 | "video": false,
17 | "viewportWidth": 1600,
18 | "viewportHeight": 1200
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/cypress/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "serverRoot": "http://localhost:8088",
3 | "port": 8088,
4 | "dbtype": "sqlite3",
5 | "dbconfig": "file::memory:?cache=shared&_busy_timeout=5000",
6 | "useSSL": false,
7 | "webpath": "../pack",
8 | "filespath": "../../files",
9 | "telemetry": false,
10 | "webhook_update": [],
11 | "session_expire_time": 2592000,
12 | "session_refresh_time": 18000
13 | }
14 |
--------------------------------------------------------------------------------
/webapp/cypress/support/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import '@testing-library/cypress/add-commands'
5 |
6 | import 'cypress-real-events/support'
7 |
8 | import './api_commands'
9 | import './ui_commands'
10 |
11 | import 'cypress-failed-log'
12 |
--------------------------------------------------------------------------------
/webapp/cypress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "noEmit": true,
5 | "types": [
6 | "cypress",
7 | "cypress-real-events",
8 | "@testing-library/cypress"
9 | ]
10 | },
11 | "include": [
12 | "**/*.ts"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/html-templates/deveditor.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/webapp/html-templates/page.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/webapp/i18n/ars.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/webapp/i18n/kab.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/webapp/i18n/lt.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/webapp/i18n/sl.json:
--------------------------------------------------------------------------------
1 | {
2 | "BoardComponent.add-a-group": "+ Dodaj skupino",
3 | "BoardComponent.delete": "Izbriši",
4 | "BoardComponent.hidden-columns": "Skriti stolpci",
5 | "BoardComponent.hide": "Skrij",
6 | "BoardComponent.new": "+ Novo",
7 | "BoardComponent.no-property": "Ni {property}",
8 | "BoardComponent.no-property-title": "Elementi s prazno lastnostjo {property} bodo šli sem. Tega stolpca ni mogoče odstraniti.",
9 | "BoardComponent.show": "Pokaži",
10 | "BoardPage.newVersion": "Na voljo je nova različica Boards, kliknite tukaj za ponovno nalaganje.",
11 | "BoardPage.syncFailed": "Plošča se lahko izbriše ali dostop prekliče."
12 | }
13 |
--------------------------------------------------------------------------------
/webapp/src/blockIcons.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {randomEmojiList} from './emojiList'
4 |
5 | class BlockIcons {
6 | static readonly shared = new BlockIcons()
7 |
8 | randomIcon(): string {
9 | const index = Math.floor(Math.random() * randomEmojiList.length)
10 | const icon = randomEmojiList[index]
11 | return icon
12 | }
13 | }
14 |
15 | export {BlockIcons}
16 |
--------------------------------------------------------------------------------
/webapp/src/blocks/checkboxBlock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {ContentBlock} from './contentBlock'
4 | import {Block, createBlock} from './block'
5 |
6 | type CheckboxBlock = ContentBlock & {
7 | type: 'checkbox'
8 | }
9 |
10 | function createCheckboxBlock(block?: Block): CheckboxBlock {
11 | return {
12 | ...createBlock(block),
13 | type: 'checkbox',
14 | }
15 | }
16 |
17 | export {CheckboxBlock, createCheckboxBlock}
18 |
--------------------------------------------------------------------------------
/webapp/src/blocks/commentBlock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {Block, createBlock} from './block'
4 |
5 | type CommentBlock = Block & {
6 | type: 'comment'
7 | }
8 |
9 | function createCommentBlock(block?: Block): CommentBlock {
10 | return {
11 | ...createBlock(block),
12 | type: 'comment',
13 | }
14 | }
15 |
16 | export {CommentBlock, createCommentBlock}
17 |
--------------------------------------------------------------------------------
/webapp/src/blocks/contentBlock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {Block, createBlock} from './block'
4 |
5 | type IContentBlockWithCords = {
6 | block: Block
7 | cords: {x: number, y?: number, z?: number}
8 | }
9 |
10 | type ContentBlock = Block
11 |
12 | const createContentBlock = createBlock
13 |
14 | export {ContentBlock, IContentBlockWithCords, createContentBlock}
15 |
--------------------------------------------------------------------------------
/webapp/src/blocks/dividerBlock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {Block, createBlock} from './block'
4 | import {ContentBlock} from './contentBlock'
5 |
6 | type DividerBlock = ContentBlock & {
7 | type: 'divider'
8 | }
9 |
10 | function createDividerBlock(block?: Block): DividerBlock {
11 | return {
12 | ...createBlock(block),
13 | type: 'divider',
14 | }
15 | }
16 |
17 | export {DividerBlock, createDividerBlock}
18 |
--------------------------------------------------------------------------------
/webapp/src/blocks/h1Block.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {ContentBlock} from './contentBlock'
4 | import {Block, createBlock} from './block'
5 |
6 | type H1Block = ContentBlock & {
7 | type: 'h1'
8 | }
9 |
10 | function createH1Block(block?: Block): H1Block {
11 | return {
12 | ...createBlock(block),
13 | type: 'h1',
14 | }
15 | }
16 |
17 | export {H1Block, createH1Block}
18 |
19 |
--------------------------------------------------------------------------------
/webapp/src/blocks/h2Block.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {ContentBlock} from './contentBlock'
4 | import {Block, createBlock} from './block'
5 |
6 | type H2Block = ContentBlock & {
7 | type: 'h2'
8 | }
9 |
10 | function createH2Block(block?: Block): H2Block {
11 | return {
12 | ...createBlock(block),
13 | type: 'h2',
14 | }
15 | }
16 |
17 | export {H2Block, createH2Block}
18 |
19 |
--------------------------------------------------------------------------------
/webapp/src/blocks/h3Block.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {ContentBlock} from './contentBlock'
4 | import {Block, createBlock} from './block'
5 |
6 | type H3Block = ContentBlock & {
7 | type: 'h3'
8 | }
9 |
10 | function createH3Block(block?: Block): H3Block {
11 | return {
12 | ...createBlock(block),
13 | type: 'h3',
14 | }
15 | }
16 |
17 | export {H3Block, createH3Block}
18 |
19 |
--------------------------------------------------------------------------------
/webapp/src/blocks/sharing.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | interface ISharing {
5 | id: string
6 | enabled: boolean
7 | token: string
8 | modifiedBy?: string
9 | updateAt?: number
10 | }
11 |
12 | export {ISharing}
13 |
--------------------------------------------------------------------------------
/webapp/src/blocks/team.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | interface ITeam {
4 | readonly id: string
5 | readonly title: string
6 | readonly signupToken: string
7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
8 | readonly settings: Readonly>
9 | readonly modifiedBy?: string
10 | readonly updateAt?: number
11 | }
12 |
13 | export {ITeam}
14 |
--------------------------------------------------------------------------------
/webapp/src/blocks/textBlock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {ContentBlock} from './contentBlock'
4 | import {Block, createBlock} from './block'
5 |
6 | type TextBlock = ContentBlock & {
7 | type: 'text'
8 | }
9 |
10 | function createTextBlock(block?: Block): TextBlock {
11 | return {
12 | ...createBlock(block),
13 | type: 'text',
14 | }
15 | }
16 |
17 | export {TextBlock, createTextBlock}
18 |
--------------------------------------------------------------------------------
/webapp/src/blocks/workspace.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | interface IWorkspace {
4 | readonly id: string
5 | readonly title: string
6 | readonly signupToken: string
7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
8 | readonly settings: Readonly>
9 | readonly modifiedBy?: string
10 | readonly updateAt?: number
11 | }
12 |
13 | export {IWorkspace}
14 |
--------------------------------------------------------------------------------
/webapp/src/boardCloudLimits/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export const LimitUnlimited = 0
5 |
6 | export interface BoardsCloudLimits {
7 | cards: number
8 | used_cards: number
9 | card_limit_timestamp: number
10 | views: number
11 | }
12 |
--------------------------------------------------------------------------------
/webapp/src/boardsCloudLimits/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export const LimitUnlimited = 0
5 |
6 | export interface BoardsCloudLimits {
7 | cards: number
8 | used_cards: number
9 | card_limit_timestamp: number
10 | views: number
11 | }
12 |
--------------------------------------------------------------------------------
/webapp/src/components/__snapshots__/rootPortal.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/RootPortal should match snapshot 1`] = `
4 |
7 |
8 |
9 | Testing Portal
10 |
11 |
12 |
13 | `;
14 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blockContent.scss:
--------------------------------------------------------------------------------
1 | .BlockContent {
2 | display: flex;
3 |
4 | &.over-up {
5 | border-top: 1px solid rgba(128, 192, 255, 0.4);
6 | }
7 |
8 | &.over-down {
9 | border-bottom: 1px solid rgba(128, 192, 255, 0.4);
10 | }
11 |
12 | &:hover {
13 | .action {
14 | opacity: 1;
15 |
16 | .AddIcon {
17 | opacity: 0.5;
18 | }
19 | }
20 | }
21 |
22 | .action {
23 | transition: opacity 0.3s;
24 | opacity: 0;
25 | margin: 5px;
26 | }
27 |
28 | .content {
29 | flex-grow: 1;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/attachment/attachment.scss:
--------------------------------------------------------------------------------
1 | .Attachment {
2 | display: none;
3 | }
4 |
5 | .AttachmentView {
6 | border: 1px solid #ccc;
7 | border-radius: 5px;
8 | padding: 10px;
9 | margin-bottom: 10px;
10 | }
11 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/checkbox/checkbox.scss:
--------------------------------------------------------------------------------
1 | .Checkbox {
2 | display: flex;
3 |
4 | .inputCheck {
5 | width: auto;
6 | }
7 |
8 | .inputText {
9 | outline: 0;
10 | flex-grow: 1;
11 | }
12 |
13 | }
14 |
15 | .CheckboxView {
16 | display: flex;
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/divider/__snapshots__/divider.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/blocksEditor/blocks/divider should match Display snapshot 1`] = `
4 |
5 |
8 |
9 | `;
10 |
11 | exports[`components/blocksEditor/blocks/divider should match Input snapshot 1`] = `
`;
12 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/divider/divider.scss:
--------------------------------------------------------------------------------
1 | .Divider {
2 | width: 100%;
3 | margin: 5px 0;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h1/__snapshots__/h1.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/blocksEditor/blocks/h1 should match Display snapshot 1`] = `
4 |
5 |
6 |
9 | test-value
10 |
11 |
12 |
13 | `;
14 |
15 | exports[`components/blocksEditor/blocks/h1 should match Input snapshot 1`] = `
16 |
17 |
22 |
23 | `;
24 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h1/h1.scss:
--------------------------------------------------------------------------------
1 | .H1 {
2 | font-size: 32px;
3 | font-weight: 700;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h2/__snapshots__/h2.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/blocksEditor/blocks/h2 should match Display snapshot 1`] = `
4 |
5 |
6 |
9 | test-value
10 |
11 |
12 |
13 | `;
14 |
15 | exports[`components/blocksEditor/blocks/h2 should match Input snapshot 1`] = `
16 |
17 |
22 |
23 | `;
24 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h2/h2.scss:
--------------------------------------------------------------------------------
1 | .H2 {
2 | font-size: 24px;
3 | font-weight: 700;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h3/__snapshots__/h3.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/blocksEditor/blocks/h3 should match Display snapshot 1`] = `
4 |
5 |
6 |
9 | test-value
10 |
11 |
12 |
13 | `;
14 |
15 | exports[`components/blocksEditor/blocks/h3 should match Input snapshot 1`] = `
16 |
17 |
22 |
23 | `;
24 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/h3/h3.scss:
--------------------------------------------------------------------------------
1 | .H3 {
2 | font-size: 18px;
3 | font-weight: 700;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/image/image.scss:
--------------------------------------------------------------------------------
1 | .Image {
2 | display: none;
3 | }
4 |
5 | .ImageView {
6 | max-width: 400px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/list-item/__snapshots__/list-item.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/blocksEditor/blocks/list-item should match Display snapshot 1`] = `
4 |
5 |
6 |
7 | test-value
8 |
9 |
10 |
11 | `;
12 |
13 | exports[`components/blocksEditor/blocks/list-item should match Input snapshot 1`] = `
14 |
25 | `;
26 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/list-item/list-item.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/components/blocksEditor/blocks/list-item/list-item.scss
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/quote/quote.scss:
--------------------------------------------------------------------------------
1 | .Editor .Quote input {
2 | width: calc(100% - 80px);
3 | }
4 |
5 | .Quote {
6 | width: 100%;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/text-dev/text.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/components/blocksEditor/blocks/text-dev/text.scss
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/text/text.scss:
--------------------------------------------------------------------------------
1 | .TextContent {
2 | width: 100%;
3 | border: 2px solid #2684ff;
4 | border-radius: 4px;
5 | padding: 10px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/blocks/video/video.scss:
--------------------------------------------------------------------------------
1 | .Video {
2 | display: none;
3 | }
4 |
5 | .VideoView {
6 | max-width: 400px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/components/blocksEditor/editor.scss:
--------------------------------------------------------------------------------
1 | .Editor {
2 | margin-left: 50px;
3 | color: rgb(var(--center-channel-color-rgb));
4 | background-color: rgb(var(--center-channel-bg-rgb));
5 |
6 | .RootInput {
7 | display: block;
8 | }
9 |
10 | &.with-content-type {
11 | .RootInput {
12 | display: none;
13 | }
14 | }
15 |
16 | input {
17 | width: 100%;
18 | border: 1px solid hsl(0, 0%, 80%);
19 | border-radius: 4px;
20 | padding: 3px 6px;
21 | outline: 0;
22 |
23 | &:focus {
24 | border: 2px solid #2684ff;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/webapp/src/components/boardTemplateSelector/boardTemplateSelectorPreview.scss:
--------------------------------------------------------------------------------
1 | .BoardTemplateSelectorPreview {
2 | position: relative;
3 | transform-origin: top left;
4 | transform: scale(0.8);
5 | width: 126%;
6 | height: 480px;
7 | border-radius: var(--modal-rad);
8 | pointer-events: none;
9 |
10 | .ButtonWithMenu {
11 | display: none;
12 | }
13 |
14 | .Kanban {
15 | overflow: hidden;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/components/cardActionsMenu/cardActionsMenuIcon.scss:
--------------------------------------------------------------------------------
1 | .CardActionsMenuIcon {
2 | border-radius: 3px;
3 | padding: 0;
4 | box-shadow: rgba(var(--center-channel-color-rgb), 0.1) 0 0 0 1px,
5 | rgba(var(--center-channel-color-rgb), 0.1) 0 2px 4px;
6 | height: 24px;
7 | width: 24px;
8 |
9 | &:hover {
10 | background: rgb(var(--center-channel-color-rgb), 0.1);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/webapp/src/components/cardActionsMenu/cardActionsMenuIcon.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import OptionsIcon from '../../widgets/icons/options'
7 | import IconButton from '../../widgets/buttons/iconButton'
8 |
9 | import './cardActionsMenuIcon.scss'
10 |
11 | const CardActionsMenuIcon = () => {
12 | return (
13 | }
16 | />
17 | )
18 | }
19 |
20 | export default CardActionsMenuIcon
21 |
--------------------------------------------------------------------------------
/webapp/src/components/cardBadges.scss:
--------------------------------------------------------------------------------
1 | .CardBadges {
2 | display: flex;
3 | align-items: center;
4 | margin-top: 4px;
5 | height: 24px;
6 |
7 | span {
8 | display: flex;
9 | align-items: center;
10 | margin-right: 4px;
11 |
12 | .Icon,
13 | .CompassIcon {
14 | color: rgba(var(--center-channel-color-rgb), 0.64);
15 | fill: currentColor;
16 | margin-right: 4px;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/src/components/cardLimitNotification.scss:
--------------------------------------------------------------------------------
1 | .NotifyAdminSuccessNotify {
2 | position: fixed;
3 | bottom: 173px;
4 | height: unset;
5 |
6 | .NotificationBox__icon {
7 | font-size: 24px;
8 |
9 | svg {
10 | stroke: var(--online-indicator);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/webapp/src/components/content/__snapshots__/contentElement.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/content/contentElement should match snapshot for checkbox type 1`] = `
4 |
22 | `;
23 |
--------------------------------------------------------------------------------
/webapp/src/components/content/__snapshots__/dividerElement.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/content/DividerElement should match snapshot 1`] = `
4 |
9 | `;
10 |
--------------------------------------------------------------------------------
/webapp/src/components/content/__snapshots__/textElement.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/content/TextElement return a textElement 1`] = `
4 |
18 | `;
19 |
--------------------------------------------------------------------------------
/webapp/src/components/content/archivedFile/__snapshots__/archivedFile.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/content/archivedFile should match snapshot 1`] = `
4 |
27 | `;
28 |
--------------------------------------------------------------------------------
/webapp/src/components/content/checkboxElement.scss:
--------------------------------------------------------------------------------
1 | .CheckboxElement {
2 | display: flex;
3 | align-items: center;
4 | min-height: 34px;
5 |
6 | input {
7 | margin-right: 10px;
8 | }
9 |
10 | .Editable {
11 | width: 100%;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/webapp/src/components/content/dividerElement.scss:
--------------------------------------------------------------------------------
1 | .DividerElement {
2 | padding-top: 16px;
3 | border-bottom: 1px solid rgba(var(--center-channel-color-rgb), 0.09);
4 | margin-bottom: 17px;
5 | flex-grow: 1;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/components/content/dividerElement.test.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 | import {render} from '@testing-library/react'
6 |
7 | import {wrapIntl} from '../../testUtils'
8 |
9 | import DividerElement from './dividerElement'
10 |
11 | describe('components/content/DividerElement', () => {
12 | test('should match snapshot', async () => {
13 | const component = wrapIntl( )
14 | const {container} = render(component)
15 | expect(container).toMatchSnapshot()
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/webapp/src/components/content/textElement.scss:
--------------------------------------------------------------------------------
1 | .TextElement {
2 | display: inline;
3 |
4 | .markdown-editor-error {
5 | background-color: rgba(210, 75, 78, 0.08);
6 | border: 1px solid var(--error-text);
7 | }
8 |
9 | .error-message {
10 | color: var(--dnd-indicator, rgba(210, 75, 78, 1));
11 | margin: 16px 0;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/webapp/src/components/globalHeader/globalHeaderSettingsMenu.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/components/globalHeader/globalHeaderSettingsMenu.scss
--------------------------------------------------------------------------------
/webapp/src/components/guestNoBoards.scss:
--------------------------------------------------------------------------------
1 | .GuestNoBoards {
2 | height: 100%;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 |
7 | > div {
8 | display: flex;
9 | align-items: center;
10 | flex-direction: column;
11 | justify-content: center;
12 | text-align: center;
13 | }
14 |
15 | .title {
16 | font-size: 52px;
17 | font-weight: 400;
18 | }
19 |
20 | .subtitle {
21 | font-size: 20px;
22 | margin: 16px 0;
23 | }
24 |
25 | svg {
26 | margin: 56px 0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/webapp/src/components/hiddenCardCount/hiddenCardCount.scss:
--------------------------------------------------------------------------------
1 | .HiddenCardCount {
2 | display: flex;
3 | height: 30px;
4 |
5 | &:hover {
6 | cursor: pointer;
7 | }
8 |
9 | .hidden-card-title {
10 | background: rgba(243, 192, 199, 0.2);
11 | color: #d24b4e;
12 | padding: 3px 6px;
13 | border-radius: 4px;
14 | text-transform: uppercase;
15 | font-weight: bold;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/components/kanban/__snapshots__/kanbanColumn.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`src/components/kanban/kanbanColumn should match snapshot 1`] = `
4 |
9 | `;
10 |
--------------------------------------------------------------------------------
/webapp/src/components/kanban/calculation/__snapshots__/kanbanOption.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/kanban/calculations/Option base case 1`] = `
4 |
5 |
8 |
9 | Count Unique Values
10 |
11 |
14 |
15 |
16 |
17 | `;
18 |
--------------------------------------------------------------------------------
/webapp/src/components/kanban/calculation/calculation.scss:
--------------------------------------------------------------------------------
1 | .KanbanCalculation {
2 | position: relative;
3 |
4 | button {
5 | cursor: pointer !important;
6 | height: 24px;
7 | padding: 0 6px;
8 | min-width: 24px;
9 |
10 | span {
11 | max-width: 35px;
12 | overflow: hidden;
13 | text-overflow: ellipsis;
14 | white-space: nowrap;
15 | }
16 |
17 | &:hover {
18 | background-color: rgba(var(--center-channel-color-rgb), 0.1);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/webapp/src/components/kanban/kanbanColumn.scss:
--------------------------------------------------------------------------------
1 | .octo-board-column {
2 | &.dragover {
3 | background-color: rgba(128, 192, 255, 0.15);
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/webapp/src/components/live-markdown-plugin/utils/findRangesWithRegex.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | const findRangesWithRegex = (text: string, regex: RegExp): number[][] => {
4 | const ranges: number[][] = []
5 | let matches
6 |
7 | do {
8 | matches = regex.exec(text)
9 | if (matches) {
10 | ranges.push([matches.index, (matches.index + matches[0].length) - 1])
11 | }
12 | } while (matches)
13 |
14 | return ranges
15 | }
16 |
17 | export default findRangesWithRegex
18 |
--------------------------------------------------------------------------------
/webapp/src/components/markdownEditorInput/entryComponent/entryComponent.scss:
--------------------------------------------------------------------------------
1 | .EntryComponent {
2 | display: flex;
3 | align-items: center;
4 | justify-content: space-between;
5 | width: 100%;
6 |
7 | .EntryComponent__left {
8 | display: flex;
9 | align-items: center;
10 | }
11 |
12 | .EntryComponent__hint {
13 | opacity: 0.56;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/components/modalWrapper.scss:
--------------------------------------------------------------------------------
1 | .ModalWrapper {
2 | position: relative;
3 | overflow: unset;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/components/modalWrapper.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import React from 'react'
4 | import './modalWrapper.scss'
5 |
6 | type Props = {
7 | children: React.ReactNode
8 | }
9 |
10 | const ModalWrapper = (props: Props) => {
11 | return (
12 |
13 | {props.children}
14 |
15 | )
16 | }
17 |
18 | export default React.memo(ModalWrapper)
19 |
--------------------------------------------------------------------------------
/webapp/src/components/newVersionBanner.scss:
--------------------------------------------------------------------------------
1 | .NewVersionBanner {
2 | background-color: var(--prop-blue);
3 | text-align: center;
4 | padding: 10px;
5 | }
6 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/addComments/add_comments.scss:
--------------------------------------------------------------------------------
1 | .AddCommentTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: 170px;
4 | top: 18px;
5 | }
6 |
7 | .tippy-arrow {
8 | top: -21px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | top: 24px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/addDescription/add_description.scss:
--------------------------------------------------------------------------------
1 | .AddDescriptionTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | top: -10px;
4 | left: calc(120px + 20%);
5 | }
6 |
7 | .tippy-arrow {
8 | left: 21px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | left: -21px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/addProperties/add_properties.scss:
--------------------------------------------------------------------------------
1 | .AddPropertiesTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: 100%;
4 | top: calc(50% - 6px);
5 | }
6 |
7 | .tippy-arrow {
8 | top: -21px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | top: 24px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/addView/add_view.scss:
--------------------------------------------------------------------------------
1 | .AddViewTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: 91%;
4 | top: 100%;
5 | }
6 |
7 | .tippy-arrow {
8 | left: 21px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | right: 22px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/copyLink/copy_link.scss:
--------------------------------------------------------------------------------
1 | .CopyLinkTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: calc(100% - 6px);
4 | top: 18px;
5 | }
6 |
7 | .tippy-arrow {
8 | top: 21px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | top: -24px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/manageCategories/manageCategories.scss:
--------------------------------------------------------------------------------
1 | .ManageCatergoies {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | margin-left: 14px;
4 | margin-top: 5px;
5 | }
6 |
7 | .tutorial-tour-tip__overlay {
8 | cursor: pointer;
9 | }
10 |
11 | .tutorial-tour-tip__footer {
12 | margin-top: 15px;
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/openCard/open_card.scss:
--------------------------------------------------------------------------------
1 | .OpenCardTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: 80%;
4 | top: calc(100% - 6px);
5 | }
6 |
7 | .tutorial-tour-tip__overlay {
8 | cursor: pointer;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/searchForBoards/searchForBoards.scss:
--------------------------------------------------------------------------------
1 | .SearchForBoards {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | margin-top: 10px;
4 | }
5 |
6 | .tutorial-tour-tip__overlay {
7 | cursor: pointer;
8 | }
9 |
10 | .tutorial-tour-tip__footer {
11 | margin-top: 15px;
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/shareBoard/shareBoard.scss:
--------------------------------------------------------------------------------
1 | .ShareBoardTourStep {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | left: calc(80% - 16px);
4 | top: 27px;
5 | }
6 |
7 | .tippy-arrow {
8 | left: -20px !important;
9 | }
10 |
11 | &.tippy-box.tutorial-tour-tip__box {
12 | right: -22px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/components/onboardingTour/sidebarCategories/sidebarCategories.scss:
--------------------------------------------------------------------------------
1 | .SidebarCategories {
2 | &.tutorial-tour-tip__pulsating-dot-ctr {
3 | margin-left: 135px;
4 | margin-top: -10px;
5 | }
6 |
7 | .tutorial-tour-tip__overlay {
8 | cursor: pointer;
9 | }
10 |
11 | .tutorial-tour-tip__footer {
12 | margin-top: 15px;
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/components/shareBoard/__snapshots__/shareBoardLoginButton.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`src/components/shareBoard/shareBoardLoginButton should match snapshot 1`] = `
4 |
5 |
8 |
13 |
14 | Login
15 |
16 |
17 |
18 |
19 | `;
20 |
--------------------------------------------------------------------------------
/webapp/src/components/shareBoard/shareBoardButton.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/components/shareBoard/shareBoardButton.scss
--------------------------------------------------------------------------------
/webapp/src/components/shareBoard/shareBoardLoginButton.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/components/shareBoard/shareBoardLoginButton.scss
--------------------------------------------------------------------------------
/webapp/src/components/sidebar/__snapshots__/deleteBoardDialog.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`components/sidebar/DeleteBoardDialog Cancel should not submit 1`] = `
4 |
7 | exists
8 |
9 | `;
10 |
11 | exports[`components/sidebar/DeleteBoardDialog Delete should submit 1`] = `
12 |
15 | deleted
16 |
17 | `;
18 |
--------------------------------------------------------------------------------
/webapp/src/components/sidebar/sidebarSettingsMenu.scss:
--------------------------------------------------------------------------------
1 | .SidebarSettingsMenu {
2 | .menu-entry {
3 | display: flex;
4 | cursor: pointer;
5 | flex-direction: row;
6 | padding: 0 16px 0 8px;
7 | height: 36px;
8 | align-items: center;
9 | padding-left: 20px;
10 | color: rgba(var(--sidebar-text-rgb), 0.64);
11 | font-weight: 400;
12 |
13 | &:hover {
14 | background-color: rgba(var(--sidebar-text-rgb), 0.08);
15 | display: flex;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/webapp/src/components/table/horizontalGrip.scss:
--------------------------------------------------------------------------------
1 | .HorizontalGrip {
2 | width: 5px;
3 | cursor: ew-resize;
4 | flex-shrink: 0;
5 |
6 | &:hover {
7 | background-color: rgba(90, 192, 255, 0.7);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/webapp/src/components/viewHeader/filterComponent.scss:
--------------------------------------------------------------------------------
1 | .FilterComponent {
2 | min-width: 430px;
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/src/components/viewHeader/filterEntry.scss:
--------------------------------------------------------------------------------
1 | .FilterEntry {
2 | display: flex;
3 | flex-direction: row;
4 |
5 | > div {
6 | display: flex;
7 | flex-direction: row;
8 | }
9 |
10 | .Button {
11 | overflow: hidden;
12 | max-width: 220px;
13 | text-overflow: ellipsis;
14 | white-space: normal;
15 | display: block;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/components/viewHeader/filterValue.scss:
--------------------------------------------------------------------------------
1 | .filterValue {
2 | .Menu {
3 | max-height: 400px;
4 | overflow-y: auto;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/components/viewMenu.scss:
--------------------------------------------------------------------------------
1 | .ViewMenu {
2 |
3 | margin-top: -200px;
4 |
5 | .view-list {
6 | max-height: 30vh;
7 | overflow-y: auto;
8 | height: auto;
9 | }
10 |
11 | .subMenu {
12 | height: 100%;
13 | overflow: visible;
14 | }
15 |
16 | @media (max-height: 370px) {
17 | margin-top: -230px;
18 |
19 | .subMenu {
20 | height: 50px;
21 | overflow-y: scroll;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/webapp/src/config/clientConfig.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export type ClientConfig = {
5 | telemetry: boolean
6 | telemetryid: string
7 | enablePublicSharedBoards: boolean
8 | featureFlags: Record
9 | teammateNameDisplay: string
10 | maxFileSize: number
11 | }
12 |
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-Light.woff2
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-LightItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-LightItalic.woff2
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-Regular.woff2
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-RegularItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-RegularItalic.woff2
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-SemiBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-SemiBold.woff2
--------------------------------------------------------------------------------
/webapp/src/fonts/metropolis/Metropolis-SemiBoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/fonts/metropolis/Metropolis-SemiBoldItalic.woff2
--------------------------------------------------------------------------------
/webapp/src/insights/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export type TopBoard = {
5 | boardID: string
6 | icon: string
7 | title: string
8 | activityCount: number
9 | activeUsers: string
10 | createdBy: string
11 | }
12 |
13 | export type TopBoardResponse = {
14 | has_next: boolean
15 | items: TopBoard[]
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/onboardingTour/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export interface PrepareOnboardingResponse {
5 | teamID: string
6 | boardID: string
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/pages/errorPage.scss:
--------------------------------------------------------------------------------
1 | .ErrorPage {
2 | height: 100%;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 |
7 | > div {
8 | display: flex;
9 | align-items: center;
10 | flex-direction: column;
11 | justify-content: center;
12 | text-align: center;
13 | }
14 |
15 | .title {
16 | font-size: 52px;
17 | font-weight: 400;
18 | }
19 |
20 | .subtitle {
21 | font-size: 20px;
22 | margin: 16px 0;
23 | }
24 |
25 | svg {
26 | margin: 56px 0;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/webapp/src/properties/createdBy/createdBy.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import Person from '../person/person'
7 | import {PropertyProps} from '../types'
8 |
9 | const CreatedBy = (props: PropertyProps): JSX.Element => {
10 | return (
11 |
16 | )
17 | }
18 |
19 | export default CreatedBy
20 |
--------------------------------------------------------------------------------
/webapp/src/properties/createdTime/createdTime.scss:
--------------------------------------------------------------------------------
1 | .CreatedTime {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/properties/email/property.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {IntlShape} from 'react-intl'
4 |
5 | import {PropertyType, PropertyTypeEnum, FilterValueType} from '../types'
6 |
7 | import Email from './email'
8 |
9 | export default class EmailProperty extends PropertyType {
10 | Editor = Email
11 | name = 'Email'
12 | type = 'email' as PropertyTypeEnum
13 | displayName = (intl: IntlShape) => intl.formatMessage({id: 'PropertyType.Email', defaultMessage: 'Email'})
14 | canFilter = true
15 | filterValueType = 'text' as FilterValueType
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/properties/multiperson/multiperson.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import {PropertyProps} from '../types'
7 | import ConfirmPerson from '../person/confirmPerson'
8 |
9 | const MultiPerson = (props: PropertyProps): JSX.Element => {
10 | return (
11 |
15 | )
16 | }
17 |
18 | export default MultiPerson
19 |
--------------------------------------------------------------------------------
/webapp/src/properties/multiselect/__snapshots__/multiselect.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`properties/multiSelect shows only the selected options when menu is not opened 1`] = `
4 |
5 |
10 |
13 | a
14 |
15 |
18 | b
19 |
20 |
21 |
22 | `;
23 |
--------------------------------------------------------------------------------
/webapp/src/properties/number/__snapshots__/number.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`properties/number should match snapshot for number with empty value 1`] = `
4 |
5 |
12 |
13 | `;
14 |
--------------------------------------------------------------------------------
/webapp/src/properties/number/number.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import {PropertyProps} from '../types'
7 | import BaseTextEditor from '../baseTextEditor'
8 |
9 | const Number = (props: PropertyProps): JSX.Element => {
10 | return (
11 | props.propertyValue === '' || !isNaN(parseInt(props.propertyValue as string, 10))}
14 | />
15 | )
16 | }
17 | export default Number
18 |
--------------------------------------------------------------------------------
/webapp/src/properties/person/person.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import {PropertyProps} from '../types'
7 |
8 | import ConfirmPerson from './confirmPerson'
9 |
10 | const Person = (props: PropertyProps): JSX.Element => {
11 | return (
12 |
16 | )
17 | }
18 |
19 | export default Person
20 |
--------------------------------------------------------------------------------
/webapp/src/properties/phone/phone.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import {PropertyProps} from '../types'
7 | import BaseTextEditor from '../baseTextEditor'
8 |
9 | const Phone = (props: PropertyProps): JSX.Element => {
10 | return (
11 | true}
14 | />
15 | )
16 | }
17 | export default Phone
18 |
--------------------------------------------------------------------------------
/webapp/src/properties/phone/property.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {IntlShape} from 'react-intl'
4 |
5 | import {PropertyType, PropertyTypeEnum, FilterValueType} from '../types'
6 |
7 | import Phone from './phone'
8 |
9 | export default class PhoneProperty extends PropertyType {
10 | Editor = Phone
11 | name = 'Phone'
12 | type = 'phone' as PropertyTypeEnum
13 | displayName = (intl: IntlShape) => intl.formatMessage({id: 'PropertyType.Phone', defaultMessage: 'Phone'})
14 | canFilter = true
15 | filterValueType = 'text' as FilterValueType
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/properties/text/property.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {IntlShape} from 'react-intl'
4 |
5 | import {PropertyType, PropertyTypeEnum, FilterValueType} from '../types'
6 |
7 | import Text from './text'
8 |
9 | export default class TextProperty extends PropertyType {
10 | Editor = Text
11 | name = 'Text'
12 | type = 'text' as PropertyTypeEnum
13 | displayName = (intl: IntlShape) => intl.formatMessage({id: 'PropertyType.Text', defaultMessage: 'Text'})
14 | canFilter = true
15 | filterValueType = 'text' as FilterValueType
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/properties/text/text.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import {PropertyProps} from '../types'
7 | import BaseTextEditor from '../baseTextEditor'
8 |
9 | const Text = (props: PropertyProps): JSX.Element => {
10 | return (
11 | true}
14 | spellCheck={true}
15 | />
16 | )
17 | }
18 | export default Text
19 |
--------------------------------------------------------------------------------
/webapp/src/properties/unknown/property.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {IntlShape} from 'react-intl'
4 |
5 | import Text from '../text/text'
6 | import {PropertyType, PropertyTypeEnum} from '../types'
7 |
8 | export default class UnkownProperty extends PropertyType {
9 | Editor = Text
10 | name = 'Text'
11 | type = 'unknown' as PropertyTypeEnum
12 | displayName = (intl: IntlShape) => intl.formatMessage({id: 'PropertyType.Unknown', defaultMessage: 'Unknown'})
13 | }
14 |
--------------------------------------------------------------------------------
/webapp/src/properties/updatedBy/__snapshots__/updatedBy.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`properties/updatedBy should match snapshot 1`] = `
4 |
5 |
8 |
11 | username_1
12 |
13 |
14 |
15 | `;
16 |
--------------------------------------------------------------------------------
/webapp/src/properties/updatedBy/updatedBy.scss:
--------------------------------------------------------------------------------
1 | .LastModifiedBy {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/properties/updatedTime/__snapshots__/updatedTime.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`properties/updatedTime should match snapshot 1`] = `
4 |
5 |
8 | June 15, 2021 at 4:22 PM
9 |
10 |
11 | `;
12 |
--------------------------------------------------------------------------------
/webapp/src/properties/updatedTime/updatedTime.scss:
--------------------------------------------------------------------------------
1 | .UpdatedTime {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/properties/url/property.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import {IntlShape} from 'react-intl'
4 |
5 | import {PropertyType, PropertyTypeEnum, FilterValueType} from '../types'
6 |
7 | import Url from './url'
8 |
9 | export default class UrlProperty extends PropertyType {
10 | Editor = Url
11 | name = 'Url'
12 | type = 'url' as PropertyTypeEnum
13 | displayName = (intl: IntlShape) => intl.formatMessage({id: 'PropertyType.Url', defaultMessage: 'URL'})
14 | canFilter = true
15 | filterValueType = 'text' as FilterValueType
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/statistics/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export interface BoardSiteStatistics {
5 | board_count: number
6 | card_count: number
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/store/hooks.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import {TypedUseSelectorHook, useDispatch, useSelector} from 'react-redux'
5 |
6 | import type {RootState, AppDispatch} from '.'
7 |
8 | export const useAppDispatch = () => useDispatch()
9 | export const useAppSelector: TypedUseSelectorHook = useSelector
10 |
--------------------------------------------------------------------------------
/webapp/src/styles/_markdown.scss:
--------------------------------------------------------------------------------
1 | .markdown__table {
2 | margin: 5px 0 10px;
3 | background: var(--center-channel-bg);
4 | border-collapse: collapse;
5 |
6 | th,
7 | td {
8 | padding: 6px 13px;
9 | border: 1px solid #ddd;
10 | }
11 |
12 | a {
13 | white-space: nowrap;
14 | word-break: initial;
15 | }
16 |
17 | tbody tr {
18 | background: var(--center-channel-bg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/webapp/src/styles/shared-variables.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | --center-channel-bg-rgb: 255, 255, 255;
3 | --center-channel-color-rgb: 63, 67, 80;
4 | --sidebar-bg-rgb: 30, 50, 92;
5 | --sidebar-text-rgb: 255, 255, 255;
6 | --button-color-rgb: 255, 255, 255;
7 | --button-bg-rgb: 28, 88, 217;
8 | --button-danger-color-rgb: 255, 255, 255;
9 | --button-danger-bg-rgb: 210, 75, 78;
10 | --link-color-rgb: 56, 111, 229;
11 | --error-text-rgb: #d24b4e;
12 | }
13 |
--------------------------------------------------------------------------------
/webapp/src/styles/variables.scss:
--------------------------------------------------------------------------------
1 | @import './shared-variables';
2 | @import './focalboard-variables';
3 |
--------------------------------------------------------------------------------
/webapp/src/telemetry/telemetry.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export interface TelemetryHandler {
5 | trackEvent: (userId: string, userRoles: string, category: string, event: string, props?: any) => void
6 | pageVisited: (userId: string, userRoles: string, category: string, name: string) => void
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/test/fetchMock.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | class FetchMock {
5 | static fn = jest.fn(async () => {
6 | const response = new Response()
7 | return response
8 | })
9 |
10 | static async jsonResponse(json: string): Promise {
11 | const response = new Response(json)
12 | return response
13 | }
14 | }
15 |
16 | export {FetchMock}
17 |
--------------------------------------------------------------------------------
/webapp/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "*": [
7 | "../node_modules/*",
8 | "../@custom_types/*"
9 | ]
10 | }
11 | },
12 | "include": [
13 | "./**/*.ts",
14 | "./**/*.tsx"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/types/images.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | declare module '*.jpg';
5 | declare module '*.png';
6 | declare module '*.gif';
7 | declare module '*.apng';
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/__snapshots__/guestBadge.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`widgets/guestBadge should match the snapshot on show 1`] = `
4 |
15 | `;
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/adminBadge/__snapshots__/adminBadge.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`widgets/adminBadge should match the snapshot for Admin 1`] = `
4 |
15 | `;
16 |
17 | exports[`widgets/adminBadge should match the snapshot for TeamAdmin 1`] = `
18 |
19 |
22 |
25 | Team Admin
26 |
27 |
28 |
29 | `;
30 |
--------------------------------------------------------------------------------
/webapp/src/widgets/adminBadge/adminBadge.scss:
--------------------------------------------------------------------------------
1 | .AdminBadge {
2 | display: inline-flex;
3 | align-items: center;
4 | margin: 0 10px 0 4px;
5 | }
6 |
7 | .AdminBadge__box {
8 | padding: 2px 4px;
9 | border: 0;
10 | background: rgba(var(--center-channel-color-rgb), 0.16);
11 | border-radius: 2px;
12 | font-family: inherit;
13 | font-size: 10px;
14 | font-weight: 600;
15 | line-height: 14px;
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/widgets/editable.scss:
--------------------------------------------------------------------------------
1 | .Editable {
2 | cursor: text;
3 | overflow: hidden;
4 | text-overflow: ellipsis;
5 | border: 1px solid transparent;
6 | min-height: 24px;
7 |
8 | &.active {
9 | min-width: 100px;
10 | }
11 |
12 | &::placeholder {
13 | color: rgba(var(--center-channel-color-rgb), 0.4);
14 | opacity: 1;
15 | }
16 |
17 | &.error {
18 | border: 1px solid rgb(var(--error-text-rgb));
19 | border-radius: var(--default-rad);
20 | }
21 |
22 | &.readonly {
23 | background-color: transparent;
24 | flex: 1;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/webapp/src/widgets/editableArea.scss:
--------------------------------------------------------------------------------
1 | .EditableAreaWrap {
2 | width: 100%;
3 | }
4 |
5 | .EditableArea {
6 | resize: none;
7 | }
8 |
9 | .EditableAreaContainer {
10 | height: 0;
11 | overflow: hidden;
12 | }
13 |
14 | .EditableAreaReference {
15 | height: auto;
16 | width: 100%;
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/guestBadge.scss:
--------------------------------------------------------------------------------
1 | .GuestBadge {
2 | display: inline-flex;
3 | align-items: center;
4 | margin: 0 10px 0 4px;
5 | }
6 |
7 | .GuestBadge__box {
8 | padding: 2px 4px;
9 | border: 0;
10 | background: rgba(var(--center-channel-color-rgb), 0.16);
11 | border-radius: 2px;
12 | font-family: inherit;
13 | font-size: 10px;
14 | font-weight: 600;
15 | line-height: 14px;
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/HandRight.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function HandRight(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/Link.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './link.scss'
9 |
10 | export default function LinkIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/add.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/widgets/icons/add.scss
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/add.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './add.scss'
9 |
10 | export default function AddIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/alert.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function AlertIcon(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/apps.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function Apps(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/board.scss:
--------------------------------------------------------------------------------
1 | .BoardIcon {
2 | stroke-width: 8px;
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/brokenFile.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function BrokenFile(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/calendar.scss:
--------------------------------------------------------------------------------
1 | .CalendarIcon {
2 | stroke-width: 8px;
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/card.scss:
--------------------------------------------------------------------------------
1 | .CardIcon {
2 | stroke-width: 6px;
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/check.scss:
--------------------------------------------------------------------------------
1 | .CheckIcon {
2 | stroke: currentColor;
3 | stroke-width: 8px;
4 | fill: none;
5 | width: 1em;
6 | height: 1em;
7 | line-height: 1em;
8 | }
9 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/check.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './check.scss'
7 |
8 | export default function CheckIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/checkIcon.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | // TODO use this icon instead of check.tsx
9 | export default function Check(): JSX.Element {
10 | return (
11 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/chevronDown.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function ChevronDown(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/chevronRight.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function ChevronRight(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/chevronUp.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function ChevronUp(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/close.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function CloseIcon(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/closeCircle.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './add.scss'
9 |
10 | export default function CloseCircle(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/compassIcon.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | type Props = {
7 | icon: string
8 | className?: string
9 | }
10 |
11 | export default function CompassIcon(props: Props): JSX.Element {
12 | // All compass icon classes start with icon,
13 | // so not expecting that prefix in props.
14 | return (
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/delete.scss:
--------------------------------------------------------------------------------
1 | .DeleteIcon {
2 | fill: rgba(var(--center-channel-color-rgb), 0.5);
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/delete.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './delete.scss'
9 |
10 | export default function DeleteIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/disclosureTriangle.scss:
--------------------------------------------------------------------------------
1 | .DisclosureTriangleIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/disclosureTriangle.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './disclosureTriangle.scss'
7 |
8 | export default function DisclosureTriangle(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/divider.scss:
--------------------------------------------------------------------------------
1 | .DividerIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/dot.scss:
--------------------------------------------------------------------------------
1 | .DotIcon {
2 | fill: rgba(var(--center-channel-color-rgb), 0.5);
3 | width: 24px;
4 | height: 24px;
5 | }
6 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/dot.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './dot.scss'
7 |
8 | export default function DotIcon(): JSX.Element {
9 | return (
10 |
15 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/dropdown.scss:
--------------------------------------------------------------------------------
1 | .DropdownIcon {
2 | color: rgb(var(--center-channel-color-rgb));
3 | font-size: 16px;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/dropdown.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './dropdown.scss'
9 |
10 | export default function DropdownIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/duplicate.scss:
--------------------------------------------------------------------------------
1 | .DuplicateIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/duplicate.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './duplicate.scss'
9 |
10 | export default function DuplicateIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/edit.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function EditIcon(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/emoji.scss:
--------------------------------------------------------------------------------
1 | .EmojiIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/focalboard_logo.scss:
--------------------------------------------------------------------------------
1 | .FocalboardLogoIcon {
2 | width: 32px;
3 | height: 32px;
4 | fill: rgba(var(--sidebar-text-rgb), 0.7);
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/folder.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function Folder(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/gallery.scss:
--------------------------------------------------------------------------------
1 | .GalleryIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/globe.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function Globe(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/grip.scss:
--------------------------------------------------------------------------------
1 | .GripIcon {
2 | fill: rgb(var(--center-channel-color-rgb), 0.5);
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/hamburger.scss:
--------------------------------------------------------------------------------
1 | .HamburgerIcon {
2 | stroke: rgba(var(--center-channel-color-rgb), 0.5);
3 | stroke-width: 6px;
4 | fill: none;
5 | width: 24px;
6 | height: 24px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/hamburger.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './hamburger.scss'
7 |
8 | export default function HamburgerIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/help.scss:
--------------------------------------------------------------------------------
1 | .HelpIcon {
2 | color: rgba(var(--sidebar-text-rgb), 0.7);
3 | font-size: 16px;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/help.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import React from 'react'
4 |
5 | import CompassIcon from './compassIcon'
6 |
7 | import './help.scss'
8 |
9 | export default function HelpIcon(): JSX.Element {
10 | return (
11 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/hide.scss:
--------------------------------------------------------------------------------
1 | .HideIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/hideSidebar.scss:
--------------------------------------------------------------------------------
1 | .HideSidebarIcon {
2 | stroke: rgba(var(--center-channel-color-rgb), 0.5);
3 | stroke-width: 6px;
4 | fill: none;
5 | width: 24px;
6 | height: 24px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/hideSidebar.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './hideSidebar.scss'
7 |
8 | export default function HideSidebarIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/image.scss:
--------------------------------------------------------------------------------
1 | .ImageIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/link.scss:
--------------------------------------------------------------------------------
1 |
2 | .LinkIcon {
3 | color: rgba(var(--body-color), 0.5);
4 | font-size: 18px;
5 | width: 16px;
6 |
7 | &::before {
8 | margin: 0 !important;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/lockOutline.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function LockOutline(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/logo.scss:
--------------------------------------------------------------------------------
1 | .LogoIcon {
2 | font-size: 16px;
3 | color: rgba(var(--sidebar-text-rgb), 0.7);
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/logo.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './logo.scss'
7 | import CompassIcon from './compassIcon'
8 |
9 | export default function LogoIcon(): JSX.Element {
10 | return (
11 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/logoWithName.scss:
--------------------------------------------------------------------------------
1 | .LogoWithNameIcon {
2 | width: 150px;
3 | height: 32px;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/logoWithNameWhite.scss:
--------------------------------------------------------------------------------
1 | .LogoWithNameWhiteIcon {
2 | width: 150px;
3 | height: 32px;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/message.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function MessageIcon(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/newFolder.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function CreateNewFolder(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/options.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/widgets/icons/options.scss
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/options.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './options.scss'
9 |
10 | export default function OptionsIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/random.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function RandomIcon(): JSX.Element {
9 | return (
10 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/search.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function Search(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/settings.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/src/widgets/icons/settings.scss
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/settings.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | import './settings.scss'
9 |
10 | export default function SettingsIcon(): JSX.Element {
11 | return (
12 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/show.scss:
--------------------------------------------------------------------------------
1 | .ShowIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/showSidebar.scss:
--------------------------------------------------------------------------------
1 | .ShowSidebarIcon {
2 | stroke: rgba(var(--center-channel-color-rgb), 0.5);
3 | stroke-width: 6px;
4 | fill: none;
5 | width: 24px;
6 | height: 24px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/showSidebar.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './showSidebar.scss'
7 |
8 | export default function ShowSidebarIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/sortDown.scss:
--------------------------------------------------------------------------------
1 | .SortDownIcon {
2 | stroke: rgba(var(--center-channel-color-rgb), 0.5);
3 | stroke-width: 8px;
4 | fill: none;
5 | width: 24px;
6 | height: 24px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/sortDown.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './sortDown.scss'
7 |
8 | export default function SortDownIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/sortUp.scss:
--------------------------------------------------------------------------------
1 | .SortUpIcon {
2 | stroke: currentColor;
3 | stroke-width: 8px;
4 | fill: none;
5 | width: 24px;
6 | height: 24px;
7 | }
8 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/sortUp.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './sortUp.scss'
7 |
8 | export default function SortUpIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/submenuTriangle.scss:
--------------------------------------------------------------------------------
1 | .SubmenuTriangleIcon {
2 | fill: currentColor;
3 | stroke: none;
4 | width: 24px;
5 | height: 24px;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/submenuTriangle.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import './submenuTriangle.scss'
7 |
8 | export default function SubmenuTriangleIcon(): JSX.Element {
9 | return (
10 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/table.scss:
--------------------------------------------------------------------------------
1 | .TableIcon {
2 | stroke-width: 8px;
3 | }
4 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/text.scss:
--------------------------------------------------------------------------------
1 | .TextIcon {
2 | stroke: none;
3 | width: 1em;
4 | height: 1em;
5 | line-height: 1em;
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/icons/update.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import React from 'react'
5 |
6 | import CompassIcon from './compassIcon'
7 |
8 | export default function Update(): JSX.Element {
9 | return (
10 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/colorOption.scss:
--------------------------------------------------------------------------------
1 | .ColorOption {
2 | .menu-colorbox {
3 | display: inline-block;
4 | margin-right: 8px;
5 | vertical-align: middle;
6 | width: 18px;
7 | height: 18px;
8 | border-radius: 3px;
9 | box-shadow: rgba(15, 15, 15, 0.1) 0 0 0 1px inset;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/index.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | import Menu from './menu'
5 |
6 | export default Menu
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/labelOption.scss:
--------------------------------------------------------------------------------
1 | .Menu {
2 | .LabelOption.menu-option {
3 | cursor: auto;
4 | pointer-events: none;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/menuItem.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 |
4 | export type MenuOptionProps = {
5 | id: string
6 | name: string
7 | onClick: (id: string) => void
8 | }
9 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/separatorOption.scss:
--------------------------------------------------------------------------------
1 | .MenuSeparator {
2 | border-bottom: solid 1px rgba(var(--center-channel-color-rgb), 0.16);
3 | margin: 8px 0;
4 | }
5 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menu/separatorOption.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | import React, {FC} from 'react'
4 |
5 | import './separatorOption.scss'
6 |
7 | const SeparatorOption: FC = (): JSX.Element => (
8 |
9 | )
10 |
11 | export default SeparatorOption
12 |
--------------------------------------------------------------------------------
/webapp/src/widgets/menuWrapper.scss:
--------------------------------------------------------------------------------
1 | .MenuWrapper {
2 | position: relative;
3 | cursor: default;
4 |
5 | &.disabled {
6 | cursor: default;
7 | }
8 |
9 | &.override.menuOpened {
10 | display: block;
11 | }
12 |
13 | *:first-child {
14 | /* stylelint-disable property-no-vendor-prefix*/
15 | -webkit-user-select: text; /* Chrome all / Safari all */
16 | -moz-user-select: text; /* Firefox all */
17 | -ms-user-select: text; /* IE 10+ */
18 | user-select: text;
19 | /* stylelint-enable property-no-vendor-prefix*/
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/webapp/src/widgets/propertyMenu.scss:
--------------------------------------------------------------------------------
1 | .PropertyMenu {
2 | &.menu-textbox {
3 | font-weight: 400;
4 | padding: 2px 10px;
5 | cursor: text;
6 | touch-action: none;
7 | border: solid 1px #909090;
8 | border-radius: 3px;
9 | margin: 5px;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/webapp/static/addDescription.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/addDescription.png
--------------------------------------------------------------------------------
/webapp/static/addProperty.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/addProperty.gif
--------------------------------------------------------------------------------
/webapp/static/app-bar-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/app-bar-icon.png
--------------------------------------------------------------------------------
/webapp/static/boards-screenshots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/boards-screenshots.png
--------------------------------------------------------------------------------
/webapp/static/boards-welcome-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/boards-welcome-small.png
--------------------------------------------------------------------------------
/webapp/static/boards-welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/boards-welcome.png
--------------------------------------------------------------------------------
/webapp/static/changeViews.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/changeViews.gif
--------------------------------------------------------------------------------
/webapp/static/comment.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/comment.gif
--------------------------------------------------------------------------------
/webapp/static/copyLink.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/copyLink.gif
--------------------------------------------------------------------------------
/webapp/static/emoji_spirit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/emoji_spirit.png
--------------------------------------------------------------------------------
/webapp/static/onboardingBg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/onboardingBg.jpg
--------------------------------------------------------------------------------
/webapp/static/share.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/share.gif
--------------------------------------------------------------------------------
/webapp/static/upgrade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/webapp/static/upgrade.png
--------------------------------------------------------------------------------
/webapp/webpack.prod.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2 | // See LICENSE.txt for license information.
3 | const merge = require('webpack-merge');
4 | const TerserPlugin = require('terser-webpack-plugin');
5 |
6 | const makeCommonConfig = require('./webpack.common.js');
7 |
8 | const commonConfig = makeCommonConfig();
9 |
10 | const config = merge.merge(commonConfig, {
11 | mode: 'production',
12 | optimization: {
13 | minimize: true,
14 | minimizer: [new TerserPlugin({extractComments: false})],
15 | },
16 | });
17 |
18 | module.exports = [
19 | merge.merge(config, {
20 | }),
21 | ];
22 |
--------------------------------------------------------------------------------
/website/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org/
2 |
3 | root = true
4 |
5 | [*]
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 | charset = utf-8
10 |
11 | [*.{md,css,html}]
12 | indent_style = space
13 | indent_size = 4
14 |
15 | [*.toml]
16 | indent_style = space
17 | indent_size = 2
18 |
19 | [*.go]
20 | indent_style = tab
21 |
22 | [Makefile,*.mk]
23 | indent_style = tab
24 |
25 | [*.md]
26 | trim_trailing_whitespace = false
27 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | # build artifacts
2 | dist
3 |
4 | # os artifacts
5 | *.swp
6 | .DS_Store
7 |
8 | # IDE artifacts
9 | .idea/
10 |
--------------------------------------------------------------------------------
/website/Makefile:
--------------------------------------------------------------------------------
1 |
2 | BASE_URL?=https://www.focalboard.com
3 |
4 | .PHONY: dist
5 | dist:
6 | rm -rf ./dist
7 | hugo -s site --destination ../dist/html -b$(BASE_URL)
8 |
9 | .PHONY: run
10 | run:
11 | hugo server --buildDrafts --disableFastRender -F -s site
12 |
--------------------------------------------------------------------------------
/website/site/.hugo_build.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/.hugo_build.lock
--------------------------------------------------------------------------------
/website/site/archetypes/default.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "{{ replace .TranslationBaseName "-" " " | title }}"
3 | date: {{ .Date }}
4 | draft: true
5 | ---
6 |
--------------------------------------------------------------------------------
/website/site/content/blog/2021-1-7-hello.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Hello World
3 | slug: hello
4 | date: 2021-01-07
5 | categories:
6 | - "general"
7 | author: Chen Lim
8 | github: chenilim
9 | community: chen-i.lim
10 | ---
11 |
12 | > "I long to accomplish a great and noble task, but it is my chief duty to accomplish small tasks as if they were great and noble."
13 | > -- Helen Keller
14 |
--------------------------------------------------------------------------------
/website/site/content/docs/personal-edition/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Personal Edition"
3 | date: "2020-12-15T12:01:23-04:00"
4 | section: "docs"
5 | weight: 1
6 | ---
7 |
8 | If you are new to Focalboard, [Personal Desktop](desktop) is the fastest way to try it out.
9 |
10 | To use it with your team, use [Mattermost Boards](../mattermost).
11 | You can import boards from Personal Desktop to Mattermost Boards.
12 |
13 | You can also set up the standalone Development or Personal Server on [Ubuntu](ubuntu) or with [Docker](docker).
14 |
--------------------------------------------------------------------------------
/website/site/content/feedback/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "We love your feedback!"
3 | date: "2021-03-03T12:01:23-04:00"
4 | section: "feedback"
5 | weight: 1
6 | ---
7 |
8 | Please contact us via one of the following:
9 | * [File a GitHub issue](https://github.com/mattermost/focalboard/issues) for bugs or feature ideas
10 | * [Start a GitHub discussion](https://github.com/mattermost/focalboard/discussions)
11 |
12 | Focalboard is an open source project that is in early access. Help shape its future by sharing what you'd like to see with the community.
13 |
14 | Thank you for your input!
15 |
--------------------------------------------------------------------------------
/website/site/content/fwlink/doc-boards.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page Moved
5 |
8 |
9 |
10 | This page has moved. Click here to go to the new page.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/website/site/content/fwlink/plugin-setup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page Moved
5 |
8 |
9 |
10 | This page has moved. Click here to go to the new page.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/website/site/content/fwlink/setup-536.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page Moved
5 |
8 |
9 |
10 | This page has moved. Click here to go to the new page.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/website/site/content/fwlink/websocket-connect-error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page Moved
5 |
8 |
9 |
10 | This page has moved. Click here to go to the new page.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/website/site/content/guide/user/add view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/add view.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/all tasks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/all tasks.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/board sidebar menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/board sidebar menu.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/by status properties.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/by status properties.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/by status.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/by status.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/settings menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/settings menu.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/share board menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/share board menu.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/share board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/share board.png
--------------------------------------------------------------------------------
/website/site/content/guide/user/table header menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/content/guide/user/table header menu.png
--------------------------------------------------------------------------------
/website/site/content/guide/websocket-errors/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Troubleshooting: Websocket errors"
3 | date: "2021-06-14T12:01:23-04:00"
4 | section: "guide"
5 | weight: 4
6 | ---
7 |
8 | If the websocket persistently fails to connect to the server, check that the web proxy is configured correctly:
9 | * [If running Focalboard with Mattermost](/download/mattermost/)
10 | * [If running Focalboard Personal Server](/download/personal-edition/ubuntu/#configure-nginx)
11 |
--------------------------------------------------------------------------------
/website/site/layouts/404.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/website/site/layouts/_default/_markup/render-link.html:
--------------------------------------------------------------------------------
1 | {{ htmlUnescape .Text }}
--------------------------------------------------------------------------------
/website/site/layouts/blog/li.html:
--------------------------------------------------------------------------------
1 |
2 | - {{ .Title}}
3 | posted on {{ .Date.Format "January 2, 2006" }}
4 |
5 |
--------------------------------------------------------------------------------
/website/site/layouts/partials/blogauthor.html:
--------------------------------------------------------------------------------
1 | {{ .name }}
2 | -
3 |
4 | @{{ .community }}
5 |
6 | on
7 |
8 | community.mattermost.com
9 |
10 | and
11 |
12 | @{{ .github }}
13 |
14 | on GitHub
15 |
--------------------------------------------------------------------------------
/website/site/layouts/partials/hanchor.html:
--------------------------------------------------------------------------------
1 | {{ . | replaceRE "()" `${1} ${3}` | safeHTML }}
2 |
--------------------------------------------------------------------------------
/website/site/layouts/partials/mailinglist.html:
--------------------------------------------------------------------------------
1 | {{ if .Site.Params.mailinglist.enable }}
2 |
5 | {{ end }}
6 |
--------------------------------------------------------------------------------
/website/site/layouts/partials/notification.html:
--------------------------------------------------------------------------------
1 | {{ if .Site.Params.notification.enable }}
2 |
12 |
13 | {{ end }}
14 |
--------------------------------------------------------------------------------
/website/site/layouts/partials/page-edit.html:
--------------------------------------------------------------------------------
1 | {{ if .File }}
2 |
7 | Edit on GitHub
8 |
9 | {{ end }}
10 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/baseurl.html:
--------------------------------------------------------------------------------
1 | {{ .Page.Site.BaseURL }}
2 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/bignumber.html:
--------------------------------------------------------------------------------
1 |
2 |
{{ .Get "number" }}
3 |
4 |
5 |
6 |
7 |
8 | {{ .Get "content" | markdownify }}
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/blogurl.html:
--------------------------------------------------------------------------------
1 | {{ .Page.Site.BaseURL }}blog
2 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/content.html:
--------------------------------------------------------------------------------
1 | {{ .Get 0 | readFile | markdownify }}
2 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/md.html:
--------------------------------------------------------------------------------
1 | {{ .Inner }}
2 |
--------------------------------------------------------------------------------
/website/site/layouts/shortcodes/note.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/website/site/static/css/code.css:
--------------------------------------------------------------------------------
1 | code {
2 | padding: .2rem;
3 | }
4 |
--------------------------------------------------------------------------------
/website/site/static/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/website/site/static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/website/site/static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/website/site/static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/website/site/static/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/website/site/static/img/arrow-right.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/website/site/static/img/bgroundedcenter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/website/site/static/img/bgroundedleft.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/website/site/static/img/bgroundedright.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/website/site/static/img/check.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/website/site/static/img/download-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/website/site/static/img/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/favicon-16x16.png
--------------------------------------------------------------------------------
/website/site/static/img/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/favicon-32x32.png
--------------------------------------------------------------------------------
/website/site/static/img/hero.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/hero.jpg
--------------------------------------------------------------------------------
/website/site/static/img/mentioned/newstack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/mentioned/newstack.png
--------------------------------------------------------------------------------
/website/site/static/img/mentioned/producthunt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/mentioned/producthunt.png
--------------------------------------------------------------------------------
/website/site/static/img/mentioned/techrepublic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/mentioned/techrepublic.png
--------------------------------------------------------------------------------
/website/site/static/img/mentioned/venturebeat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/mentioned/venturebeat.png
--------------------------------------------------------------------------------
/website/site/static/img/mentioned/ycombinator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/mentioned/ycombinator.png
--------------------------------------------------------------------------------
/website/site/static/img/roadmap/analytics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/roadmap/analytics.png
--------------------------------------------------------------------------------
/website/site/static/img/roadmap/card-dependencies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/roadmap/card-dependencies.png
--------------------------------------------------------------------------------
/website/site/static/img/roadmap/standard-properties.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/roadmap/standard-properties.png
--------------------------------------------------------------------------------
/website/site/static/img/tabs/boards.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/tabs/boards.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/company-goals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/company-goals.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/content-calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/content-calendar.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/meeting-agenda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/meeting-agenda.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/project-tasks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/project-tasks.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/roadmap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/roadmap.png
--------------------------------------------------------------------------------
/website/site/static/img/templates/welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/templates/welcome.png
--------------------------------------------------------------------------------
/website/site/static/img/use-icon.svg:
--------------------------------------------------------------------------------
1 |
7 |
15 |
--------------------------------------------------------------------------------
/website/site/static/img/views/boardview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/views/boardview.png
--------------------------------------------------------------------------------
/website/site/static/img/views/calendarview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/views/calendarview.png
--------------------------------------------------------------------------------
/website/site/static/img/views/galleryview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/views/galleryview.png
--------------------------------------------------------------------------------
/website/site/static/img/views/listview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/img/views/listview.png
--------------------------------------------------------------------------------
/website/site/static/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | Disallow: /cgi-bin/
3 | Disallow: /&utm_source
4 | Disallow: /&utm_medium
5 | Disallow: /&utm_campaign
6 | Disallow: /?utm_
7 |
8 | Sitemap: https://www.focalboard.com/sitemap.xml
9 |
--------------------------------------------------------------------------------
/website/site/static/video/accelerate1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/video/accelerate1.mp4
--------------------------------------------------------------------------------
/website/site/static/video/comment-animation.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/website/site/static/video/comment-animation.mp4
--------------------------------------------------------------------------------
/website/site/themes/archetypes/default.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "{{ replace .TranslationBaseName "-" " " | title }}"
3 | date: {{ .Date }}
4 | draft: true
5 | ---
6 |
--------------------------------------------------------------------------------
/website/site/themes/content/contribute/_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Contribute"
3 | date: "2017-08-19T12:01:23-04:00"
4 | ---
5 |
6 | # heading
7 |
8 | text!
9 |
--------------------------------------------------------------------------------
/website/site/themes/layouts/404.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/website/site/themes/layouts/_default/list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{ partial "head.html" .}}
10 |
11 |
12 | {{ partial "nav.html" .}}
13 | {{ .Content }}
14 |
15 |
16 |
--------------------------------------------------------------------------------
/website/site/themes/layouts/_default/single.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ .Content }}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/website/site/themes/layouts/partials/nav2.html:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
--------------------------------------------------------------------------------
/win-wpf/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 | obj
3 | msix
4 | temp
5 | dist
6 | *.msix
7 | *.suo
8 | *.csproj.user
9 |
--------------------------------------------------------------------------------
/win-wpf/Focalboard/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/win-wpf/Focalboard/focalboard.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/win-wpf/Focalboard/focalboard.ico
--------------------------------------------------------------------------------
/win-wpf/Focalboard/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/win-wpf/art/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/win-wpf/art/StoreLogo.png
--------------------------------------------------------------------------------
/win-wpf/art/icon150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/win-wpf/art/icon150.png
--------------------------------------------------------------------------------
/win-wpf/art/icon44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattermost-community/focalboard/de5e5cc4141f14f69bf0e5666383997b81f851d6/win-wpf/art/icon44.png
--------------------------------------------------------------------------------
/win-wpf/build.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | WHERE msbuild.exe > nul 2>&1
4 | IF %ERRORLEVEL% NEQ 0 set PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin
5 |
6 | WHERE msbuild.exe > nul 2>&1
7 | IF %ERRORLEVEL% NEQ 0 set PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin
8 |
9 | WHERE msbuild.exe > nul
10 | IF %ERRORLEVEL% NEQ 0 echo msbuild.exe not found; exit /b 1
11 |
12 | echo Building...
13 |
14 | msbuild.exe Focalboard.sln /t:Rebuild /p:Configuration=Release /p:Platform="x64" /p:DebugSymbols=false /p:DebugType=None
15 |
--------------------------------------------------------------------------------
/win-wpf/package-zip.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | if exist dist\focalboard-win.zip del /q dist\focalboard-win.zip
4 | if not exist dist mkdir dist
5 |
6 | if exist temp del /s /f /q temp
7 | rmdir /s /q temp
8 | if not exist temp mkdir temp
9 | xcopy /e /i /y Focalboard\bin\x64\Release temp
10 | copy ..\build\MIT-COMPILED-LICENSE.md temp
11 | copy ..\NOTICE.txt temp
12 | copy ..\webapp\NOTICE.txt temp\webapp-NOTICE.txt
13 |
14 | echo --- Contents of temp ---
15 | dir /s /b temp
16 | echo ---
17 |
18 | powershell Compress-Archive -Path temp\* -DestinationPath dist\focalboard-win.zip
19 |
--------------------------------------------------------------------------------
/win-wpf/package.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | WHERE makeappx.exe > nul 2>&1
4 | IF %ERRORLEVEL% NEQ 0 set PATH=%PATH%;C:\Program Files (x86)\Windows Kits\10\App Certification Kit
5 |
6 | WHERE makeappx.exe > nul
7 | IF %ERRORLEVEL% NEQ 0 echo makeappx.exe not found; exit /b 1
8 |
9 | echo Packaging...
10 |
11 | rd /s /q msix
12 | mkdir msix
13 | xcopy /e /i /y Focalboard\bin\x64\Release msix
14 | mkdir msix\Assets
15 | copy art\StoreLogo.png msix\Assets
16 | copy art\icon150.png msix\Assets
17 | copy art\icon44.png msix\Assets
18 | copy AppxManifest.xml msix
19 | makeappx.exe pack /o /v /d msix /p Focalboard.msix
20 |
--------------------------------------------------------------------------------