Compare commits

..
816 Commits
Author SHA1 Message Date
Wyatt Johnson 375ef09d78 Merge pull request #1670 from coralproject/templates
Custom CSS Fix
2018-05-31 11:50:41 -06:00
Kim Gardner 135f0e300f Small typo 2018-05-31 13:33:34 -04:00
Wyatt Johnson 9d752685cd resolved custom css loading issue 2018-05-31 11:27:02 -06:00
Kim Gardner a638dafd85 Merge pull request #1667 from coralproject/fix-dropdown-display
Fix DropDown display bug
2018-05-30 16:58:10 -04:00
Kim Gardner 93436a2eb5 Merge branch 'master' into fix-dropdown-display 2018-05-30 16:49:47 -04:00
Kim Gardner a16233484c Merge pull request #1666 from coralproject/auth
Fixed double encoding
2018-05-30 16:45:57 -04:00
Chi Vinh Le c98830aa63 Fix DropDown display bug 2018-05-30 22:23:52 +02:00
Wyatt Johnson c24251e8f2 Fixed double encoding 2018-05-30 14:22:13 -06:00
Wyatt Johnson 9ed991936e Merge pull request #1664 from conversario/ban-user-message
remove unused method
2018-05-30 10:08:20 -06:00
Wyatt Johnson ede273a3e0 fix to target handler 2018-05-30 10:00:04 -06:00
Wyatt Johnson c6deabf919 Merge branch 'master' into ban-user-message 2018-05-30 09:49:18 -06:00
Wyatt Johnson 2e40cd53cb Merge pull request #1665 from cristiandean/translation_br
Added missing translation pt_BR
2018-05-30 09:48:10 -06:00
Cristian b9e3a01cdd Added missing translation pt_BR 2018-05-30 09:19:59 -03:00
Leandro 5c7345313e remove unused method 2018-05-30 09:25:10 +02:00
Kim Gardner 8933b43e1a Merge pull request #1661 from coralproject/dropdown-ios
Use <button> for dropdown to fix IOS bug
2018-05-29 15:21:28 -04:00
Kim Gardner 6c1fb2b34d Merge branch 'master' into dropdown-ios 2018-05-29 15:14:35 -04:00
Kim Gardner 0db3b354ca Merge pull request #1662 from coralproject/rte-focus-ios
Workaround RTE Button focus bug on IOS
2018-05-29 15:14:26 -04:00
Kim Gardner a732793cb1 Merge branch 'master' into rte-focus-ios 2018-05-29 15:06:26 -04:00
Wyatt Johnson 03a7ecff0b Merge pull request #1663 from coralproject/e2e-update
E2E improvements
2018-05-29 11:38:22 -06:00
Chi Vinh Le 606f463331 Typo 2018-05-29 16:52:07 +02:00
Chi Vinh Le 576820f1f8 Fix warnings 2018-05-29 16:50:11 +02:00
Chi Vinh Le 3a84da9495 Activate Websocket and add browser console logging 2018-05-29 16:42:04 +02:00
okbel b15a306c43 çhanges 2018-05-28 16:20:20 -03:00
okbel 4299c373ba changes and updates to the e2e 2018-05-28 15:17:31 -03:00
Wyatt Johnson 6f0694d341 Merge pull request #1660 from hjanuschka/patch-1
add missing dependency
2018-05-28 09:53:18 -06:00
Wyatt Johnson da820ad6db updated yarn.lock 2018-05-28 09:42:22 -06:00
Chi Vinh Le ed679096c8 Workaround RTE Button focus bug on IOS 2018-05-28 17:16:44 +02:00
Chi Vinh Le 6577365930 Use standard buttons to fix IOS bug 2018-05-28 16:19:56 +02:00
Helmut Januschka 1fb206daa4 add missing dependency 2018-05-28 10:56:46 +02:00
Wyatt Johnson 2bd4e1182b Merge pull request #1657 from erikreyna/talk-plugin-rich-text-patch_placeholder-fix
move placeholder right behind contentEditable
2018-05-25 16:28:49 -06:00
Kim Gardner 9fe2175da3 Merge branch 'master' into talk-plugin-rich-text-patch_placeholder-fix 2018-05-25 18:19:37 -04:00
Kim Gardner c1692dfb70 Merge pull request #1630 from coralproject/karma
Karma Score
2018-05-25 18:19:25 -04:00
Kim Gardner cb83514365 Merge branch 'master' into talk-plugin-rich-text-patch_placeholder-fix 2018-05-25 18:12:21 -04:00
Erik Reyna ba3af0aeb3 apply @cvle suggestion for fix 2018-05-25 18:07:41 -04:00
Kim Gardner 51cb917d6b Merge branch 'master' into karma 2018-05-25 17:04:30 -04:00
Chi Vinh Le b02fd67742 Merge branch 'karma' of ssh://github.com/coralproject/talk into karma 2018-05-25 22:50:18 +02:00
Chi Vinh Le 90e4682cf6 Take karma into account when doing e2e 2018-05-25 22:49:35 +02:00
Wyatt Johnson 3ff8b8519e Merge pull request #1658 from coralproject/bump-version-4-4-2
Bump version to 4.4.2
2018-05-25 13:58:46 -06:00
Wyatt Johnson 105cff6990 Merge branch 'master' into bump-version-4-4-2 2018-05-25 13:52:44 -06:00
Kim Gardner 99854d8644 Merge pull request #1648 from coralproject/fix-ipad-touch-issue
Fix Touch issues on iOS Safari (iPad)
2018-05-25 15:04:55 -04:00
Kim Gardner cedabf04e3 Bump version to 4.4.2 2018-05-25 15:04:00 -04:00
Erik Reyna 2c6843129a move placeholder right behind contentEditable 2018-05-25 15:02:34 -04:00
Kim Gardner 47761cf8a0 Merge branch 'master' into fix-ipad-touch-issue 2018-05-25 14:49:25 -04:00
Kim Gardner 4442ffc784 Merge pull request #1656 from coralproject/csp
Disable CSP
2018-05-25 14:49:07 -04:00
Wyatt Johnson 016b6d6007 Merge branch 'master' into karma 2018-05-25 12:44:48 -06:00
Wyatt Johnson e94d13e594 Merge branch 'master' into fix-ipad-touch-issue 2018-05-25 12:44:19 -06:00
Kim Gardner 68c7477f3a Merge branch 'master' into csp 2018-05-25 14:40:21 -04:00
Kim Gardner 700cee4e56 Merge pull request #1653 from conversario/missing-translations-local-auth
Add missing translations (en/de) for plugins ignore-user and local-auth.
2018-05-25 14:39:56 -04:00
Kiwi d0740cb323 Merge branch 'master' into csp 2018-05-25 15:36:44 -03:00
Kim Gardner c021c3adc8 Merge branch 'master' into missing-translations-local-auth 2018-05-25 14:22:38 -04:00
Kim Gardner 130fb0d4e9 Merge pull request #1655 from coralproject/translations
Added missing translation
2018-05-25 14:22:23 -04:00
Kiwi 79a0f0321f Merge branch 'master' into karma 2018-05-25 15:12:57 -03:00
Kiwi 5090f9c6b2 Merge branch 'master' into csp 2018-05-25 15:12:20 -03:00
Kim Gardner 5e8c950dc5 Merge branch 'master' into translations 2018-05-25 14:04:03 -04:00
Kim Gardner c7b2641ea7 Merge pull request #1654 from coralproject/docs
Enhanced documentation on JWT's
2018-05-25 14:03:47 -04:00
Wyatt Johnson ba2abab358 added pivotal tracker ref 2018-05-25 11:55:17 -06:00
Wyatt Johnson 5535dde053 Merge branch 'master' into fix-ipad-touch-issue 2018-05-25 11:53:04 -06:00
Wyatt Johnson c1eab3f2c6 moved event handler to bundle 2018-05-25 11:51:43 -06:00
Wyatt Johnson 540df09b5b Update stream.njk 2018-05-25 11:48:55 -06:00
Kim Gardner ed2842717d Merge branch 'master' into docs 2018-05-25 13:45:12 -04:00
Kim Gardner d9621e6801 Merge pull request #1645 from mkonikov/delete-modal-iphone
[iOS CSS Fix] Improve legibility of the verify text
2018-05-25 13:44:59 -04:00
Wyatt Johnson 5f6b1235aa Merge branch 'master' into missing-translations-local-auth 2018-05-25 11:44:07 -06:00
Kim Gardner d923857eda Merge branch 'master' into delete-modal-iphone 2018-05-25 13:36:01 -04:00
Kim Gardner d96702eef5 Merge pull request #1646 from mkonikov/hr-fix
[CSS Fix] HR line on older devices - Flexbox
2018-05-25 13:35:18 -04:00
Wyatt Johnson 0e29a85d72 Merge branch 'master' into missing-translations-local-auth 2018-05-25 11:33:04 -06:00
Wyatt Johnson 7d861236b8 disable CSP until we can work on configuration + webpack issues 2018-05-25 11:21:53 -06:00
Wyatt Johnson 3a79cc684b added missing translation 2018-05-25 11:19:02 -06:00
Wyatt Johnson e1d77daf47 enhanced docs around jwt's 2018-05-25 11:16:24 -06:00
Kiwi 4ec5ccd1a3 Merge branch 'master' into hr-fix 2018-05-25 14:00:12 -03:00
Kiwi 5e6586d228 Merge branch 'master' into delete-modal-iphone 2018-05-25 13:17:57 -03:00
Kim Gardner d414867bb0 Merge branch 'master' into fix-ipad-touch-issue 2018-05-25 12:04:49 -04:00
Kim Gardner cfb162c490 Merge branch 'master' into karma 2018-05-25 12:04:15 -04:00
Fabian Neumann b7d2621cb8 Remove redundant period. It's in the translation strings already. 2018-05-25 17:19:43 +02:00
Wyatt Johnson 3141133e34 Merge pull request #1640 from mkonikov/word-break
Remove wordbreak
2018-05-25 09:12:36 -06:00
Fabian Neumann 325e763fd0 Remove redundancy 2018-05-25 16:34:29 +02:00
Fabian Neumann ab6a193dcb One more missing German translation 2018-05-25 16:31:07 +02:00
Fabian Neumann 56483f3888 Add missing translations (en/de) for plugins ignore-user and local-auth. 2018-05-25 16:09:38 +02:00
Mendel Konikov 4800e32758 Use overflow wrap for better compatibility 2018-05-24 19:07:00 -04:00
Wyatt Johnson 16573b127e text-replace error 2018-05-24 16:19:52 -06:00
Mendel Konikov abafa45be7 Replace break all with break-word 2018-05-24 17:20:54 -04:00
Mendel Konikov ce708bff42 Merge branch 'master' of github.com:mkonikov/talk into word-break 2018-05-24 17:18:29 -04:00
Wyatt Johnson 64c16a1805 support the __webpack_nonce__ parameter 2018-05-24 15:02:08 -06:00
Wyatt Johnson f8cc658c54 csp fixes 2018-05-24 14:34:13 -06:00
Wyatt Johnson e39bcb11ba added comment 2018-05-24 14:02:02 -06:00
Wyatt Johnson a046162f9c karma -> karmaThresholds 2018-05-24 13:57:26 -06:00
Wyatt Johnson 8f51b07388 Merge branch 'master' into karma 2018-05-24 13:28:03 -06:00
Wyatt Johnson 45113f14c7 Merge pull request #1650 from coralproject/whitelisted-langs
Added support for forcing languages
2018-05-24 13:24:00 -06:00
Wyatt Johnson 0c35badd95 name changes 2018-05-24 12:58:55 -06:00
Wyatt Johnson 1c0bfdb89e Merge branch 'master' into whitelisted-langs 2018-05-24 12:38:22 -06:00
Wyatt Johnson 8f4846404a fixed default doc 2018-05-24 12:35:45 -06:00
Wyatt Johnson c642cc811c fix 2018-05-24 12:34:58 -06:00
Wyatt Johnson 945ab9a1b6 Added support for forcing languages 2018-05-24 12:32:06 -06:00
Chi Vinh Le e1298e4fd9 Fix Touch issues on IOS Safari (iPad) 2018-05-24 19:00:07 +02:00
Wyatt Johnson 0c1e4873f8 fixed first time user 2018-05-24 10:11:49 -06:00
okbel f3d89e63d2 Merge branch 'karma' of github.com:coralproject/talk into karma
* 'karma' of github.com:coralproject/talk: (32 commits)
  fixed translations
  "Trust" flag to "Karma" and updated translations
  adjusted karma tooltip
  field renamed
  patches to reliability computation based on settings
  add from to import statement
  Remuve dupe "apply"
  Fix broken link to tokenusernotfound
  Make it so low threshold is included in karma calc
  Fix incorrect statement regarding GDPR
  simplified language negotiation
  Docs typo
  relying on ip
  req not properly passed
  German translations for the email notification plugins.
  Small modification
  doc patch
  fix for custom css
  fixes to csp policy
  disable by default
  ...
2018-05-24 13:09:13 -03:00
Wyatt Johnson 0835f3f321 fixed translations 2018-05-23 17:16:51 -06:00
Wyatt Johnson 9a73c6db59 "Trust" flag to "Karma" and updated translations 2018-05-23 16:18:22 -06:00
Wyatt Johnson 97416d421b adjusted karma tooltip 2018-05-23 16:18:22 -06:00
Wyatt Johnson f36b6e2cb6 field renamed 2018-05-23 16:18:22 -06:00
Wyatt Johnson 975448ec69 patches to reliability computation based on settings 2018-05-23 16:18:22 -06:00
Mendel Konikov 92420ae827 Fix hr line on older devices 2018-05-23 17:42:40 -04:00
Mendel Konikov a6ec021bd1 Explicitly set opacity to 1 for iPhone 2018-05-23 17:25:09 -04:00
Kim Gardner 921b85fba3 Merge branch 'master' into karma 2018-05-23 16:47:52 -04:00
Kim Gardner 9c7ed62cba Merge pull request #1644 from erikreyna/patch-1
add from to import statement
2018-05-23 16:47:02 -04:00
Wyatt Johnson b7a053c011 Merge branch 'master' into patch-1 2018-05-23 13:28:20 -06:00
Kim Gardner 6548df971c Merge branch 'master' into karma 2018-05-23 15:19:32 -04:00
Kim Gardner 27818d966d Merge pull request #1642 from babolivier/patch-1
[Doc] Fix incorrect statement regarding GDPR
2018-05-23 14:43:46 -04:00
Erik Reyna f7f6ed635c add from to import statement
from expected from import statement, thanks eslint
2018-05-23 14:24:11 -04:00
Wyatt Johnson 61c09f5818 Merge branch 'master' into patch-1 2018-05-23 12:17:05 -06:00
Wyatt Johnson def20a3b37 Merge pull request #1643 from smic1909/patch-1
Fix broken link to tokenusernotfound
2018-05-23 12:16:48 -06:00
Wyatt Johnson 4ae3e90422 Merge branch 'master' into patch-1 2018-05-23 12:09:44 -06:00
Wyatt Johnson 9539073eb8 Merge pull request #1633 from coralproject/csp
Content Security Policy + Nunjacks
2018-05-23 12:08:45 -06:00
Wyatt Johnson 422260607e Merge branch 'master' into csp 2018-05-23 11:53:24 -06:00
Wyatt Johnson a16c584880 Merge branch 'master' into patch-1 2018-05-23 11:25:14 -06:00
Wyatt Johnson 3fcc85139d Merge pull request #1641 from coralproject/locales
Locale Negotiation
2018-05-23 10:12:27 -06:00
okbel 17f76e85b0 changes 2018-05-23 13:07:34 -03:00
Brendan Abolivier a95d55b6da Remuve dupe "apply" 2018-05-23 10:05:21 +02:00
Simon 879865a4c1 Fix broken link to tokenusernotfound
Fix broken link to tokenusernotfound
2018-05-23 09:14:32 +02:00
Kim Gardner 8405bdf9bc Merge branch 'karma' of git+ssh://github.com/coralproject/talk into karma 2018-05-22 20:12:40 -04:00
Kim Gardner 8e24d4f5c6 Make it so low threshold is included in karma calc 2018-05-22 20:12:17 -04:00
Kim Gardner 9265d29ac0 Merge branch 'master' into karma 2018-05-22 19:00:12 -04:00
Brendan Abolivier 849fe37b9b Fix incorrect statement regarding GDPR
GDPR's reach doesn't depend on the person or business's location, but on whether this person or this business include european citizen in its target (which can be easy to state for a business, but not that much for an individual).
2018-05-22 23:25:12 +02:00
Wyatt Johnson 1a52ad5d97 Merge branch 'master' into locales 2018-05-22 14:42:43 -06:00
Wyatt Johnson b984af3e2e Merge pull request #1638 from coralproject/akismet-bug
Akismet Bug - Req not properly passed
2018-05-22 14:42:24 -06:00
Wyatt Johnson 10a786f84d simplified language negotiation 2018-05-22 14:21:32 -06:00
Mendel Konikov 4f5f424c77 Remove wordbreak 2018-05-22 15:49:19 -04:00
Kiwi 9b4455f7bd Merge branch 'master' into csp 2018-05-22 16:39:20 -03:00
Kim Gardner 3a12e776c3 Merge branch 'master' into akismet-bug 2018-05-22 15:01:50 -04:00
Kim Gardner 6667bbe01f Docs typo 2018-05-22 13:18:28 -04:00
Kim Gardner 583cb6566b Merge branch 'master' into karma 2018-05-22 12:54:09 -04:00
Kim Gardner f90e17c3e0 Merge pull request #1625 from coralproject/party-fixes
Displaying multiple external provider IDs
2018-05-22 12:52:08 -04:00
Kim Gardner 71b1259db6 Merge branch 'master' into akismet-bug 2018-05-22 12:21:53 -04:00
Kiwi a39b967164 Merge branch 'master' into party-fixes 2018-05-22 13:19:08 -03:00
okbel b411f3e059 relying on ip 2018-05-22 13:08:59 -03:00
okbel 1aed51468f req not properly passed 2018-05-22 12:40:21 -03:00
Kim Gardner fd271d237c Merge branch 'master' into csp 2018-05-22 10:44:08 -04:00
Kim Gardner 04ae6fbb43 Merge pull request #1637 from conversario/notification-translations
German translations for the email notification plugins.
2018-05-22 10:43:50 -04:00
Fabian Neumann 4767354379 German translations for the email notification plugins. 2018-05-22 12:36:25 +02:00
Kim Gardner 55998a67da Merge branch 'master' into csp 2018-05-21 16:18:46 -04:00
Kim Gardner eee1e858bf Merge pull request #1634 from mkonikov/disabled-download-button
Show overflow text on download comments button when disabled
2018-05-21 16:18:30 -04:00
Kiwi 2c9d30bfd2 Small modification
Removed obsolete line and add todo
2018-05-21 17:09:36 -03:00
Kim Gardner 763833783d Merge branch 'master' into disabled-download-button 2018-05-21 15:22:51 -04:00
Kim Gardner 1f5e3d9f3f Merge pull request #1635 from conversario/translations-de-4.4.1
German translations for v4.4.1
2018-05-21 11:19:05 -04:00
Kim Gardner 30f03f5fb8 Merge branch 'master' into disabled-download-button 2018-05-21 11:07:59 -04:00
Kim Gardner 43c7b6f23f Merge branch 'master' into karma 2018-05-21 11:07:34 -04:00
Kim Gardner ced9d2ea4b Merge branch 'master' into translations-de-4.4.1 2018-05-21 11:06:17 -04:00
Wyatt Johnson 5aba578a98 doc patch 2018-05-18 16:47:58 -06:00
Wyatt Johnson dd0ad17038 fix for custom css 2018-05-18 16:44:43 -06:00
Wyatt Johnson 868343a29b fixes to csp policy 2018-05-18 16:42:23 -06:00
Wyatt Johnson 5403872bb7 disable by default 2018-05-18 16:21:53 -06:00
Wyatt Johnson f58e3df439 added config for report only mode 2018-05-18 16:21:53 -06:00
Wyatt Johnson 000d9ae56a Merge branch 'master' into csp 2018-05-18 15:28:26 -06:00
Kim Gardner e2ba08e708 Merge pull request #1632 from mkonikov/extra-p
Only display paragraph if delete requested
2018-05-18 17:18:00 -04:00
Kim Gardner 20860bb773 Merge branch 'master' into extra-p 2018-05-18 16:33:27 -04:00
Kim Gardner b15766bf80 Merge pull request #1629 from coralproject/rte-bugfixes
RTE Bugfixes
2018-05-18 16:33:15 -04:00
Kim Gardner 531cb0793f Merge branch 'master' into rte-bugfixes 2018-05-18 16:24:30 -04:00
Wyatt Johnson 8265c13149 Merge branch 'master' into extra-p 2018-05-18 11:26:37 -06:00
okbel b816053191 Updating the cache 2018-05-18 14:07:10 -03:00
Mendel Konikov ffa6b99d09 Wrap els in div 2018-05-18 12:32:24 -04:00
okbel 0e8065cdf9 Styling 2018-05-18 13:31:50 -03:00
Wyatt Johnson 9484d4c6f5 Merge branch 'master' into csp 2018-05-18 10:11:39 -06:00
Belén Curcio 5ebbc24264 Merge branch 'master' into karma 2018-05-18 13:09:07 -03:00
okbel 43e0f95aa6 Merge branch 'party-fixes' of github.com:coralproject/talk into party-fixes
* 'party-fixes' of github.com:coralproject/talk: (33 commits)
  patched migration bugs
  Don't close popup when there is an error
  Update .nsprc
  fix optimisticResponse typo
  Remove deprecated useMongoClient
  Update lint-staged to fix dependency issue
  copy updates
  Update package.json
  Ready
  Set is_test to false
  Removing
  Added support for new indexes
  Remove unused variable 2
  Remove unused variable
  Remove ModerationIndicator from container
  Show username already exists error
  No indicator on new queue
  Exclude deleted when loading more
  Remove modqueue counts on the frontend
  sepatate state
  ...
2018-05-18 13:07:03 -03:00
okbel 1f40d6b7bb replacing by a one liner :) 2018-05-18 13:05:46 -03:00
Fabian Neumann 8ee90387f6 German translations for v4.4.1 2018-05-18 16:03:30 +02:00
Wyatt Johnson 43170121f3 Merge branch 'master' into party-fixes 2018-05-17 21:03:12 -06:00
Wyatt Johnson 4f001bbdf2 Merge pull request #1628 from conversario/withremovetag-typo
fix optimisticResponse typo
2018-05-17 21:02:37 -06:00
Wyatt Johnson f5362f445a Merge branch 'master' into withremovetag-typo 2018-05-17 20:48:33 -06:00
Wyatt Johnson 1bcf1a23fc Merge branch 'master' into extra-p 2018-05-17 20:34:37 -06:00
Wyatt Johnson b2306066ce Merge pull request #1627 from coralproject/upgrade-mongoose
Upgrade Mongoose
2018-05-17 20:32:40 -06:00
Wyatt Johnson ebcff4d95e patched migration bugs 2018-05-17 18:58:01 -06:00
Wyatt Johnson 2484066922 Merge branch 'master' into upgrade-mongoose 2018-05-17 18:43:24 -06:00
Wyatt Johnson 2822a2dddd Merge branch 'master' into csp 2018-05-17 18:43:12 -06:00
Mendel Konikov 5f410276c6 Show overflow text on download comments button when disabled 2018-05-17 20:41:59 -04:00
Wyatt Johnson c84a9716a1 added support for csp 2018-05-17 18:37:50 -06:00
Mendel Konikov d83c2fd566 Only display paragraph if delete requested 2018-05-17 20:03:12 -04:00
Kim Gardner cd6aacbc76 Merge pull request #1607 from coralproject/admin-auth
External Signin for Admin
2018-05-17 19:08:21 -04:00
Wyatt Johnson 95072be97e switched ejs for nunjucks 2018-05-17 15:59:49 -06:00
Kiwi f0589fba26 Merge branch 'master' into admin-auth 2018-05-17 16:36:32 -03:00
Chi Vinh Le 417befd52a Don't close popup when there is an error 2018-05-17 21:34:37 +02:00
Wyatt Johnson 8d8cd57d79 Merge branch 'master' into upgrade-mongoose 2018-05-17 13:19:09 -06:00
Wyatt Johnson 086c43a003 Update .nsprc 2018-05-17 13:18:57 -06:00
Wyatt Johnson 887f7e17f4 server side 2018-05-17 11:38:00 -06:00
okbel 6444e8c2ab Karma 2018-05-17 13:48:30 -03:00
Leandro 0339e97b37 fix optimisticResponse typo 2018-05-17 16:39:04 +02:00
Kiwi ae88ae3f98 Merge pull request #1614 from conversario/comment-tombstone-slot
Add new slot 'commentTombstone'
2018-05-16 21:00:13 -03:00
Kim Gardner 5241206b03 Remove deprecated useMongoClient 2018-05-16 18:24:34 -04:00
Kim Gardner 663caa1001 Update lint-staged to fix dependency issue 2018-05-16 18:18:36 -04:00
Chi Vinh Le d07c54918d Indent, outdent fixes 2018-05-16 21:37:48 +02:00
Chi Vinh Le 2eac8f48d6 Workaround IOS focus bug when clicking on buttons 2018-05-16 21:37:35 +02:00
Kim Gardner 3a383ff8ba Merge branch 'master' into admin-auth 2018-05-16 12:58:59 -04:00
Kim Gardner 34760653a2 Merge branch 'master' into comment-tombstone-slot 2018-05-16 12:58:51 -04:00
Kim Gardner d176578aed Merge branch 'master' into party-fixes 2018-05-16 12:41:34 -04:00
Kim Gardner e3323ce5ec Merge pull request #1544 from conversario/global-switchoff
New setting: Disable commenting site-wide
2018-05-16 12:14:09 -04:00
Belén Curcio 7fc5c5a6be Merge branch 'master' into comment-tombstone-slot 2018-05-16 12:55:24 -03:00
okbel 2524004e2a Styling 2018-05-16 11:55:05 -03:00
okbel 91060537bb displaying multiple provider ids 2018-05-16 11:51:28 -03:00
Kim Gardner f0b87501c0 Merge branch 'master' into admin-auth 2018-05-15 19:06:27 -04:00
Kim Gardner ea6757cce5 Merge branch 'master' into global-switchoff 2018-05-15 18:55:58 -04:00
Kim Gardner cb9945053f Merge pull request #1624 from coralproject/username-change-copy
Username change copy
2018-05-15 18:48:31 -04:00
Kim Gardner fca6603b38 Merge branch 'master' into admin-auth 2018-05-15 18:13:05 -04:00
Kim Gardner 56ee58efdf Merge branch 'master' into global-switchoff 2018-05-15 17:55:35 -04:00
Wyatt Johnson 0b407d516b copy updates 2018-05-15 15:51:14 -06:00
Kim Gardner 4cca800af0 Merge pull request #1623 from coralproject/wyattjoh-patch-1
Bump to 4.4.1
2018-05-15 13:32:49 -04:00
Wyatt Johnson ee0790dbe8 Update package.json 2018-05-15 11:25:58 -06:00
Kim Gardner 6890d24e47 Merge pull request #1616 from coralproject/gdpr-change-email-bug
GDPR Bug - Confirm Email Dialog inputs shouldn't be connected to the save button in the background
2018-05-15 12:54:39 -04:00
okbel 2392e1ca78 Merge branch 'gdpr-change-email-bug' of github.com:coralproject/talk into gdpr-change-email-bug
* 'gdpr-change-email-bug' of github.com:coralproject/talk:
  Set is_test to false
  Added support for new indexes
2018-05-15 13:34:12 -03:00
okbel 40a431b374 Ready 2018-05-15 13:31:29 -03:00
Kim Gardner 5214705f5b Merge branch 'master' into gdpr-change-email-bug 2018-05-15 12:24:47 -04:00
Kim Gardner 79df9b487f Merge pull request #1622 from icco/patch-1
Set Akismet is_test to false
2018-05-15 12:24:23 -04:00
Nat Welch ef5e5ddbcf Set is_test to false
Akismet is no longer in test mode.
2018-05-15 11:55:02 -04:00
Wyatt Johnson 2e773a4438 Merge branch 'master' into gdpr-change-email-bug 2018-05-15 09:27:09 -06:00
Kim Gardner 2a2eabfae0 Merge pull request #1621 from coralproject/indexes
MongoDB Indexes
2018-05-15 11:07:55 -04:00
okbel bb9be71a7a Merge branch 'gdpr-change-email-bug' of github.com:coralproject/talk into gdpr-change-email-bug
* 'gdpr-change-email-bug' of github.com:coralproject/talk:
  Remove unused variable 2
  Remove unused variable
  Remove ModerationIndicator from container
  Show username already exists error
  No indicator on new queue
  Exclude deleted when loading more
  Remove modqueue counts on the frontend
2018-05-15 12:07:15 -03:00
okbel 50acf9ca50 Removing 2018-05-15 11:47:07 -03:00
Kim Gardner 3ae0136f75 Merge branch 'master' into gdpr-change-email-bug 2018-05-14 17:59:16 -04:00
Wyatt Johnson d3ad486f81 Merge branch 'master' into indexes 2018-05-14 14:52:57 -06:00
Wyatt Johnson 32510db1fa Merge pull request #1618 from coralproject/remove-mod-count-frontend
Remove modqueue counts on the frontend
2018-05-14 14:52:43 -06:00
Wyatt Johnson 8d44525c16 Added support for new indexes 2018-05-14 14:37:27 -06:00
Wyatt Johnson 83fddfdc40 Merge branch 'master' into remove-mod-count-frontend 2018-05-14 14:36:42 -06:00
Kim Gardner ed32a69b68 Merge branch 'master' into gdpr-change-email-bug 2018-05-14 16:32:51 -04:00
Kim Gardner 02b1e03c21 Merge pull request #1620 from coralproject/username-already-exists
Show username already exists error
2018-05-14 16:29:19 -04:00
Chi Vinh Le 08d523a4d6 Remove unused variable 2 2018-05-14 21:38:30 +02:00
Chi Vinh Le b5adea4b2a Remove unused variable 2018-05-14 21:30:09 +02:00
Chi Vinh Le beef4e8b3b Remove ModerationIndicator from container 2018-05-14 21:28:48 +02:00
Chi Vinh Le 5a190839d1 Show username already exists error 2018-05-14 20:44:30 +02:00
Chi Vinh Le ab7e5bc858 No indicator on new queue 2018-05-14 20:05:18 +02:00
Chi Vinh Le 12e848aace Exclude deleted when loading more 2018-05-14 19:27:18 +02:00
Chi Vinh Le 67c3fe3c5b Remove modqueue counts on the frontend 2018-05-14 19:18:34 +02:00
okbel 1f7c4e58a1 sepatate state 2018-05-14 13:31:24 -03:00
Fabian Neumann 8e392ef32d Remove superfluous className 2018-05-14 15:01:51 +02:00
Fabian Neumann 36063b459e Add new slot 'commentTombstone'.
With this slot plugins can override the default tombstone for deleted
comments.
2018-05-14 13:57:46 +02:00
Kim Gardner 400890237c Merge branch 'master' into admin-auth 2018-05-11 18:06:53 -04:00
Wyatt Johnson bde1dff33b changed to seperate slot 2018-05-11 14:45:03 -06:00
Wyatt Johnson f846ef0c06 Merge pull request #1595 from clintabrown/fix-my-profile-title-link
Fix My Profile story title link behavior
2018-05-11 14:37:23 -06:00
Wyatt Johnson fa31541fb7 Merge branch 'master' into fix-my-profile-title-link 2018-05-11 14:13:29 -06:00
Wyatt Johnson 4fcd5dd4f7 Merge pull request #1604 from coralproject/email-attach-fix
Email Attach Fixes
2018-05-11 13:05:45 -06:00
Chi Vinh Le 7d8d5a6115 Use lodash get 2018-05-11 20:46:32 +02:00
Chi Vinh Le f0dcd844a7 Fix excludeIf condition 2018-05-11 20:44:45 +02:00
Wyatt Johnson 9a1b9fb864 Merge branch 'master' into email-attach-fix 2018-05-11 11:39:08 -06:00
Wyatt Johnson 6cf4203c9b Update translations.yml 2018-05-11 11:38:54 -06:00
Kiwi 85e21f8090 Merge pull request #1606 from coralproject/ios-focus-zoom-issues
Disable autofocus on IOS Safari, prevent zoom on narrow screens
2018-05-11 14:31:21 -03:00
Chi Vinh Le 64583fabbe Merge branch 'email-attach-fix' of ssh://github.com/coralproject/talk into email-attach-fix 2018-05-11 18:40:26 +02:00
Kiwi bdaf5c633e Merge branch 'master' into email-attach-fix 2018-05-11 13:40:00 -03:00
Kiwi 945e2670f5 Merge branch 'master' into ios-focus-zoom-issues 2018-05-11 13:39:52 -03:00
Kiwi 4166e36e1e Merge pull request #1599 from coralproject/css-templates
CSS and Template Fixes + Improvements
2018-05-11 13:39:36 -03:00
Chi Vinh Le f018ccf33e Prevent showing add email address dialog when usernam is not set 2018-05-11 18:38:41 +02:00
Belén Curcio e61f325e86 Merge branch 'master' into fix-my-profile-title-link 2018-05-11 13:36:12 -03:00
Wyatt Johnson ef72b7b1d5 Merge branch 'master' into email-attach-fix 2018-05-11 10:33:32 -06:00
okbel a571cf830d Adding target 2018-05-11 13:32:55 -03:00
Kiwi 5dea051427 Merge branch 'master' into css-templates 2018-05-11 13:25:52 -03:00
Kim Gardner 730ef1a5c4 Merge pull request #1608 from mkonikov/copy-fix
Update download page copy
2018-05-11 12:25:39 -04:00
Belén Curcio 622b79b491 Removing unnecessary functions 2018-05-11 13:22:48 -03:00
Wyatt Johnson faa0ee8ceb added global wrap 2018-05-11 10:22:45 -06:00
Kiwi d67c25a791 Merge branch 'master' into email-attach-fix 2018-05-11 13:21:20 -03:00
Belén Curcio 32d615527a Merge branch 'master' into fix-my-profile-title-link 2018-05-11 13:08:13 -03:00
Wyatt Johnson 3a9051bf1b Merge branch 'master' into css-templates 2018-05-11 10:07:59 -06:00
Kim Gardner e8cce02bef Merge branch 'master' into global-switchoff 2018-05-11 11:56:35 -04:00
Kim Gardner 44c2d7847a Merge branch 'master' into copy-fix 2018-05-11 11:55:53 -04:00
Kiwi 93359d8250 Merge pull request #1613 from coralproject/wyattjoh-patch-1
Delete package-lock.json
2018-05-11 12:37:28 -03:00
Wyatt Johnson ba2985e891 Merge branch 'master' into email-attach-fix 2018-05-11 09:33:55 -06:00
Wyatt Johnson 42d4abf842 review updates 2018-05-11 09:33:29 -06:00
Wyatt Johnson 29ffe287cd Delete package-lock.json 2018-05-11 09:21:55 -06:00
Kiwi 05c13126ad Merge branch 'master' into ios-focus-zoom-issues 2018-05-11 12:21:15 -03:00
Kim Gardner 787dd8ec8a Merge branch 'master' into copy-fix 2018-05-11 11:18:22 -04:00
Kim Gardner 47c7125190 Merge pull request #1612 from mkonikov/capitalize
Capitalize "Information"
2018-05-11 11:17:29 -04:00
Chi Vinh Le fc5621a060 Add reference to story 2018-05-11 17:12:28 +02:00
Mendel Konikov f57f8397fe Capitalize "Information" 2018-05-11 11:01:15 -04:00
Fabian Neumann 1236e7a504 Disable/hide the reply buttons when commenting is disabled. 2018-05-11 12:52:44 +02:00
Fabian Neumann bae20c38ec Rename globalSwitchoff to disableCommenting. 2018-05-11 12:21:13 +02:00
Fabian Neumann d731357001 Remove plugin docs for global-switchoff. Not a plugin anymore. 2018-05-11 12:20:26 +02:00
Fabian Neumann f28a3f2f4e Add test case: err if trying to comment while it's disabled 2018-05-11 11:28:58 +02:00
Fabian Neumann 48fc3ab5db Move "global switchoff" code from plugin to core 2018-05-11 11:28:58 +02:00
Fabian Neumann fab15daacd Fix: use the correct keys to get the settings 2018-05-11 11:19:09 +02:00
Fabian Neumann 499030028c Add hooks to RootMutation to save our setting in the database. 2018-05-11 11:19:09 +02:00
Fabian Neumann bbd3050b95 Small refactoring 2018-05-11 11:19:09 +02:00
Fabian Neumann b73620bcb0 WIP 2018-05-11 11:19:09 +02:00
Mendel Konikov 2d1b675234 Update download page copy 2018-05-10 21:01:26 -04:00
Kim Gardner ac7bea209e Merge branch 'master' into email-attach-fix 2018-05-10 18:53:39 -04:00
Kim Gardner dd1b51e09b Merge branch 'master' into fix-my-profile-title-link 2018-05-10 18:52:56 -04:00
Wyatt Johnson 33be00a540 Added support for external signins on Admin 2018-05-10 16:44:19 -06:00
Chi Vinh Le 631206f360 Disable autofocus on IOS Safari, prevent zoom on narrow screens 2018-05-11 00:30:12 +02:00
Wyatt Johnson 4d6ef95416 Merge branch 'master' into css-templates 2018-05-10 14:55:25 -06:00
Wyatt Johnson 462f5e8206 Merge pull request #1603 from coralproject/losowsky-patch-2
Corrections and clarity
2018-05-10 14:55:12 -06:00
Wyatt Johnson 524aa3e863 Merge branch 'master' into losowsky-patch-2 2018-05-10 14:46:09 -06:00
Andrew Losowsky e0cada5bde Update 03-07-product-guide-trust.md 2018-05-10 13:44:03 -07:00
Wyatt Johnson dd0381d22a Merge branch 'master' into email-attach-fix 2018-05-10 14:43:37 -06:00
Wyatt Johnson 2e37f78705 Email Attach Fixes 2018-05-10 13:31:00 -06:00
Kim Gardner 0203a65656 Merge branch 'master' into fix-my-profile-title-link 2018-05-10 15:23:24 -04:00
Kim Gardner 4413e5616c Merge pull request #1596 from coralproject/tombstone-copy
Small tweak to tombstone copy
2018-05-10 15:23:07 -04:00
Wyatt Johnson b9c5024e68 Merge branch 'master' into css-templates 2018-05-10 12:11:48 -06:00
Kim Gardner 38f9c2f458 Merge branch 'master' into tombstone-copy 2018-05-10 13:42:26 -04:00
Kim Gardner fc14c5ab1c Merge pull request #1598 from coralproject/mobile-fix
Fit Delete My Account modals on mobile
2018-05-10 13:42:06 -04:00
Wyatt Johnson 75f9a697cb Merge branch 'master' into tombstone-copy 2018-05-10 11:34:11 -06:00
Kim Gardner 89f87dc9ad Merge branch 'master' into css-templates 2018-05-10 13:33:50 -04:00
Kim Gardner 85f45f390c Merge branch 'master' into mobile-fix 2018-05-10 13:33:15 -04:00
Kim Gardner 10317671ee Merge branch 'master' into losowsky-patch-2 2018-05-10 10:41:01 -04:00
Kim Gardner b16f15e47d Merge pull request #1601 from coralproject/check-correct-email
Allow changing email back and forth
2018-05-10 10:40:34 -04:00
Andrew Losowsky 2554b26110 Corrections and clarity
Fixed the incorrect thresholds and made the description clearer
2018-05-10 10:21:44 -04:00
Chi Vinh Le a092a197cf Check correct email 2018-05-09 23:45:53 +02:00
Kim Gardner e069d823a4 Merge pull request #1600 from coralproject/cli-fix
CLI Fixes
2018-05-09 16:50:59 -04:00
Wyatt Johnson ca3d56def8 asset refresh patched 2018-05-09 14:40:24 -06:00
Wyatt Johnson 9af3772087 Added json output for assets list
- Fixes #1597
2018-05-09 14:28:04 -06:00
Wyatt Johnson 51525de679 fixed set-role description 2018-05-09 14:17:43 -06:00
Wyatt Johnson 969206f905 copy adjustment 2018-05-09 14:14:48 -06:00
Wyatt Johnson 302cab8ca0 added header to graphiql 2018-05-09 14:12:27 -06:00
Wyatt Johnson 55a9c1e6b4 added link to graphiql 2018-05-09 14:05:16 -06:00
Wyatt Johnson 4426be5f39 improved dev experience, fixed css order 2018-05-09 13:56:05 -06:00
okbel 0ded5c72e9 adding media 2018-05-09 14:23:22 -03:00
Kim Gardner 1517611c9e Update tombstone copy 2018-05-09 11:00:02 -04:00
Clint Brown 8be4300ff4 Fix My Profile story title link behavior 2018-05-09 17:41:16 +10:00
Kim Gardner eda9a0cadf Merge pull request #1594 from coralproject/ignore-user
Fixed Ignore User Error
2018-05-08 18:08:42 -04:00
Wyatt Johnson 763e091e3f Merge branch 'master' into ignore-user 2018-05-08 16:00:56 -06:00
Kim Gardner 02d5a503c4 Merge pull request #1593 from coralproject/reply-missing-postdontagree
Pass postDontAgree to replies
2018-05-08 18:00:33 -04:00
Kim Gardner 13ffeb5889 Merge branch 'master' into reply-missing-postdontagree 2018-05-08 17:49:13 -04:00
Chi Vinh Le b50fde619e Pass postDontAgree to replies 2018-05-08 23:46:33 +02:00
Wyatt Johnson 7348bfc7c9 fixed error 2018-05-08 15:46:24 -06:00
Kim Gardner b27bfda759 Merge pull request #1592 from coralproject/delete-fix
Delete Fix
2018-05-08 17:40:08 -04:00
Wyatt Johnson 1815bd4d75 fix translation copy 2018-05-08 15:30:12 -06:00
Wyatt Johnson 8c29b0f1d4 fix for delete 2018-05-08 15:20:56 -06:00
Kiwi eb66cef4fc Merge pull request #1590 from coralproject/deleted-comments
Exclude deleted comments
2018-05-08 17:11:27 -03:00
Wyatt Johnson 17a0297911 fixed bug.. 2018-05-08 14:03:11 -06:00
Wyatt Johnson a1edbcf974 disallow adding a tag to a deleted comment 2018-05-08 14:03:11 -06:00
Kim Gardner 8c304c762d Merge branch 'deleted-comments' of git+ssh://github.com/coralproject/talk into deleted-comments 2018-05-08 15:49:51 -04:00
Kiwi d64af05093 Merge branch 'master' into deleted-comments 2018-05-08 16:25:05 -03:00
Kiwi 8aff2f69b3 Merge pull request #1591 from coralproject/translation-patch
Update translations.yml
2018-05-08 16:24:53 -03:00
Kiwi 4e9cf2b912 Merge branch 'master' into deleted-comments 2018-05-08 16:24:48 -03:00
Kim Gardner b10141716f Merge branch 'master' into translation-patch 2018-05-08 15:00:58 -04:00
Wyatt Johnson 4973a2021d Merge pull request #1589 from coralproject/notification-fixes
Fixes for notifications
2018-05-08 12:41:33 -06:00
Wyatt Johnson 7b86ec7d0a Update translations.yml 2018-05-08 12:06:52 -06:00
Wyatt Johnson e14af46c68 prevent actions against deleted comments 2018-05-08 12:02:04 -06:00
Wyatt Johnson 74dbfda633 Exclude deleted comments 2018-05-08 11:53:49 -06:00
Wyatt Johnson 44ba77b202 Merge branch 'master' into notification-fixes 2018-05-08 10:38:26 -06:00
Wyatt Johnson 9cee164a15 Merge pull request #1582 from coralproject/settings
Settings Cache Refactor
2018-05-08 10:38:13 -06:00
Wyatt Johnson 231dfe7997 Fixes for notifications 2018-05-08 09:32:14 -06:00
okbel d02bb20333 removing extra 2018-05-08 11:33:39 -03:00
okbel e9c18faf32 Deleted Comment display in Queues 2018-05-08 11:30:33 -03:00
okbel 2f94674b78 Adding CommentDeletedTombstone 2018-05-08 11:08:46 -03:00
Kim Gardner b7b60e6436 Merge branch 'master' into settings 2018-05-07 20:22:26 -04:00
Kim Gardner 778064d756 Merge pull request #1585 from coralproject/docs-fixes
Links, typos, updates for docs
2018-05-07 20:21:34 -04:00
Kim Gardner 57917335cb Merge branch 'master' into settings 2018-05-07 20:21:17 -04:00
Wyatt Johnson 7926c5ccbf Merge branch 'master' into docs-fixes 2018-05-07 18:13:16 -06:00
Kim Gardner 7aad40b0e3 Merge pull request #1587 from coralproject/email
Fixed email in use error
2018-05-07 20:11:09 -04:00
Wyatt Johnson a7c9f01125 fixed bug 2018-05-07 17:59:43 -06:00
Kim Gardner e74b8c9099 Merge branch 'master' into email 2018-05-07 19:55:37 -04:00
Kim Gardner c6a76990f4 Merge pull request #1586 from coralproject/password
Fixed bug with password form
2018-05-07 19:55:21 -04:00
Wyatt Johnson 08a857e07c Fixed email in use error 2018-05-07 17:51:46 -06:00
Wyatt Johnson 10a99aab88 Fixed bug with password form 2018-05-07 17:47:02 -06:00
Wyatt Johnson 15c3a96291 fixed settings 2018-05-07 17:16:52 -06:00
Wyatt Johnson 7b0a7f7d9a Merge branch 'master' into settings 2018-05-07 16:30:21 -06:00
Kim Gardner 926364ad72 Merge pull request #1584 from coralproject/trace
Tracing
2018-05-07 18:30:08 -04:00
Kim Gardner 0e7961aa1c Fix broken links 2018-05-07 17:27:59 -04:00
Kim Gardner 890730a26d Merge branch 'master' into docs-fixes 2018-05-07 17:20:21 -04:00
Kim Gardner a2f5af69b4 Merge branch 'master' into trace 2018-05-07 17:20:16 -04:00
Kim Gardner 0d1f3d1da3 Merge branch 'master' into settings 2018-05-07 17:19:54 -04:00
Kim Gardner 1c7606b651 Merge pull request #1583 from coralproject/security
Node Security Patch
2018-05-07 17:19:27 -04:00
Kim Gardner 7a32bf855d Links, typos, updates for docs 2018-05-07 17:14:43 -04:00
Wyatt Johnson cb50a1e709 updated excemptions 2018-05-07 15:12:37 -06:00
Wyatt Johnson 86595b4dd0 Added exception for metascraper 2018-05-07 15:07:21 -06:00
Wyatt Johnson fa2730a661 Upgraded lodash 2018-05-07 15:06:53 -06:00
Wyatt Johnson 01039aa411 include trace ID in each downstream request 2018-05-07 14:57:51 -06:00
Wyatt Johnson 732ff98f9b fixed test 2018-05-07 14:50:03 -06:00
Wyatt Johnson 3024300a3f Merge branch 'master' into settings 2018-05-07 14:43:07 -06:00
Kim Gardner 7f543f543b Merge pull request #1581 from coralproject/fix-add-email-dialog
Fix Add Email Dialog
2018-05-07 16:36:31 -04:00
Wyatt Johnson c9957add72 Merge branch 'master' into settings 2018-05-07 14:31:09 -06:00
Wyatt Johnson 2b1108cd88 Settings Cache Refactor 2018-05-07 14:27:00 -06:00
Chi Vinh Le 5953ed711a Remove unused code 2018-05-07 22:21:25 +02:00
Chi Vinh Le 8c2733734a Fix Add Email Dialog 2018-05-07 22:16:36 +02:00
Kim Gardner 66bb61ed13 Merge pull request #1580 from coralproject/save-icon
Fix save icon
2018-05-07 15:35:23 -04:00
Kim Gardner f2ea3bdd42 Merge branch 'master' into save-icon 2018-05-07 15:23:11 -04:00
Kim Gardner 71bda42cfb Merge pull request #1577 from coralproject/inputfield-controlled
Fix InputField controlled / uncontrolled mode
2018-05-07 15:23:02 -04:00
Kim Gardner 030b805290 Merge branch 'master' into save-icon 2018-05-07 15:22:09 -04:00
Kim Gardner 1ca7fd58bd Merge branch 'master' into inputfield-controlled 2018-05-07 15:10:45 -04:00
Kim Gardner 7aa31b7cb2 Merge pull request #1571 from coralproject/change-pass-error-bug
Change Password Errors BUG
2018-05-07 15:10:09 -04:00
Chi Vinh Le 4fb511e488 Fix save icon 2018-05-07 21:07:46 +02:00
Kim Gardner e3fa99100b Merge branch 'master' into change-pass-error-bug 2018-05-07 14:59:05 -04:00
Kim Gardner 5aeb16fc99 Merge pull request #1579 from coralproject/bug-fixes
Fixes password validation field for Change Email Dialog
2018-05-07 14:58:56 -04:00
Kim Gardner 21e92b92f3 Merge branch 'master' into bug-fixes 2018-05-07 14:38:55 -04:00
Kim Gardner ecf05d76c0 Merge branch 'master' into inputfield-controlled 2018-05-07 14:37:51 -04:00
Kim Gardner 0f47378ae3 Merge pull request #1576 from coralproject/restore-cancel
Restore cancel buttons
2018-05-07 14:37:00 -04:00
Belen Curcio 46e5efbd55 validation for password input in change email 2018-05-07 15:00:55 -03:00
Chi Vinh Le 06abccabb4 Fix InputField controlled / uncontrolled mode 2018-05-07 18:26:37 +02:00
Chi Vinh Le 565ba2af06 Restore cancel buttons 2018-05-07 17:54:59 +02:00
Wyatt Johnson 802a3bd656 Merge pull request #1573 from coralproject/copy-changes
Copy and bug fixes
2018-05-05 10:04:56 -06:00
Wyatt Johnson 413b6a2a60 Merge branch 'master' into copy-changes 2018-05-05 09:40:50 -06:00
Wyatt Johnson e37346f544 Merge pull request #1572 from coralproject/csv-copy-changes
CSV Copy Changes
2018-05-05 09:40:06 -06:00
Kim Gardner ce92765218 Swap DeletedOn and DeletedFor 2018-05-04 17:40:10 -04:00
Kim Gardner 8b5cb9d96d Copy tweaks 2018-05-04 17:36:05 -04:00
Kim Gardner 7cf991d672 Change copy 2018-05-04 17:03:22 -04:00
Belen Curcio 4312b8d024 bug 2018-05-04 17:49:40 -03:00
Kim Gardner 910beb0f40 Merge pull request #1547 from jerodb/es-translations
Changed general spanish translations
2018-05-04 16:23:04 -04:00
Kim Gardner 810cb222f9 Merge branch 'master' into es-translations 2018-05-04 15:48:56 -04:00
Jero 7a7dcdd7c6 corrections in spanish translations 2018-05-04 16:35:24 -03:00
Kim Gardner 66f1fd7d8a Merge pull request #1569 from coralproject/username-change-fixes
Username Change Fixes
2018-05-04 14:55:44 -04:00
Wyatt Johnson 7362c6c993 Merge branch 'master' into username-change-fixes 2018-05-04 12:09:52 -06:00
Wyatt Johnson a0fbfe4ff4 Merge pull request #1568 from coralproject/forgot-password-change
Forgot password in Change Password
2018-05-04 12:09:38 -06:00
Wyatt Johnson 103543f830 Merge branch 'master' into forgot-password-change 2018-05-04 11:59:10 -06:00
Wyatt Johnson f2d8e49d5b Merge branch 'master' into username-change-fixes 2018-05-04 11:58:46 -06:00
Kim Gardner ade9b99a09 Merge pull request #1570 from coralproject/small-styling-tweaks
GDPR styling tweaks
2018-05-04 13:53:39 -04:00
Wyatt Johnson 6bad9e5306 Fixed bug with button placement 2018-05-04 11:50:37 -06:00
Wyatt Johnson 2a5075f434 Form update 2018-05-04 11:33:20 -06:00
Chi Vinh Le d41984f171 Remove unused field 2018-05-04 19:32:29 +02:00
Chi Vinh Le 4bc8a167a4 Styling tweaks 2018-05-04 19:29:05 +02:00
Wyatt Johnson 9a8f0e98a4 Username Change Fixes 2018-05-04 11:16:53 -06:00
Belén Curcio 05ec8eaee2 Merge branch 'master' into forgot-password-change 2018-05-04 13:40:22 -03:00
Belen Curcio eabcbc36c6 forgot password 2018-05-04 13:34:20 -03:00
Kiwi 822193bba5 Merge pull request #1556 from coralproject/user-detail-enh
User detail refactor
2018-05-04 17:46:52 +02:00
Kim Gardner a008503b52 Merge branch 'master' into user-detail-enh 2018-05-04 09:14:06 -04:00
Kim Gardner 401593afde Merge pull request #1564 from coralproject/email-auth-gdpr
[GDPR] Attach Local Authentication (External Auth)
2018-05-04 09:13:47 -04:00
okbel 7f9c71a802 Merge branch 'master' of github.com:coralproject/talk into email-auth-gdpr
* 'master' of github.com:coralproject/talk:
  fix
  handle confirmed email better
  standardized styles, fixed mutation bug
  password patches
  fixed merge error
  Fix build fail
  Missed an s
  docs patch
  Add feature overview to GDPR docs
  InputField conflict
  moving mutations to /hocs folder
  moving mutations to /hocs folder
  withUpdateEmailAddress in the plugins hoc
2018-05-04 09:46:58 -03:00
okbel f3a3746d6b Merge branch 'email-auth-gdpr' of github.com:coralproject/talk into email-auth-gdpr
* 'email-auth-gdpr' of github.com:coralproject/talk: (51 commits)
  JWT_Audience is listed twice in the docs under required keys
  moved settings loading into try/catch block
  Grammar
  fix
  Fix email subject variables
  Update email copy
  Styling
  Styling
  Updating InputField
  Updating InputField
  added emails around account deletion
  moving mutations to /hocs folder
  typo
  cleaned up config as js instead of json file
  added space
  added durations to configuration file
  Update copy to reflect ability to take action up until account is deleted
  translations
  copy fixes
  added email to final step
  ...
2018-05-04 09:41:22 -03:00
Kim Gardner e51736040f Merge branch 'master' into user-detail-enh 2018-05-03 20:27:16 -04:00
Kim Gardner 9d47d3ff91 Merge pull request #1538 from coralproject/gdpr-email
[GDPR] Change Email (Local)
2018-05-03 20:08:27 -04:00
Wyatt Johnson 15df20e720 fix 2018-05-03 17:57:53 -06:00
Kim Gardner 00b6f0816c Merge branch 'master' into gdpr-email 2018-05-03 19:52:39 -04:00
Wyatt Johnson 949925586f handle confirmed email better 2018-05-03 17:50:53 -06:00
Wyatt Johnson 3fbd655cb8 Merge branch 'master' into email-auth-gdpr 2018-05-03 16:22:43 -06:00
Wyatt Johnson 848ec34e99 Merge pull request #1566 from davisshaver/patch-1
JWT_Audience is listed twice in the docs under required keys
2018-05-03 16:22:06 -06:00
Wyatt Johnson fa66f07db6 standardized styles, fixed mutation bug 2018-05-03 15:58:52 -06:00
Wyatt Johnson ea71b779d2 password patches 2018-05-03 15:51:50 -06:00
Wyatt Johnson b5958d5879 fixed merge error 2018-05-03 15:45:43 -06:00
Kim Gardner 35cefd5570 Fix build fail 2018-05-03 17:42:47 -04:00
Davis Shaver 31cb70fa77 JWT_Audience is listed twice in the docs under required keys 2018-05-03 17:42:10 -04:00
Kim Gardner aee963ce39 Missed an s 2018-05-03 17:34:41 -04:00
Wyatt Johnson bc3ceac61a docs patch 2018-05-03 15:26:50 -06:00
Kim Gardner ae9732c9b4 Merge branch 'gdpr-email' of git+ssh://github.com/coralproject/talk into gdpr-email 2018-05-03 17:19:17 -04:00
Wyatt Johnson c783d15df3 Merge branch 'master' into gdpr-email 2018-05-03 15:18:22 -06:00
Wyatt Johnson e9fdaa1b5a Merge branch 'master' into email-auth-gdpr 2018-05-03 15:13:13 -06:00
Kim Gardner 8bfe344c39 Merge pull request #1536 from coralproject/gdpr-delete
[GDPR] Delete Account
2018-05-03 17:08:55 -04:00
Kim Gardner a20e050559 Merge branch 'gdpr-email' of git+ssh://github.com/coralproject/talk into gdpr-email 2018-05-03 17:08:39 -04:00
Kim Gardner 58b73a4d0a Add feature overview to GDPR docs 2018-05-03 17:08:20 -04:00
Wyatt Johnson 2e7bad3508 moved settings loading into try/catch block 2018-05-03 14:57:11 -06:00
Kim Gardner bfda6a4ce8 Merge branch 'master' into gdpr-email 2018-05-03 16:54:54 -04:00
Kim Gardner 9d448d4185 Merge branch 'master' into gdpr-delete 2018-05-03 16:46:32 -04:00
Kim Gardner 68dfb9cad7 Merge pull request #1559 from coralproject/cli
CLI Fixes
2018-05-03 16:45:52 -04:00
Kim Gardner 3e9d835eb2 Grammar 2018-05-03 16:37:19 -04:00
Wyatt Johnson f5099d94bc fix 2018-05-03 14:32:56 -06:00
Kim Gardner d9806c0ecc Fix email subject variables 2018-05-03 16:23:47 -04:00
Wyatt Johnson edf32a911d Merge branch 'master' into cli 2018-05-03 14:20:05 -06:00
Kim Gardner 903b74cb31 Update email copy 2018-05-03 15:43:22 -04:00
okbel 070ecbaafc translations 2018-05-03 16:30:15 -03:00
okbel f9f7855775 Merge branch 'email-auth-gdpr' of github.com:coralproject/talk into email-auth-gdpr
* 'email-auth-gdpr' of github.com:coralproject/talk:
  added docs
  Added TALK_ prefix to constants RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER
  cleaned up refs to passwor dhash
  RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER now can be set with env vars
2018-05-03 16:25:17 -03:00
okbel 438c515d2f moving mutations to /hocs folder 2018-05-03 16:06:28 -03:00
okbel 65aa90904a Styling 2018-05-03 16:00:25 -03:00
okbel 140ef3eb5e Styling 2018-05-03 15:57:00 -03:00
okbel 467aecf0ee Merge branch 'gdpr-delete' of github.com:coralproject/talk into gdpr-delete
* 'gdpr-delete' of github.com:coralproject/talk:
  added emails around account deletion
2018-05-03 15:48:49 -03:00
okbel 10dbce55ba Updating InputField 2018-05-03 15:45:19 -03:00
okbel 6cfebb408f Updating InputField 2018-05-03 15:42:28 -03:00
okbel 29a840fe06 InputField conflict 2018-05-03 15:38:17 -03:00
Wyatt Johnson 690e6752ee added emails around account deletion 2018-05-03 12:29:05 -06:00
okbel 788cf25fa5 moving mutations to /hocs folder 2018-05-03 15:20:07 -03:00
okbel 687d0555c8 moving mutations to /hocs folder 2018-05-03 15:18:09 -03:00
okbel bc9e76c889 Merge branch 'gdpr-delete' of github.com:coralproject/talk into gdpr-delete
* 'gdpr-delete' of github.com:coralproject/talk:
  typo
  cleaned up config as js instead of json file
  added space
  added durations to configuration file
  Update copy to reflect ability to take action up until account is deleted
  added docs
  Added TALK_ prefix to constants RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER
  RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER now can be set with env vars
2018-05-03 15:17:04 -03:00
okbel f173f495a5 moving mutations to /hocs folder 2018-05-03 15:15:58 -03:00
okbel 2b52f07c45 Merge branch 'gdpr-email' of github.com:coralproject/talk into gdpr-email
* 'gdpr-email' of github.com:coralproject/talk:
  added docs
  Added TALK_ prefix to constants RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER
  RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER now can be set with env vars
  Update version to 4.4.0
2018-05-03 15:13:09 -03:00
okbel 8a9af89699 withUpdateEmailAddress in the plugins hoc 2018-05-03 15:12:23 -03:00
Kim Gardner 64cb665124 typo 2018-05-03 14:00:07 -04:00
Wyatt Johnson df29e610b3 cleaned up config as js instead of json file 2018-05-03 11:40:55 -06:00
Wyatt Johnson 20c5804559 added space 2018-05-03 11:38:23 -06:00
Wyatt Johnson 06b08756e7 added durations to configuration file 2018-05-03 11:36:34 -06:00
Kim Gardner e23933e9df Merge branch 'master' into email-auth-gdpr 2018-05-03 13:28:34 -04:00
Kim Gardner e1f6dc49a8 Merge branch 'master' into gdpr-email 2018-05-03 13:18:25 -04:00
Kim Gardner 8caf995517 Merge branch 'master' into gdpr-delete 2018-05-03 13:17:44 -04:00
Kim Gardner 287cff289b Update copy to reflect ability to take action up until account is deleted 2018-05-03 13:04:05 -04:00
Wyatt Johnson 368b6fb847 Merge pull request #1565 from cristiandean/recaptcha-env
Set RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER by env vars
2018-05-03 10:58:16 -06:00
okbel 3b5a45ec01 translations 2018-05-03 13:45:33 -03:00
Wyatt Johnson 0e20ddb2fd added docs 2018-05-03 10:40:06 -06:00
okbel f6d3f4cb14 translations 2018-05-03 13:32:52 -03:00
Wyatt Johnson 375f1bb6b1 copy fixes 2018-05-03 10:09:36 -06:00
Wyatt Johnson 6485b1f080 added email to final step 2018-05-03 10:09:36 -06:00
Cristian 8b35f2300a Added TALK_ prefix to constants RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER 2018-05-03 13:06:47 -03:00
Kim Gardner 0caa82c1c4 Typo 2018-05-03 11:59:27 -04:00
okbel 94b3ab4ac8 translations 2018-05-03 12:59:03 -03:00
Wyatt Johnson 8fee07a3f8 cleaned up refs to passwor dhash 2018-05-03 09:58:49 -06:00
Cristian 12701942c6 RECAPTCHA_WINDOW and RECAPTCHA_INCORRECT_TRIGGER now can be set with env vars 2018-05-03 12:57:51 -03:00
Wyatt Johnson bab9347d06 adjusted copy 2018-05-03 09:53:24 -06:00
Kim Gardner b995da8301 Unbold a word 2018-05-03 11:37:48 -04:00
Wyatt Johnson 51847cf955 Updated copy for delete 2018-05-03 09:26:48 -06:00
Wyatt Johnson ee0f734705 cleaned up download mutations 2018-05-03 09:13:44 -06:00
Wyatt Johnson 87d0c99558 moved hoc's into plugin 2018-05-03 08:59:26 -06:00
Kim Gardner 225a04fed1 Copy fixes 2018-05-03 10:53:16 -04:00
Wyatt Johnson a42135c3bb merge bug 2018-05-03 08:39:34 -06:00
okbel a9132c1353 stream fragment 2018-05-03 11:07:58 -03:00
okbel fff6e1c231 Review changes 2018-05-03 10:24:43 -03:00
Kim Gardner 0791a2731b Merge branch 'master' into gdpr-email 2018-05-02 22:18:26 -04:00
okbel aa6c9890b2 Merge branch 'email-auth-gdpr' of github.com:coralproject/talk into email-auth-gdpr
* 'email-auth-gdpr' of github.com:coralproject/talk:
  Update version to 4.4.0
2018-05-02 21:02:10 -03:00
okbel a649bd8252 done - but translations 2018-05-02 21:01:08 -03:00
okbel 59cac9db8b Adding reducer 2018-05-02 20:58:34 -03:00
okbel 478770f6c6 Changes 2018-05-02 20:41:32 -03:00
Belén Curcio 262c68ca8f Merge branch 'master' into email-auth-gdpr 2018-05-02 20:14:32 -03:00
okbel e409695979 Merge branch 'gdpr-delete' of github.com:coralproject/talk into gdpr-delete
* 'gdpr-delete' of github.com:coralproject/talk:
  Update version to 4.4.0
2018-05-02 20:09:49 -03:00
okbel ccb62263c1 checking me null 2018-05-02 20:08:29 -03:00
Wyatt Johnson 74acf73396 Merge branch 'master' into gdpr-delete 2018-05-02 17:00:51 -06:00
okbel cdae2796a5 Changes 2018-05-02 18:48:52 -03:00
okbel 09d20257ac Changes 2018-05-02 18:46:41 -03:00
okbel 1bf440c4a6 Changes 2018-05-02 18:43:06 -03:00
okbel 3b2deeb007 Checking if email verification is required 2018-05-02 18:35:15 -03:00
okbel b04fc1faf8 wip 2018-05-02 18:15:04 -03:00
Wyatt Johnson db11dc4928 Merge pull request #1563 from coralproject/version-4-4-0
Update version to 4.4.0
2018-05-02 14:37:07 -06:00
okbel bfb4b790d4 Adding error 2018-05-02 16:49:56 -03:00
okbel c7db780582 Updating the cache with data from the fragment 2018-05-02 16:46:20 -03:00
Kim Gardner 45c75f3c48 Update version to 4.4.0 2018-05-02 15:22:17 -04:00
Wyatt Johnson c1492d1065 Added incorrect password error 2018-05-02 13:22:15 -06:00
Wyatt Johnson 0159918049 docs updates 2018-05-02 13:04:17 -06:00
Kim Gardner cb9b02c180 remove profile-settings from gitignore 2018-05-02 14:20:19 -04:00
okbel c8e5678c9c Using fragments :) 2018-05-02 14:18:40 -03:00
okbel 48a78735bd Importing translations 2018-05-02 14:11:11 -03:00
okbel 8dcaf8ea4c Moving the translations too 2018-05-02 14:08:29 -03:00
okbel 58cc078d25 Moving gdpr to talk-plugin-profile-data 2018-05-02 14:03:21 -03:00
okbel c57acddfc0 Moving gdpr to talk-plugin-profile-data 2018-05-02 14:01:03 -03:00
okbel 780bd42ceb Moving gdpr to talk-plugin-local-auth 2018-05-02 13:49:23 -03:00
okbel b2f37733e8 Sending correct parameters 2018-05-02 13:39:08 -03:00
okbel 6c0c76328f merge conflict 2018-05-02 13:28:03 -03:00
Wyatt Johnson 7c16ae2220 cli fix 2018-05-02 10:17:41 -06:00
Wyatt Johnson 26438d0b90 patched json 2018-05-02 09:59:10 -06:00
Wyatt Johnson ddaa8eb858 Merge branch 'master' into gdpr-delete 2018-05-02 09:58:04 -06:00
Kim Gardner 72ca9b38bb Merge branch 'master' into gdpr-email 2018-05-02 11:21:11 -04:00
Kim Gardner 26b9dcdaa9 Merge branch 'master' into cli 2018-05-02 11:13:42 -04:00
Kim Gardner 9dc040f6d2 Merge pull request #1560 from mkonikov/rich-text-docs
Add note explaining possible plugin conflict
2018-05-02 11:13:10 -04:00
Mendel Konikov 018addc6ad Remove space to correct markdown link formatting 2018-05-01 20:37:42 -04:00
Mendel Konikov c3d01be0df Add note explaining possible plugin conflict 2018-05-01 20:34:42 -04:00
Wyatt Johnson d6828c5ef4 cli fixes 2018-05-01 16:27:47 -06:00
Kim Gardner 17a63c0bf9 Merge branch 'master' into gdpr-email 2018-05-01 17:50:27 -04:00
Kim Gardner a8dd1ec38b Merge pull request #1557 from coralproject/indexes
Index Creation Patch
2018-05-01 17:48:48 -04:00
Wyatt Johnson d12310026b Fixes to shema loading 2018-05-01 15:41:05 -06:00
okbel 864e06222c Adding input 2018-05-01 17:59:31 -03:00
okbel d5fa7455e5 Adding InputField 2018-05-01 17:55:01 -03:00
okbel 49fcc1ea43 Adding missing slot 2018-05-01 17:30:57 -03:00
okbel ff7ee2aefc Updating cache 2018-05-01 17:18:58 -03:00
okbel 5eead8b7ee Adding AccountDeletionRequestedSign.js 2018-05-01 16:32:42 -03:00
okbel 9b4d650427 Wip: mutations, styles and functionality 2018-05-01 16:18:37 -03:00
okbel 5c806174bb Adding withRequestAccountDeletion, withRequestDownloadLink, withCancelAccountDeletion 2018-05-01 15:51:56 -03:00
okbel 3bb91f6833 Adding withRequestAccountDeletion, withRequestDownloadLink, withCancelAccountDeletion 2018-05-01 15:43:10 -03:00
Wyatt Johnson b014225b73 fixes for index creation 2018-05-01 12:02:39 -06:00
Kim Gardner 92d32aaa8d Merge branch 'master' into user-detail-enh 2018-05-01 13:41:10 -04:00
Kim Gardner 7717462300 Merge pull request #1555 from coralproject/configure-enh
Configure enhancements
2018-05-01 13:32:38 -04:00
Kim Gardner 06682225c8 Fix error message 2018-05-01 13:25:33 -04:00
Kim Gardner 3145411921 Merge branch 'master' into configure-enh 2018-05-01 13:23:14 -04:00
okbel bd21d9a1a1 fix b 2018-05-01 14:19:43 -03:00
okbel f4cb16e56e styles wip 2018-05-01 14:14:43 -03:00
okbel 867523140c Adding StepProgress component, and all the steps 2018-05-01 14:09:43 -03:00
Kim Gardner a12e7a0e90 Merge pull request #1533 from coralproject/gdpr-username
[GDPR] Username Change
2018-05-01 12:55:24 -04:00
Kim Gardner 9c809f99c5 Merge branch 'master' into gdpr-email 2018-05-01 12:51:05 -04:00
Kim Gardner 16a21a0562 Merge branch 'master' into gdpr-username 2018-05-01 12:42:12 -04:00
Chi Vinh Le e0dad39600 Merge branch 'configure-enh' of ssh://github.com/coralproject/talk into configure-enh 2018-05-01 18:14:34 +02:00
Chi Vinh Le 74821a4d4c Readd save dialog on section change 2018-05-01 18:14:07 +02:00
Kiwi 41b3245bf4 Merge branch 'master' into configure-enh 2018-05-01 17:58:56 +02:00
Kiwi 40b157206a Merge branch 'master' into user-detail-enh 2018-05-01 17:58:02 +02:00
Kim Gardner 71cdd146fa Merge pull request #1554 from coralproject/change-config-tab-copy
Update copy for stream Configure tab
2018-05-01 11:39:33 -04:00
Chi Vinh Le d07b77b8f7 Remove forgotten console.log 2018-05-01 16:49:44 +02:00
Chi Vinh Le b2988e540e Move mutation logic to coral-admin 2018-05-01 16:48:52 +02:00
Chi Vinh Le 68b1670a55 Prevent reload or closing tab or window with pending data 2018-05-01 16:33:21 +02:00
Chi Vinh Le 2af3a94ce4 No dialog when switching sections 2018-05-01 16:29:40 +02:00
Chi Vinh Le fd3f5e5116 Cleanup leave hook 2018-05-01 16:19:47 +02:00
Chi Vinh Le e8cd938b65 Move next route out of state 2018-05-01 16:18:17 +02:00
Chi Vinh Le 9310a4734d Fix viewing/editing empty org contact email 2018-05-01 16:16:41 +02:00
Andrew Losowsky 8d1d96884e small wording change
changed 'Customize' for 'Change' (more plain English)
2018-05-01 09:08:58 -04:00
okbel 876eb1e413 wip 2018-05-01 00:17:57 -03:00
okbel 720089d3c2 Initial Delete 2018-04-30 23:45:13 -03:00
okbel bbd02dda81 Finished with crossed steps 2018-04-30 23:14:47 -03:00
okbel f5563c80b1 Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-email
* 'gdpr-username' of github.com:coralproject/talk:
  ChangeUsername instead of setUsername
2018-04-30 22:04:18 -03:00
okbel 4cd7ad9c33 ChangeUsername instead of setUsername 2018-04-30 20:20:58 -03:00
okbel 227e52c16e Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-email
* 'gdpr-username' of github.com:coralproject/talk:
  Adding translations
  Catching if username cant be updated
  fixes for tests
  fixed tests
  Fixed bug in mutation
2018-04-30 20:14:15 -03:00
okbel 5dbf379bde Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-username
* 'gdpr-username' of github.com:coralproject/talk:
  fixes for tests
  fixed tests
2018-04-30 20:04:09 -03:00
okbel cdb392cd0e Adding translations 2018-04-30 20:03:01 -03:00
okbel ad342c4bb3 Catching if username cant be updated 2018-04-30 19:56:53 -03:00
Kim Gardner 4212f0b014 Update copy 2018-04-30 18:22:35 -04:00
Wyatt Johnson b42d325cb0 fixes for tests 2018-04-30 16:13:48 -06:00
Wyatt Johnson 7a0c9c85bc fixed tests 2018-04-30 15:59:35 -06:00
Wyatt Johnson 31f0cb12b3 Fixed bug in mutation 2018-04-30 15:43:12 -06:00
Wyatt Johnson 457f305062 Merge branch 'master' into gdpr-email 2018-04-30 14:10:52 -06:00
Kim Gardner b31b01bc50 Merge branch 'master' into gdpr-username 2018-04-30 16:01:58 -04:00
Kim Gardner 743327a53b Merge pull request #1543 from coralproject/remove-profile-settings-refs
Remove refs to talk-plugin-profile-settings
2018-04-30 16:01:35 -04:00
okbel 691bfa4e30 Passing Dialog content 2018-04-30 16:53:05 -03:00
okbel 58108f257f Addin g withUpdateEmailAddress 2018-04-30 16:28:08 -03:00
Wyatt Johnson ec8f42496d Merge branch 'master' into remove-profile-settings-refs 2018-04-30 13:21:04 -06:00
okbel 35e8c005f3 WIP: Steps 2018-04-30 16:20:09 -03:00
Wyatt Johnson a5f94360b3 Merge pull request #1546 from jerodb/plugin-auth-translation
Added translation for the talk-plugin-auth's password error
2018-04-30 13:18:46 -06:00
okbel 1574dabd69 Merge branch 'gdpr-email' of github.com:coralproject/talk into gdpr-email
* 'gdpr-email' of github.com:coralproject/talk:
  fixed typo
  nightwatchjs.org doesn't support HTTPS
  added viewing and sorting spanish translations
  Added email.password_reset.subject translation
2018-04-30 16:04:44 -03:00
okbel be86b70b24 WIP: Steps 2018-04-30 16:01:35 -03:00
Belén Curcio 05a6399638 Merge branch 'master' into gdpr-email 2018-04-30 15:44:46 -03:00
Belén Curcio dbb9686074 Merge branch 'master' into remove-profile-settings-refs 2018-04-30 14:45:14 -03:00
Kim Gardner 4e10a23ad0 Merge branch 'master' into plugin-auth-translation 2018-04-30 13:43:57 -04:00
Kim Gardner e48f07f4dd Merge pull request #1548 from jerodb/password_reset-subject-translation
Added translation for email's subject
2018-04-30 13:19:27 -04:00
Kim Gardner 1143f74ba8 Merge branch 'master' into password_reset-subject-translation 2018-04-30 12:58:54 -04:00
Kim Gardner bc5a045886 Merge pull request #1549 from jerodb/viewing-sorting-translations-es
Changed spanish translations for the viewing options list
2018-04-30 12:58:20 -04:00
okbel 8df9a1e66e wip 2018-04-30 13:47:15 -03:00
Kim Gardner 4130ad5217 Merge branch 'master' into viewing-sorting-translations-es 2018-04-30 12:43:48 -04:00
Wyatt Johnson 1e8c3de221 Merge pull request #1550 from theel0ja/patch-1
nightwatchjs.org doesn't support HTTPS
2018-04-30 10:23:55 -06:00
Kim Gardner fdf5ca1d7a Merge branch 'master' into patch-1 2018-04-30 11:15:36 -04:00
Kim Gardner 612230ad0c Merge pull request #1551 from theel0ja/patch-2
fixed typo
2018-04-30 11:15:03 -04:00
okbel e67d68267c Adding Change Email 2018-04-29 22:00:42 -03:00
okbel 9419b67fff Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-email
* 'gdpr-username' of github.com:coralproject/talk: (36 commits)
  performing mutation
  Spanish translations
  More translations
  No empty username, no same username
  Decrease font-size and padding in Flag Comment popup a bit.
  Translations
  Adding translations
  Adding translations
  InputField refactor
  wip more validations
  Full functionality, needs translation
  Adding Dialog, styles and more
  Use email vs e-mail
  Small fix
  Adding withChangeUsername to plugin hocs, wip and more
  Introducing profileHeader slot
  Adding a notification after saving
  Fix lint
  Add missing ctx arg for CLI users create
  final refactor, done.
  ...
2018-04-29 20:29:54 -03:00
Elias Ojala edbd21f25f fixed typo 2018-04-28 23:02:29 +03:00
Elias Ojala f42e9dab4c nightwatchjs.org doesn't support HTTPS 2018-04-28 12:27:15 +03:00
Jero 90c235d9d1 Added the password error translation 2018-04-27 10:52:38 -03:00
Jero 3dbe59fd27 Translation for talk-plugin-auth password_error added 2018-04-27 10:25:59 -03:00
Jero 885f186e39 added viewing and sorting spanish translations 2018-04-26 19:19:06 -03:00
Kim Gardner 12d48d6248 Merge branch 'master' into gdpr-username 2018-04-26 18:02:13 -04:00
Jero 878cbb9195 Added email.password_reset.subject translation 2018-04-26 18:35:45 -03:00
Jero b8d435fb07 Added missing spanish translations 2018-04-26 18:29:25 -03:00
okbel a7e09352ef performing mutation 2018-04-26 18:09:27 -03:00
okbel 0a0bbbb3ce Spanish translations 2018-04-26 17:55:44 -03:00
okbel ad5c51c486 More translations 2018-04-26 17:53:02 -03:00
okbel ab02b1b6ca No empty username, no same username 2018-04-26 17:00:08 -03:00
Kim Gardner 2d6a6d652e Merge pull request #1545 from conversario/popupmenu-style
Decrease font-size and padding in Report comment popup
2018-04-26 13:36:26 -04:00
Kim Gardner 287d0bf538 Merge branch 'master' into popupmenu-style 2018-04-26 12:47:56 -04:00
Fabian Neumann 8643b1fbf2 Decrease font-size and padding in Flag Comment popup a bit. 2018-04-26 17:52:03 +02:00
okbel ba7de6bf81 Translations 2018-04-26 11:25:40 -03:00
okbel 6495c0a16b Adding translations 2018-04-26 11:19:25 -03:00
okbel 2db9489646 Adding translations 2018-04-26 11:15:35 -03:00
okbel 8f6691f7a4 InputField refactor 2018-04-26 11:15:18 -03:00
Kim Gardner dd9a9d5882 Remove refs to talk-plugin-profile-settings 2018-04-25 15:30:40 -04:00
okbel cbdd1921ec Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-username
* 'gdpr-username' of github.com:coralproject/talk:
  Use email vs e-mail
  Small fix
2018-04-25 13:36:14 -03:00
okbel aefac2056e wip more validations 2018-04-25 13:36:00 -03:00
Kim Gardner 2fa81111ba Merge branch 'master' into gdpr-username 2018-04-25 12:34:15 -04:00
Kim Gardner 2048a2cc7f Merge pull request #1541 from coralproject/docs-formatting
Small docs fix
2018-04-25 12:33:47 -04:00
okbel 5a0a30fc12 Merge branch 'gdpr-username' of github.com:coralproject/talk into gdpr-username
* 'gdpr-username' of github.com:coralproject/talk:
  Fix lint
  Add missing ctx arg for CLI users create
2018-04-25 13:13:38 -03:00
Belén Curcio 358d56c2cf Merge branch 'master' into docs-formatting 2018-04-25 13:10:55 -03:00
Belén Curcio 6376fe21cb Merge pull request #1542 from coralproject/grammar-fixes
Use email vs e-mail
2018-04-25 13:10:29 -03:00
okbel a79d71da7d Full functionality, needs translation 2018-04-25 12:53:03 -03:00
okbel 754b5c5fbb Adding Dialog, styles and more 2018-04-25 12:20:51 -03:00
Kim Gardner 2bc6687957 Use email vs e-mail 2018-04-25 11:09:54 -04:00
Kim Gardner 3bd2d0b3fc Small fix 2018-04-24 17:17:57 -04:00
Kim Gardner 93f102e9c1 Merge branch 'master' into gdpr-username 2018-04-24 14:59:33 -04:00
Kim Gardner d483b13aa8 Merge pull request #1539 from clintabrown/fix-cli-user-create
Fix CLI users create task
2018-04-24 14:12:08 -04:00
okbel 89114ecd13 Adding withChangeUsername to plugin hocs, wip and more 2018-04-24 14:13:24 -03:00
Kim Gardner 47a860c09d Merge branch 'master' into fix-cli-user-create 2018-04-24 13:07:38 -04:00
okbel 01ad397561 Merge branch 'master' of github.com:coralproject/talk into gdpr-username
* 'master' of github.com:coralproject/talk:
  Adding a notification after saving
  final refactor, done.
  Adding translations, en, es, more
  Validation finished
  as InputField
  fix for large icons, reorder of styles
  changes
  validations
  Adding withChangePassword to mutations and plugins API, styles
  Frontend for Change Password
2018-04-24 13:59:21 -03:00
okbel 15817712c0 Introducing profileHeader slot 2018-04-24 13:58:28 -03:00
Kim Gardner 7f506f3fea Merge pull request #1532 from coralproject/gdpr-password
[GDPR] Password Change
2018-04-24 12:55:14 -04:00
okbel 9df9b9fa46 Merge branch 'master' of github.com:coralproject/talk into gdpr-username
* 'master' of github.com:coralproject/talk:
  Fix typo
  Renamed nl to nlTA. Sorted ta.register calls
  added direct download mutation
  adjusted download to include all comments
  Added NL translation for Moment. Also, sorted locale imports alphabetically.
2018-04-24 13:47:55 -03:00
okbel f910d7023c Merge branch 'master' of github.com:coralproject/talk into gdpr-password
* 'master' of github.com:coralproject/talk:
  Fix typo
  added direct download mutation
  adjusted download to include all comments
2018-04-24 13:43:24 -03:00
okbel 37919a11ab Adding a notification after saving 2018-04-24 13:39:13 -03:00
Clint Brown f83d6246cb Fix lint 2018-04-24 17:34:14 +10:00
Clint Brown ea96b7b7ce Merge branch 'master' into fix-cli-user-create 2018-04-24 17:23:57 +10:00
Clint Brown a444d98733 Add missing ctx arg for CLI users create 2018-04-24 17:17:48 +10:00
okbel eaf0df9573 final refactor, done. 2018-04-24 00:45:51 -03:00
okbel 5e3fc2b22a Adding translations, en, es, more 2018-04-24 00:20:10 -03:00
okbel 1d2be0cef0 Validation finished 2018-04-23 23:56:54 -03:00
okbel 493c4689c2 as InputField 2018-04-23 23:34:16 -03:00
Kim Gardner 51e4bcfef9 Merge pull request #1493 from coralproject/gdpr-download
[GDPR] Download My Comments
2018-04-23 14:39:18 -04:00
okbel 76ede5c541 fix for large icons, reorder of styles 2018-04-23 15:32:21 -03:00
okbel f4f0400c4d Merge branch 'gdpr-password' of github.com:coralproject/talk into gdpr-password
* 'gdpr-password' of github.com:coralproject/talk:
  Renamed nl to nlTA. Sorted ta.register calls
  Added NL translation for Moment. Also, sorted locale imports alphabetically.
2018-04-23 15:23:14 -03:00
okbel 9bb3a9f7cb changes 2018-04-23 15:22:50 -03:00
Kim Gardner 89711b2010 Merge branch 'master' into gdpr-password 2018-04-23 12:07:52 -04:00
Kim Gardner 61ec6c886c Merge branch 'master' into gdpr-download 2018-04-23 11:00:53 -04:00
Kim Gardner 6dd0dd41e0 Merge pull request #1535 from sanoma/master
Fix Dutch locale for Moment.JS
2018-04-23 11:00:38 -04:00
Kim Gardner c936a6ff2c Fix typo 2018-04-23 10:59:23 -04:00
D. Luijten 18e8f9c3dc Merge branch 'hotfix/fix_dutch_moment_locale'
* hotfix/fix_dutch_moment_locale:
  Renamed nl to nlTA. Sorted ta.register calls
2018-04-23 16:47:08 +02:00
D. Luijten c103a0c481 Renamed nl to nlTA.
Sorted ta.register calls
2018-04-23 16:46:42 +02:00
okbel 21f942a219 validations 2018-04-23 11:43:40 -03:00
Kim Gardner 89546c4066 Merge branch 'master' into master 2018-04-23 10:23:57 -04:00
okbel b5dd63aec1 Adding withChangePassword to mutations and plugins API, styles 2018-04-23 10:32:56 -03:00
okbel bc71366fd5 Frontend for Change Password 2018-04-20 18:23:46 -03:00
Wyatt Johnson c27c60346e fixed client building 2018-04-20 13:27:03 -06:00
Wyatt Johnson 9471026162 Referenced new plugin 2018-04-20 13:20:55 -06:00
Wyatt Johnson 8e21857a52 added new plugin to registry 2018-04-20 13:20:11 -06:00
Wyatt Johnson 10d27357f4 reorganized 2018-04-20 13:17:57 -06:00
Wyatt Johnson 7d644115d1 cleanups 2018-04-20 13:11:35 -06:00
Wyatt Johnson 7fa10b1a9a Merge branch 'master' into gdpr-email 2018-04-20 12:07:23 -06:00
Wyatt Johnson ea0be250c1 Merge branch 'master' into gdpr-delete 2018-04-20 12:07:10 -06:00
Wyatt Johnson 685bd02758 Merge branch 'master' into gdpr-username 2018-04-20 12:06:52 -06:00
Wyatt Johnson aa80f47b1c Merge branch 'master' into gdpr-password 2018-04-20 12:03:59 -06:00
Wyatt Johnson 84ebd1b66f Merge branch 'master' into gdpr-download 2018-04-20 12:00:22 -06:00
Wyatt Johnson 2a3b8e511c Merge pull request #1496 from coralproject/organization-contact
Organization Email Contact
2018-04-20 11:58:53 -06:00
Wyatt Johnson 80f219513b fixed e2e 2018-04-20 11:39:34 -06:00
Wyatt Johnson 7d4102e3aa Merge branch 'master' into organization-contact 2018-04-20 10:57:47 -06:00
Wyatt Johnson 3b657e120f fix for logger 2018-04-20 10:52:03 -06:00
Wyatt Johnson a477af3b4f Merge branch 'master' into gdpr-download 2018-04-20 10:33:29 -06:00
Wyatt Johnson d4fdb20436 Merge branch 'master' into master 2018-04-20 10:31:32 -06:00
Wyatt Johnson 5a88fda511 Merge pull request #1537 from sanoma/fix_translation_staff
Added translation to staff label in comment stream.
2018-04-20 10:31:15 -06:00
Wyatt Johnson e0ebbf5119 Merge branch 'master' into gdpr-delete 2018-04-20 10:30:29 -06:00
Wyatt Johnson 3129a6615f added direct download mutation 2018-04-20 09:37:20 -06:00
Wyatt Johnson 2e013c33ac GDPR Email Support
- Email and password can be used to create a new local profile
- Email can be changed with accounts that already have a local profile
2018-04-19 17:19:14 -06:00
Wyatt Johnson 5c5cde535e Merge branch 'organization-contact' into gdpr-email 2018-04-19 17:06:13 -06:00
Wyatt Johnson 16838f0fa1 Merge branch 'organization-contact' into gdpr-email 2018-04-19 17:03:56 -06:00
Wyatt Johnson 68461308c6 pull ignored users from db 2018-04-19 13:37:14 -06:00
okbel 99cb9da0b1 Merge branch 'organization-contact' of github.com:coralproject/talk into organization-contact
* 'organization-contact' of github.com:coralproject/talk: (48 commits)
  Change to UserHistory in UserDetail.js
  Add system withheld status to InactiveCommentLabel
  fix e2e test
  removed deprecated not logged in ui for profile tab
  fixed proptype missing validation
  icon patch
  Adds Author Index for Comments
  don't show profile tab if user is logged out
  version bump
  Removed storage check
  logic cleanup
  cleanups around storageAccess
  Storage Fixes
  adjusted env
  adjusted index creation and managemen
  autocapitalize off for the username field
  added beforeTest to wait for mongoose to be ready
  small fixes
  Jest for server
  Authors cannot see their own status history
  ...
2018-04-19 14:07:51 -03:00
okbel 84b373ed95 Validation Added 2018-04-19 14:07:24 -03:00
Wyatt Johnson 67405937ed adjusted download to include all comments 2018-04-19 10:48:48 -06:00
Wyatt Johnson b60e62f976 small fixes for db logic 2018-04-19 09:21:12 -06:00
Wyatt Johnson b4e2712dfb Merge branch 'master' into fix_translation_staff 2018-04-19 08:59:29 -06:00
Tibo Beijen 43fa0d2b58 Added translation to staff label in comment stream. 2018-04-19 10:43:41 +02:00
Wyatt Johnson 8e34fd1925 implemented tombstoning 2018-04-18 17:22:39 -06:00
Kim Gardner d55d914fb4 Merge branch 'master' into gdpr-download 2018-04-18 17:27:01 -04:00
Kim Gardner 31a8de852c Merge branch 'master' into organization-contact 2018-04-18 17:01:13 -04:00
Kim Gardner 825851f603 Merge branch 'master' into master 2018-04-18 16:57:38 -04:00
Kim Gardner d9a2b10afd Merge pull request #1530 from clintabrown/fix-view-context-system-withheld
Fix admin View Context view for comments with SYSTEM_WITHHELD status
2018-04-18 16:51:05 -04:00
Kim Gardner 06c2f328d1 Merge branch 'master' into fix-view-context-system-withheld 2018-04-18 16:44:08 -04:00
Kim Gardner 5aea8d71da Merge pull request #1531 from coralproject/indexes
Adds Author Index for Comments
2018-04-18 16:32:44 -04:00
Kim Gardner 71d413004e Merge branch 'master' into indexes 2018-04-18 16:26:40 -04:00
Kim Gardner 59658fcb29 Merge pull request #1504 from coralproject/155910162
Account History to User History
2018-04-18 16:18:26 -04:00
Kim Gardner 6d2c4d215d Merge branch 'master' into 155910162 2018-04-18 16:09:06 -04:00
Kim Gardner fe23b83044 Merge pull request #1507 from coralproject/155836892
Bug: User Comment History - After loading more comments, rejecting/accepting a comment reloads the user history
2018-04-18 16:08:49 -04:00
Kim Gardner c4cbefeb81 Change to UserHistory in UserDetail.js 2018-04-18 16:02:39 -04:00
Kim Gardner d822d8343a Merge branch 'master' into 155836892 2018-04-18 15:54:07 -04:00
Kim Gardner 3e8abf554e Merge branch 'master' into 155910162 2018-04-18 15:35:21 -04:00
Wyatt Johnson 431e9d8b09 Merge branch 'master' into gdpr-delete 2018-04-18 13:17:51 -06:00
Wyatt Johnson 2adec1bc34 added deletion graph endpoints 2018-04-18 13:13:41 -06:00
Wyatt Johnson 0e2a37ac91 Merge branch 'master' into gdpr-username 2018-04-18 10:29:18 -06:00
Wyatt Johnson 84360bfddf Merge branch 'master' into gdpr-password 2018-04-18 10:28:17 -06:00
D. Luijten ea2552e173 Merge branch 'hotfix/fix_dutch_moment_locale'
* hotfix/fix_dutch_moment_locale:
  Added NL translation for Moment. Also, sorted locale imports alphabetically.
2018-04-18 14:29:02 +02:00
D. Luijten ca2070eada Added NL translation for Moment. Also, sorted locale imports alphabetically. 2018-04-18 14:28:42 +02:00
Clint Brown 3ae1051148 Add system withheld status to InactiveCommentLabel 2018-04-18 07:55:11 +10:00
Belén Curcio 6b441291c0 Merge branch 'master' into organization-contact 2018-04-17 17:32:37 -03:00
Wyatt Johnson 786c91c4ff Merge pull request #1526 from kitwestneat/no-tabs-logged-out
don't show profile tab if user is logged out
2018-04-17 13:45:27 -06:00
Wyatt Johnson b6299c2d40 fix e2e test 2018-04-17 13:35:30 -06:00
Wyatt Johnson a257fdb623 removed deprecated not logged in ui for profile tab 2018-04-17 13:23:02 -06:00
Wyatt Johnson a6344d8e71 fixed proptype missing validation 2018-04-17 13:19:03 -06:00
Wyatt Johnson ec54db58dd Merge branch 'master' into no-tabs-logged-out 2018-04-17 13:11:32 -06:00
Wyatt Johnson dcf10643a0 Merge branch 'master' into gdpr-download 2018-04-17 13:09:17 -06:00
Wyatt Johnson bc7c37241e Merge branch 'master' into organization-contact 2018-04-17 13:07:16 -06:00
Wyatt Johnson 360dbdf02d icon patch 2018-04-17 13:06:07 -06:00
Wyatt Johnson 6c8b281a82 Merge branch 'master' into indexes 2018-04-17 12:56:48 -06:00
Wyatt Johnson fb1d431948 Merge pull request #1522 from coralproject/server-jest
Serverside Jest Support
2018-04-17 12:42:00 -06:00
Wyatt Johnson 87a97d4053 Adds Author Index for Comments
- Fixes #1529
2018-04-17 12:31:31 -06:00
Belén Curcio d17c704f38 Merge branch 'master' into server-jest 2018-04-17 13:01:19 -03:00
Wyatt Johnson ba9f034bfb Allow a user to change their own username 2018-04-16 17:37:08 -06:00
Wyatt Johnson ce291448f1 Added some change to mutators 2018-04-16 12:45:17 -06:00
Wyatt Johnson 8dbfa8f274 Merge branch 'organization-contact' into gdpr-password 2018-04-16 12:32:09 -06:00
Wyatt Johnson 0ccb8b6217 Merge branch 'master' into organization-contact 2018-04-16 12:30:45 -06:00
Wyatt Johnson 0fcb0be360 Password Change Graph Support 2018-04-16 12:29:37 -06:00
Wyatt Johnson f23f962adb Updated error styling 2018-04-16 10:47:09 -06:00
Wyatt Johnson 276cb03953 fixed missing partial 2018-04-13 18:27:40 -06:00
Wyatt Johnson 12bb886032 itterated on copy 2018-04-13 18:24:46 -06:00
Belén Curcio 1f719e3aa5 Merge branch 'master' into 155836892 2018-04-13 12:52:28 -03:00
Kit Westneat e5a2152cfd don't show profile tab if user is logged out 2018-04-12 17:52:49 -04:00
Wyatt Johnson 392d7177f6 Merge branch 'master' into gdpr-download 2018-04-12 15:17:12 -06:00
Wyatt Johnson 87ffa45050 Merge pull request #1525 from coralproject/storage-fixes
Storage Fixes
2018-04-12 13:50:08 -06:00
Wyatt Johnson 4a4357bc4c version bump 2018-04-12 13:37:42 -06:00
Wyatt Johnson bb11de562f Removed storage check 2018-04-12 13:24:56 -06:00
Wyatt Johnson 5125bb5d2d logic cleanup 2018-04-12 13:22:20 -06:00
Wyatt Johnson 6553096bc7 Merge branch 'master' into organization-contact 2018-04-12 13:11:35 -06:00
Wyatt Johnson 1c87181b17 cleanups around storageAccess 2018-04-12 12:58:30 -06:00
Wyatt Johnson 142f463211 Storage Fixes
- Implements storage fixes (fixes #1520)
- Implements updates to locale
2018-04-12 12:47:09 -06:00
Wyatt Johnson 96733ade4d Merge pull request #1518 from coralproject/ignored-users-reply
Ignored User Reply Notifications
2018-04-12 11:04:49 -06:00
Wyatt Johnson 9598e6d426 Merge branch 'master' into ignored-users-reply 2018-04-12 10:54:00 -06:00
Wyatt Johnson 91c4197fd7 Merge pull request #1512 from coralproject/autocomplete-off
Disable autocomplete on username signup field
2018-04-12 10:53:48 -06:00
Wyatt Johnson 8042083f6c Merge branch 'master' into autocomplete-off 2018-04-12 10:46:04 -06:00
Belén Curcio 8232ae3e76 Merge branch 'master' into ignored-users-reply 2018-04-12 13:45:32 -03:00
Wyatt Johnson 5178529083 adjusted env 2018-04-12 09:44:17 -06:00
Wyatt Johnson 10d11c1615 adjusted index creation and managemen 2018-04-12 09:37:17 -06:00
okbel 4e63cff57f Merge branch 'autocomplete-off' of github.com:coralproject/talk into autocomplete-off
* 'autocomplete-off' of github.com:coralproject/talk:
  updated version
  FrenchCorrections
  New version of the translation
  added missing translations
  add missing strings in fr locale
  Add Finnish translation
2018-04-12 12:18:53 -03:00
okbel 0206804bf4 autocapitalize off for the username field 2018-04-12 12:18:22 -03:00
Wyatt Johnson 68473e5a29 added beforeTest to wait for mongoose to be ready 2018-04-12 08:36:45 -06:00
Wyatt Johnson d481dc8651 Merge branch 'master' into server-jest 2018-04-11 19:30:18 -06:00
Wyatt Johnson 322740d1a9 small fixes 2018-04-11 19:29:54 -06:00
Wyatt Johnson 86385e0d86 Jest for server
- Introduced the Jest testing framework into our server side code so
plugins can now have tests that run
2018-04-11 19:02:38 -06:00
Wyatt Johnson 270c070075 Merge pull request #1521 from coralproject/perm-update
Permission Updates
2018-04-11 16:06:45 -06:00
Wyatt Johnson dc0c3b4a67 Authors cannot see their own status history 2018-04-11 15:58:04 -06:00
Wyatt Johnson b51bb7486e Permission Updates
- Restrict status history to ADMIN/MODERATORS
- Restrict body history to ADMIN/MODERATORS
2018-04-11 15:56:03 -06:00
Wyatt Johnson 7f9503d6aa Merge pull request #1519 from losowsky/master
Add 'User Roles' piece to the docs
2018-04-11 14:19:46 -06:00
Andrew Losowsky f81e973315 Added User Roles to the menu 2018-04-11 15:50:42 -04:00
Wyatt Johnson 412fd34cc1 Merge branch 'master' into gdpr-download 2018-04-11 13:46:46 -06:00
Andrew Losowsky 1dc3b855aa Bullets replaced with asterisks per markdown 2018-04-11 14:33:30 -04:00
Andrew Losowsky aef5076ac1 Update 03-04-user-roles.md 2018-04-11 14:31:50 -04:00
Andrew Losowsky 2294286483 Rename 03-03-user-roles.md to 03-04-user-roles.md 2018-04-11 14:30:42 -04:00
Andrew Losowsky 6b7580acaf Create 03-03-user-roles.md 2018-04-11 14:30:27 -04:00
Andrew Losowsky b2dc178fdb Rename 03-06-product-guide-trust.md to 03-07-product-guide-trust.md 2018-04-11 14:19:02 -04:00
Andrew Losowsky dd916a3ef9 Rename 03-05-product-guide-trust.md to 03-06-product-guide-trust.md 2018-04-11 14:18:43 -04:00
Andrew Losowsky 4eff55a0d1 Rename 03-04-product-guide-trust.md to 03-05-product-guide-trust.md 2018-04-11 14:18:25 -04:00
Wyatt Johnson e77243536c Merge pull request #1516 from coralproject/coral-docs
Removed unused coral-docs
2018-04-11 11:33:33 -06:00
Wyatt Johnson 97a8a6dadd Merge branch 'master' into coral-docs 2018-04-11 11:22:52 -06:00
Wyatt Johnson 05c0998541 Merge pull request #1517 from coralproject/errors
Refactored Errors
2018-04-11 11:22:39 -06:00
Wyatt Johnson 18570a97ea Merge branch 'master' into errors 2018-04-11 11:14:15 -06:00
Wyatt Johnson 28e264868a Merge pull request #1513 from coralproject/logging
Logging Improvements
2018-04-11 11:11:45 -06:00
Wyatt Johnson 4dfc90cac4 Merge branch 'master' into autocomplete-off 2018-04-11 11:09:52 -06:00
Belén Curcio 7b4829bfac Merge branch 'master' into logging 2018-04-11 13:00:43 -03:00
Belén Curcio e4cc49cda5 Merge branch 'master' into 155836892 2018-04-11 12:58:33 -03:00
Wyatt Johnson 2e74f79b79 Ignored User Reply Notifications 2018-04-10 17:33:56 -06:00
Wyatt Johnson f1b8d71cba Refactored Errors 2018-04-10 16:51:07 -06:00
Wyatt Johnson edfe60b8e0 removed unused coral-docs 2018-04-10 15:52:10 -06:00
okbel 9e07618a26 Adding min-width for inputs 2018-04-10 13:07:40 -03:00
okbel 46ef214bd3 tiny css changes 2018-04-10 11:55:22 -03:00
okbel 5c2d8c4b62 styles 2018-04-10 11:49:44 -03:00
okbel 1ceb1b4014 Save, and edit changes 2018-04-10 11:46:32 -03:00
Wyatt Johnson afa592aa78 e2e fixes 2018-04-09 16:34:08 -06:00
Wyatt Johnson 8a7d4c4fcc readme update 2018-04-09 16:14:25 -06:00
Wyatt Johnson adb7e97a91 Merge branch 'master' into gdpr-download 2018-04-09 16:09:53 -06:00
Wyatt Johnson 43e3cb8f10 cleanup of plugin code 2018-04-09 16:07:05 -06:00
Wyatt Johnson 333ef98378 Added new plugin 2018-04-09 15:58:31 -06:00
Wyatt Johnson 5941bfac7c pulled data download into seperate plugin 2018-04-09 15:52:40 -06:00
okbel 6d4623f8bf Wip - Almost finished! 2018-04-09 17:43:58 -03:00
Wyatt Johnson e358dce594 improved support 2018-04-09 13:59:23 -06:00
okbel 91aa95d3f2 Merge branch 'master' of github.com:coralproject/talk into organization-contact
* 'master' of github.com:coralproject/talk: (36 commits)
  Fixes #1505
  PropTypes
  Removin actions, using routes, and continuing the transition when the user makes an action
  fixes related to external auth
  Adding size, and proptypes
  IfSlotIsNotEmpty Bug
  Style and translations
  allow plugin code from clients to be parsed by webpack
  SaveChangesDialog
  Spanish translations
  Adding translations
  alert route hook ready!
  Removing plugin
  Restore Links
  Removing plugin
  Save changes / discard changes dialohg
  router and state lifted
  routes
  renaming slot :D
  renaming
  ...
2018-04-09 16:51:06 -03:00
okbel 3fcad35492 autocomplete off 2018-04-09 16:27:02 -03:00
Wyatt Johnson 4694f986c0 Logging Improvements
- development logging prints pretty again
- http requests are logged using bunyan now
2018-04-09 13:22:02 -06:00
Wyatt Johnson 841738c34c Merge branch 'master' into 155836892 2018-04-09 09:11:07 -06:00
Belén Curcio f27c41b83c Merge branch 'master' into 155836892 2018-04-08 21:18:46 -03:00
okbel 071942faca Merge branch '155836892' of github.com:coralproject/talk into 155836892
* '155836892' of github.com:coralproject/talk:
  updated yarn.lock
2018-04-06 18:40:56 -03:00
okbel 9bbcb6a073 wip - inconcistencies with cache, considering refetching 2018-04-06 18:39:23 -03:00
okbel 48bfc2699b Merge branch 'master' of github.com:coralproject/talk into 155836892
* 'master' of github.com:coralproject/talk:
  PropTypes
  Removin actions, using routes, and continuing the transition when the user makes an action
  Adding size, and proptypes
  IfSlotIsNotEmpty Bug
  Style and translations
  SaveChangesDialog
  Spanish translations
  Adding translations
  alert route hook ready!
  Restore Links
  Save changes / discard changes dialohg
  router and state lifted
  routes
2018-04-06 17:59:25 -03:00
Belén Curcio ad214a8e76 Merge branch 'master' into 155836892 2018-04-06 17:56:49 -03:00
Belén Curcio d0652d0583 Merge branch 'master' into 155836892 2018-04-05 17:28:24 -03:00
Wyatt Johnson 0c6ee2fe99 updated yarn.lock 2018-04-05 10:33:38 -06:00
Wyatt Johnson c29b12688c Merge branch 'master' into 155836892 2018-04-05 10:30:53 -06:00
Belén Curcio ccfa7aff5f Merge branch 'master' into 155836892 2018-04-04 07:53:48 -03:00
okbel 0b6b85b2a5 Removing logs 2018-04-04 07:37:27 -03:00
okbel a6a0b3e931 Removing reloads 2018-04-04 07:33:50 -03:00
okbel 06f8926964 Avoiding refetching 2018-04-04 07:25:47 -03:00
okbel ef10ab8088 Renaming components and styles 2018-04-03 11:20:22 -03:00
okbel 1a39727e38 account history to user history 2018-04-03 10:29:07 -03:00
Wyatt Johnson bb7f1a57f0 Added UI for downloading your comment data
- Added button on profile page
- Added date when last downloaded data
2018-04-02 17:53:27 -06:00
Wyatt Johnson c904d0f0c0 improved routing, cleaned mail 2018-04-02 14:58:54 -06:00
Wyatt Johnson 64d8d53987 Merge branch 'master' into gdpr-download 2018-04-02 14:58:06 -06:00
okbel 133984ab36 wip 2018-03-28 13:13:29 -03:00
Belén Curcio bcbaf25365 Merge branch 'master' into organization-contact 2018-03-28 10:42:03 -03:00
okbel 6c815c1132 Working on the admin side 2018-03-28 10:39:50 -03:00
okbel b32d1ef717 Adding the email to the schema 2018-03-28 10:16:57 -03:00
okbel 94d12dfbd4 Adding organizationContactEmail 2018-03-28 10:12:58 -03:00
okbel 6a22cd54ec Adding OrganizationDetails 2018-03-28 10:04:14 -03:00
okbel 480428b4a2 PropTypes and adding field 2018-03-28 09:44:02 -03:00
okbel 5650b7cf3a Adding proptypes 2018-03-28 09:34:06 -03:00
Wyatt Johnson a808cdc195 refactored some request logic 2018-03-27 18:47:34 -06:00
Wyatt Johnson ee5316e6ef initial download support 2018-03-27 18:28:14 -06:00
438 changed files with 12964 additions and 4435 deletions
+18 -1
View File
@@ -1,12 +1,27 @@
# job_environment will setup the environment for any job being executed.
job_environment: &job_environment
NODE_ENV: test
DISABLE_CREATE_MONGO_INDEXES: TRUE
# job_defaults applies all the defaults for each job.
job_defaults: &job_defaults
working_directory: ~/coralproject/talk
docker:
- image: circleci/node:8
environment:
<<: *job_environment
# create_indexes will create the mongo indexes and wait until they have been
# built.
create_indexes: &create_indexes
run:
name: Create the database indexes and wait until they are built
command: ./bin/cli db createIndexes
# integration_environment is the environment that configures the tests.
integration_environment: &integration_environment
NODE_ENV: test
<<: *job_environment
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
E2E_MAX_RETRIES: 3
@@ -25,6 +40,7 @@ integration_job: &integration_job
- checkout
- attach_workspace:
at: ~/coralproject/talk
- <<: *create_indexes
- run:
name: Setup the database with defaults
command: ./bin/cli setup --defaults
@@ -117,6 +133,7 @@ jobs:
environment:
JEST_JUNIT_OUTPUT: /tmp/circleci-test-results/jest/test-results.xml
JEST_REPORTER: jest-junit
- <<: *create_indexes
- run:
name: Run the server unit tests
command: yarn test:server
+3
View File
@@ -1,3 +1,6 @@
{
"env": {
"jest": true
},
"extends": "@coralproject/eslint-config-talk"
}
+3 -2
View File
@@ -38,6 +38,7 @@ plugins/*
!plugins/talk-plugin-google-auth
!plugins/talk-plugin-ignore-user
!plugins/talk-plugin-like
!plugins/talk-plugin-local-auth
!plugins/talk-plugin-love
!plugins/talk-plugin-member-since
!plugins/talk-plugin-mod
@@ -50,9 +51,10 @@ plugins/*
!plugins/talk-plugin-notifications-digest-hourly
!plugins/talk-plugin-offtopic
!plugins/talk-plugin-permalink
!plugins/talk-plugin-profile-settings
!plugins/talk-plugin-profile-data
!plugins/talk-plugin-remember-sort
!plugins/talk-plugin-respect
!plugins/talk-plugin-rich-text
!plugins/talk-plugin-slack-notifications
!plugins/talk-plugin-sort-most-downvoted
!plugins/talk-plugin-sort-most-liked
@@ -66,7 +68,6 @@ plugins/*
!plugins/talk-plugin-toxic-comments
!plugins/talk-plugin-upvote
!plugins/talk-plugin-viewing-options
!plugins/talk-plugin-rich-text
**/node_modules/*
yarn-error.log
+7 -1
View File
@@ -2,6 +2,12 @@
"exceptions": [
"https://nodesecurity.io/advisories/531",
"https://nodesecurity.io/advisories/532",
"https://nodesecurity.io/advisories/566"
"https://nodesecurity.io/advisories/566",
"https://nodesecurity.io/advisories/577",
"https://nodesecurity.io/advisories/594",
"https://nodesecurity.io/advisories/603",
"https://nodesecurity.io/advisories/611",
"https://nodesecurity.io/advisories/612",
"https://nodesecurity.io/advisories/654"
]
}
+2 -1
View File
@@ -7,6 +7,7 @@ ONBUILD ARG TALK_REPLY_COMMENTS_LOAD_DEPTH=3
ONBUILD ARG TALK_THREADING_LEVEL=3
ONBUILD ARG TALK_DEFAULT_STREAM_TAB=all
ONBUILD ARG TALK_DEFAULT_LANG=en
ONBUILD ARG TALK_WHITELISTED_LANGUAGES
ONBUILD ARG TALK_PLUGINS_JSON
ONBUILD ARG TALK_WEBPACK_SOURCE_MAP
@@ -20,4 +21,4 @@ ONBUILD COPY . /usr/src/app
ONBUILD RUN cli plugins reconcile && \
yarn && \
yarn build && \
yarn cache clean
yarn cache clean
+1 -1
View File
@@ -32,7 +32,7 @@ Youve installed Talk on your server, and youre preparing to launch it on y
## End-to-End Testing
Talk uses [Nightwatch](https://nightwatchjs.org/) as our e2e testing framework. The testing infrastructure that allows us to run our tests in real browsers is provided with love by our friends at [Browserstack](https://browserstack.com).
Talk uses [Nightwatch](http://nightwatchjs.org/) as our e2e testing framework. The testing infrastructure that allows us to run our tests in real browsers is provided with love by our friends at [Browserstack](https://browserstack.com).
[![Browserstack](/public/img/browserstack_logo.png)](https://browserstack.com)
+29 -3
View File
@@ -1,5 +1,8 @@
const express = require('express');
const morgan = require('morgan');
const nunjucks = require('nunjucks');
const cons = require('consolidate');
const trace = require('./middleware/trace');
const logging = require('./middleware/logging');
const path = require('path');
const merge = require('lodash/merge');
const helmet = require('helmet');
@@ -12,6 +15,10 @@ const { ENABLE_TRACING, APOLLO_ENGINE_KEY, PORT } = require('./config');
const app = express();
// Add the trace middleware first, it will create a request ID for each request
// downstream.
app.use(trace);
//==============================================================================
// PLUGIN PRE APPLICATION MIDDLEWARE
//==============================================================================
@@ -30,7 +37,7 @@ plugins.get('server', 'app').forEach(({ plugin, app: callback }) => {
// Add the logging middleware only if we aren't testing.
if (process.env.NODE_ENV !== 'test') {
app.use(morgan('dev'));
app.use(logging.log);
}
if (ENABLE_TRACING && APOLLO_ENGINE_KEY) {
@@ -67,7 +74,26 @@ app.use(
// VIEW CONFIGURATION
//==============================================================================
app.set('views', path.join(__dirname, 'views'));
// configure the default views directory.
const views = path.join(__dirname, 'views');
app.set('views', views);
// reconfigure nunjucks.
cons.requires.nunjucks = nunjucks.configure(views, {
autoescape: true,
trimBlocks: true,
lstripBlocks: true,
watch: process.env.NODE_ENV === 'development',
});
// assign the nunjucks engine to .njk files.
app.engine('njk', cons.nunjucks);
// assign the ejs engine to .ejs and .html files.
app.engine('ejs', cons.ejs);
app.engine('html', cons.ejs);
// set .ejs as the default extension.
app.set('view engine', 'ejs');
//==============================================================================
+6 -24
View File
@@ -1,16 +1,15 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
require('./util');
const program = require('commander');
const { head, map } = require('lodash');
const Matcher = require('did-you-mean');
// We're requiring this here so it'll setup some promise rejection hooks to log
// out.
require('./util');
// Setup the program.
program
.command('serve', 'serve the application')
.command('db', 'run database commands')
.command('settings', 'interact with the application settings')
.command('assets', 'interact with assets')
.command('setup', 'setup the application')
@@ -23,20 +22,3 @@ program
'provides utilities for interacting with the plugin system'
)
.parse(process.argv);
// If the command wasn't found, output help.
const commands = map(program.commands, '_name');
const command = head(program.args);
if (!commands.includes(command)) {
const m = new Matcher(commands);
const similarCommands = m.list(command);
console.error(
`cli '${command}' is not a talk cli command. See 'cli --help'.`
);
if (similarCommands.length > 0) {
const sc = similarCommands.map(({ value }) => `\t${value}\n`).join('');
console.error(`\nThe most similar commands are\n${sc}`);
}
process.exit(1);
}
+53 -24
View File
@@ -7,7 +7,7 @@
const util = require('./util');
const program = require('commander');
const parseDuration = require('ms');
const Table = require('cli-table');
const Table = require('cli-table2');
const AssetModel = require('../models/asset');
const CommentModel = require('../models/comment');
const AssetsService = require('../services/assets');
@@ -23,23 +23,33 @@ util.onshutdown([() => mongoose.disconnect()]);
/**
* Lists all the assets registered in the database.
*/
async function listAssets() {
async function listAssets(opts) {
try {
let assets = await AssetModel.find({}).sort({ created_at: 1 });
let table = new Table({
head: ['ID', 'Title', 'URL'],
});
switch (opts.format) {
case 'json': {
console.log(JSON.stringify(assets, null, 2));
break;
}
default: {
let table = new Table({
head: ['ID', 'Title', 'URL'],
});
assets.forEach(asset => {
table.push([
asset.id,
asset.title ? asset.title : '',
asset.url ? asset.url : '',
]);
});
assets.forEach(asset => {
table.push([
asset.id,
asset.title ? asset.title : '',
asset.url ? asset.url : '',
]);
});
console.log(table.toString());
break;
}
}
console.log(table.toString());
util.shutdown();
} catch (e) {
console.error(e);
@@ -49,12 +59,13 @@ async function listAssets() {
async function refreshAssets(ageString) {
try {
const now = new Date().getTime();
const ageMs = parseDuration(ageString);
const age = new Date(now - ageMs);
const query = AssetModel.find({}, { id: 1 });
if (ageString) {
// An age was specified, so filter only those assets.
const ageMs = parseDuration(ageString);
const age = new Date(Date.now() - ageMs);
let assets = await AssetModel.find(
{
query.merge({
$or: [
{
scraped: {
@@ -65,16 +76,28 @@ async function refreshAssets(ageString) {
scraped: null,
},
],
},
{ id: 1 }
);
});
}
// Create a graph context.
const ctx = Context.forSystem();
// Load the assets.
const cursor = query.cursor();
// Queue all the assets for scraping.
await Promise.all(assets.map(({ id }) => scraper.create(ctx, id)));
console.log('Assets were queued to be scraped');
const promises = [];
let asset = await cursor.next();
while (asset) {
promises.push(scraper.create(ctx, asset.id));
asset = await cursor.next();
}
await Promise.all(promises);
console.log(`${promises.length} Assets were queued to be scraped.`);
util.shutdown();
} catch (e) {
console.error(e);
@@ -202,11 +225,17 @@ async function rewrite(search, replace, options) {
program
.command('list')
.option(
'--format <type>',
'Specify the output format [table]',
/^(table|json)$/i,
'table'
)
.description('list all the assets in the database')
.action(listAssets);
program
.command('refresh <age>')
.command('refresh [age]')
.description('queues the assets that exceed the age requested')
.action(refreshAssets);
Executable
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env node
const util = require('./util');
const program = require('commander');
const config = require('../config');
async function createIndexes() {
try {
// Ensure we enable the index creation.
config.CREATE_MONGO_INDEXES = true;
// TODO: handle the plugin index creation?
// Let's register the shutdown hooks.
util.onshutdown([() => require('../services/mongoose').disconnect()]);
// Lets create all the database indexes for the application and wait for all
// them to finish their indexing.
const models = [
require('../models/action'),
require('../models/asset'),
require('../models/comment'),
require('../models/setting'),
require('../models/user'),
require('../models/migration'),
];
// Call the `.init()` method to setup all the indexes on each model.
// `init()` returns a promise that resolves when the indexes have finished
// building successfully. The `init()` function is idempotent, so we don't
// have to worry about triggering an index rebuild.
await Promise.all(models.map(Model => Model.init()));
console.log('Indexes created');
util.shutdown(0);
} catch (err) {
console.error(err);
util.shutdown(1);
}
}
program
.command('createIndexes')
.description('creates the database indexes and waits until they are created')
.action(createIndexes);
program.parse(process.argv);
// If there is no command listed, output help.
if (process.argv.length <= 2) {
program.outputHelp();
util.shutdown();
}
+11 -8
View File
@@ -4,7 +4,8 @@ const util = require('./util');
const program = require('commander');
const inquirer = require('inquirer');
const mongoose = require('../services/mongoose');
const SettingsService = require('../services/settings');
const Settings = require('../services/settings');
const cache = require('../services/cache');
// Register the shutdown criteria.
util.onshutdown([() => mongoose.disconnect()]);
@@ -14,9 +15,12 @@ util.onshutdown([() => mongoose.disconnect()]);
*/
async function changeOrgName() {
try {
let settings = await SettingsService.retrieve();
await cache.init();
let { organizationName } = await inquirer.prompt([
// Get the original settings.
const settings = await Settings.select('organizationName');
const { organizationName } = await inquirer.prompt([
{
name: 'organizationName',
message: 'Organization Name',
@@ -25,9 +29,8 @@ async function changeOrgName() {
]);
if (settings.organizationName !== organizationName) {
settings.organizationName = organizationName;
await SettingsService.update(settings);
// Set the organization name if there was a mutation to it.
await Settings.update({ organizationName });
console.log('Settings were updated.');
} else {
@@ -36,9 +39,9 @@ async function changeOrgName() {
} catch (err) {
console.error(err);
util.shutdown(1);
} finally {
util.shutdown();
}
util.shutdown();
}
//==============================================================================
+7 -5
View File
@@ -14,7 +14,7 @@ const SettingsService = require('../services/settings');
const SetupService = require('../services/setup');
const UsersService = require('../services/users');
const MigrationService = require('../services/migration');
const errors = require('../errors');
const { ErrSettingsInit, ErrSettingsNotInit } = require('../errors');
const Context = require('../graph/context');
// Register the shutdown criteria.
@@ -41,13 +41,15 @@ const performSetup = async () => {
// We should NOT have gotten a settings object, this means that the
// application is already setup. Error out here.
throw errors.ErrSettingsInit;
} catch (e) {
throw new ErrSettingsInit();
} catch (err) {
// If the error is `not init`, then we're good, otherwise, it's something
// else.
if (e !== errors.ErrSettingsNotInit) {
throw e;
if (err instanceof ErrSettingsNotInit) {
return;
}
throw err;
}
if (program.defaults) {
+1 -1
View File
@@ -8,7 +8,7 @@ const util = require('./util');
const program = require('commander');
const mongoose = require('../services/mongoose');
const TokensService = require('../services/tokens');
const Table = require('cli-table');
const Table = require('cli-table2');
// Register the shutdown criteria.
util.onshutdown([() => mongoose.disconnect()]);
+10 -3
View File
@@ -8,7 +8,7 @@ const util = require('./util');
const program = require('commander');
const inquirer = require('inquirer');
const { stripIndent } = require('common-tags');
const Table = require('cli-table');
const Table = require('cli-table2');
// Make things colorful!
require('colors');
@@ -287,8 +287,15 @@ async function createUser() {
const { email, username, password, role } = answers;
const ctx = Context.forSystem();
// Create the user.
const user = await UsersService.createLocalUser(email, password, username);
const user = await UsersService.createLocalUser(
ctx,
email,
password,
username
);
// Set the role.
await UsersService.setRole(user.id, role);
@@ -321,7 +328,7 @@ program
.action(searchUsers);
program
.command('set-role <userID> <role>')
.command('set-role <userID>')
.description('sets the role on a user')
.action(setUserRole);
+5 -2
View File
@@ -4,7 +4,8 @@ require('../services/env');
const debug = require('debug')('talk:util');
const { uniq } = require('lodash');
const util = (module.exports = {});
// Setup the utilities.
const util = {};
/**
* Stores an array of functions that should be executed in the event that the
@@ -15,7 +16,7 @@ util.toshutdown = [];
/**
* Calls all the shutdown functions and then ends the process.
* @param {Number} [defaultCode=0] default return code upon sucesfull shutdown.
* @param {Number} [defaultCode=0] default return code upon successful shutdown.
*/
util.shutdown = (defaultCode = 0, signal = null) => {
if (signal) {
@@ -63,3 +64,5 @@ process.on('unhandledRejection', err => {
console.error(err);
process.exit(1);
});
module.exports = util;
+2
View File
@@ -10,6 +10,7 @@ import Configure from 'routes/Configure';
import StreamSettings from './routes/Configure/containers/StreamSettings';
import ModerationSettings from './routes/Configure/containers/ModerationSettings';
import TechSettings from './routes/Configure/containers/TechSettings';
import OrganizationSettings from './routes/Configure/containers/OrganizationSettings';
import { ModerationLayout, Moderation } from 'routes/Moderation';
@@ -25,6 +26,7 @@ const routes = (
<Route path="stream" component={StreamSettings} />
<Route path="moderation" component={ModerationSettings} />
<Route path="tech" component={TechSettings} />
<Route path="organization" component={OrganizationSettings} />
<IndexRedirect to="stream" />
</Route>
+1 -8
View File
@@ -5,14 +5,7 @@ export const singleView = () => ({ type: actions.SINGLE_VIEW });
// hide shortcuts note
export const hideShortcutsNote = () => (dispatch, _, { localStorage }) => {
try {
if (localStorage) {
localStorage.setItem('coral:shortcutsNote', 'hide');
}
} catch (e) {
// above will fail in Safari private mode
}
localStorage.setItem('coral:shortcutsNote', 'hide');
dispatch({ type: actions.HIDE_SHORTCUTS_NOTE });
};
+11
View File
@@ -0,0 +1,11 @@
:global {
html, body, #root, #root > div {
min-height: 100%;
}
body {
margin: 0;
background-color: #FAFAFA;
font-family: 'Roboto', sans-serif;
}
}
+1
View File
@@ -1,5 +1,6 @@
import React from 'react';
import ToastContainer from './ToastContainer';
import './App.css';
import 'material-design-lite';
import AppRouter from '../AppRouter';
@@ -14,7 +14,8 @@ const ApproveButton = ({ active, minimal, onClick, className, disabled }) => {
className={cn(
styles.root,
{ [styles.minimal]: minimal, [styles.active]: active },
className
className,
'talk-admin-approve-button'
)}
onClick={onClick}
disabled={disabled || active}
@@ -19,7 +19,7 @@ class BanUserDialog extends React.Component {
}
handleMessageChange = e => {
const { value: message } = e;
const { target: { value: message } } = e;
this.setState({ message });
};
@@ -30,6 +30,12 @@ class BanUserDialog extends React.Component {
});
};
handlePerform = () => {
this.props.onPerform({
message: this.state.message,
});
};
renderStep0() {
const { onCancel, username, info } = this.props;
@@ -63,7 +69,7 @@ class BanUserDialog extends React.Component {
}
renderStep1() {
const { onCancel, onPerform } = this.props;
const { onCancel } = this.props;
const { message } = this.state;
return (
@@ -95,7 +101,7 @@ class BanUserDialog extends React.Component {
<Button
className={cn('talk-ban-user-dialog-button-confirm')}
cStyle="black"
onClick={onPerform}
onClick={this.handlePerform}
raised
>
{t('bandialog.send')}
@@ -29,7 +29,7 @@ const CommentAnimatedEdit = ({ children, body }) => {
CommentAnimatedEdit.propTypes = {
children: PropTypes.node,
body: PropTypes.string,
body: PropTypes.string.isRequired,
};
export default CommentAnimatedEdit;
@@ -0,0 +1,5 @@
.tombstone {
background-color: #f0f0f0;
padding: 1em;
color: #1a212f;
}
@@ -0,0 +1,9 @@
import React from 'react';
import styles from './CommentDeletedTombstone.css';
import t from 'coral-framework/services/i18n';
const CommentDeletedTombstone = () => (
<div className={styles.tombstone}>{t('framework.comment_is_deleted')}</div>
);
export default CommentDeletedTombstone;
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import Label from 'coral-ui/components/Label';
import Slot from 'coral-framework/components/Slot';
import { t } from 'coral-framework/services/i18n';
import FlagLabel from 'coral-ui/components/FlagLabel';
import cn from 'classnames';
import styles from './CommentLabels.css';
@@ -63,10 +64,14 @@ const CommentLabels = ({
<FlagLabel iconName="person">{getUserFlaggedType(actions)}</FlagLabel>
)}
{hasSuspectedWords(actions) && (
<FlagLabel iconName="sms_failed">Suspect</FlagLabel>
<FlagLabel iconName="sms_failed">
{t('flags.reasons.comment.suspect_word')}
</FlagLabel>
)}
{hasHistoryFlag(actions) && (
<FlagLabel iconName="sentiment_very_dissatisfied">History</FlagLabel>
<FlagLabel iconName="sentiment_very_dissatisfied">
{t('flags.reasons.comment.trust')}
</FlagLabel>
)}
</div>
<Slot
@@ -0,0 +1,16 @@
.external {
margin-bottom: 20px;
}
.separator h5 {
text-align: center;
font-size: 1.2em;
}
.slot > * {
margin-bottom: 8px;
&:last-child {
margin-bottom: 0px;
}
}
@@ -0,0 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
import styles from './External.css';
import Slot from 'coral-framework/components/Slot';
import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty';
const External = ({ slot }) => (
<IfSlotIsNotEmpty slot={slot}>
<div>
<div className={styles.external}>
<Slot fill={slot} className={styles.slot} />
</div>
<div className={styles.separator}>
<h5>Or</h5>
</div>
</div>
</IfSlotIsNotEmpty>
);
External.propTypes = {
slot: PropTypes.string.isRequired,
};
export default External;
@@ -7,7 +7,6 @@ import styles from './Header.css';
import t from 'coral-framework/services/i18n';
import { Logo } from './Logo';
import { can } from 'coral-framework/services/perms';
import ModerationIndicator from '../routes/Moderation/containers/Indicator';
import CommunityIndicator from '../routes/Community/containers/Indicator';
const CoralHeader = ({
@@ -32,7 +31,6 @@ const CoralHeader = ({
activeClassName={styles.active}
>
{t('configure.moderate')}
<ModerationIndicator root={root} data={data} />
</IndexLink>
)}
<Link
@@ -1,10 +1,8 @@
.indicator {
display: inline-block;
background-color: #E46D59;
border-radius: 10px;
position: absolute;
top: 50%;
width: 7px;
height: 7px;
margin-top: -4px;
margin-left: 7px;
}
@@ -0,0 +1,103 @@
.karmaTooltip {
position: relative;
display: inline-block;
margin: 2px 4px 0;
}
.icon {
font-size: 16px;
color: #0D5B8F;
user-select: none;
-webkit-tap-highlight-color:rgba(0,0,0,0);
> i {
vertical-align: baseline;
}
}
.icon:hover {
cursor: pointer;
}
.menu {
background-color: white;
border: solid 1px #999;
border-radius: 3px;
padding: 10px;
position: absolute;
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
z-index: 10;
top: 32px;
left: -100px;
width: 150px;
text-align: left;
color: #616161;
}
.menu::before{
content: '';
border: 10px solid transparent;
border-top-color: #999;
position: absolute;
left: 96px;
top: -20px;
transform: rotate(180deg);
}
.menu::after{
content: '';
border: 10px solid transparent;
border-top-color: white;
position: absolute;
left: 96px;
top: -19px;
transform: rotate(180deg);
}
.menu ul {
list-style: none;
padding: 0;
li {
display: flex;
justify-content: space-between;
margin: 5px 0;
}
}
.label {
padding: 4px 5px;
border-radius: 3px;
color: #fff;
font-weight: 400;
text-align: center;
font-size: .9em;
line-height: normal;
letter-spacing: .4px;
min-width: 25px;
display: block;
/* &.reliable { background-color: #03AB61; } */
/* &.neutral { background-color: #616161; } */
&.unreliable { background-color: #F44336; }
}
.descriptionList {
padding: 0;
margin: 0;
list-style: none;
}
.strongItem {
margin-right: 3px;
}
.descriptionItem {
font-size: 0.9em;
}
.link {
color: #2B7EB5;
text-decoration: underline;
display: block;
}
@@ -0,0 +1,82 @@
import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import { Icon } from 'coral-ui';
import styles from './KarmaTooltip.css';
import ClickOutside from 'coral-framework/components/ClickOutside';
import t from 'coral-framework/services/i18n';
const initialState = { menuVisible: false };
class KarmaTooltip extends React.Component {
static propTypes = {
thresholds: PropTypes.shape({
reliable: PropTypes.number.isRequired,
unreliable: PropTypes.number.isRequired,
}).isRequired,
};
state = initialState;
toogleMenu = () => {
this.setState({ menuVisible: !this.state.menuVisible });
};
hideMenu = () => {
this.setState({ menuVisible: false });
};
render() {
const { thresholds: { unreliable } } = this.props;
const { menuVisible } = this.state;
return (
<ClickOutside onClickOutside={this.hideMenu}>
<div className={cn(styles.karmaTooltip, 'talk-admin-karma-tooltip')}>
<span
onClick={this.toogleMenu}
className={cn(styles.icon, 'talk-admin-karma-tooltip-icon')}
>
<Icon name="info" />
</span>
{menuVisible && (
<div className={cn(styles.menu, 'talk-admin-karma-tooltip-menu')}>
<strong>{t('user_detail.user_karma_score')}</strong>
<ul>
{/* NOTE: we may display this data in the future, keeping around for that eventuality */}
{/* <li>
<span>Reliable</span>{' '}
<span className={cn(styles.label, styles.reliable)}>
&ge; {reliable}
</span>
</li>
<li>
<span>Neutral</span>{' '}
<span className={cn(styles.label, styles.neutral)}>
&lt; {reliable}, &gt; {unreliable}
</span>
</li> */}
<li>
<span>{t('user_detail.unreliable')}</span>{' '}
<span className={cn(styles.label, styles.unreliable)}>
&le; {unreliable}
</span>
</li>
</ul>
<a
className={styles.link}
href={t('user_detail.karma_docs_link')}
target="_blank"
>
{t('user_detail.learn_more')}
</a>
</div>
)}
</div>
</ClickOutside>
);
}
}
export default KarmaTooltip;
@@ -14,7 +14,8 @@ const RejectButton = ({ active, minimal, onClick, className, disabled }) => {
className={cn(
styles.root,
{ [styles.minimal]: minimal, [styles.active]: active },
className
className,
'talk-admin-reject-button'
)}
onClick={onClick}
disabled={disabled || active}
+49 -41
View File
@@ -4,6 +4,7 @@ import styles from './SignIn.css';
import { Button, TextField, Alert } from 'coral-ui';
import cn from 'classnames';
import Recaptcha from 'coral-framework/components/Recaptcha';
import External from './External';
class SignIn extends React.Component {
recaptcha = null;
@@ -33,48 +34,55 @@ class SignIn extends React.Component {
render() {
const { email, password, errorMessage, requireRecaptcha } = this.props;
return (
<form className="talk-admin-login-sign-in" onSubmit={this.handleSubmit}>
{errorMessage && <Alert>{errorMessage}</Alert>}
<TextField
id="email"
label="Email Address"
value={email}
onChange={this.handleEmailChange}
/>
<TextField
id="password"
label="Password"
value={password}
onChange={this.handlePasswordChange}
type="password"
/>
{requireRecaptcha && (
<div className={styles.recaptcha}>
<Recaptcha
ref={this.handleRecaptchaRef}
onVerify={this.props.onRecaptchaVerify}
/>
</div>
)}
<Button
className={cn(styles.signInButton, 'talk-admin-login-sign-in-button')}
type="submit"
cStyle="black"
full
>
Sign In
</Button>
<p className={styles.forgotPasswordCTA}>
Forgot your password?{' '}
<a
href="#"
className={styles.forgotPasswordLink}
onClick={this.handleForgotPasswordLink}
<div className="talk-admin-login-sign-in">
<External slot="authExternalAdminSignIn" />
<form onSubmit={this.handleSubmit}>
{errorMessage && <Alert>{errorMessage}</Alert>}
<TextField
id="email"
label="Email Address"
value={email}
onChange={this.handleEmailChange}
/>
<TextField
id="password"
label="Password"
value={password}
onChange={this.handlePasswordChange}
type="password"
/>
{requireRecaptcha && (
<div className={styles.recaptcha}>
<Recaptcha
ref={this.handleRecaptchaRef}
onVerify={this.props.onRecaptchaVerify}
/>
</div>
)}
<Button
className={cn(
styles.signInButton,
'talk-admin-login-sign-in-button'
)}
type="submit"
cStyle="black"
full
>
Request a new one.
</a>
</p>
</form>
Sign In
</Button>
<p className={styles.forgotPasswordCTA}>
{/* TODO: translate */}
Forgot your password?{' '}
<a
href="#"
className={styles.forgotPasswordLink}
onClick={this.handleForgotPasswordLink}
>
Request a new one.
</a>
</p>
</form>
</div>
);
}
}
@@ -35,44 +35,49 @@
margin-right: 20px;
}
.karmaStat {
display: flex;
}
.stat:last-child {
margin-right: 0px;
}
.statItem,
.statReportResult {
.statItem, .statReportResult, .statKarmaResult {
padding: 3px 5px;
background-color: #D8D8D8;
border-radius: 3px;
font-weight: 500;
display: block;
font-size: 0.9em;
line-height: normal;
letter-spacing: 0.4px;
min-width: 60px;
min-width: 25px;
display: block;
}
.statResult {
font-size: 1.5em;
padding: 5px 0;
display: inline-block;
text-align: center;
}
.statReportResult {
.statReportResult, .statKarmaResult {
color: white;
margin: 5px 0;
font-weight: 400;
text-align: center;
}
.statReportResult.reliable {
background-color: #749C48;
.statReportResult.reliable, .statKarmaResult.good {
background-color: #03AB61;
}
.statReportResult.neutral {
.statReportResult.neutral, .statKarmaResult.neutral {
background-color: #616161;
}
.statReportResult.unreliable {
.statReportResult.unreliable, .statKarmaResult.bad {
background-color: #F44336;
}
@@ -143,3 +148,7 @@
border-color: #E45241;
color: white;
}
.userDetailItem {
padding: 2px 0;
}
+57 -54
View File
@@ -3,14 +3,10 @@ import cn from 'classnames';
import PropTypes from 'prop-types';
import capitalize from 'lodash/capitalize';
import styles from './UserDetail.css';
import AccountHistory from './AccountHistory';
import UserHistory from './UserHistory';
import { Slot } from 'coral-framework/components';
import UserDetailCommentList from '../components/UserDetailCommentList';
import {
getReliability,
isSuspended,
isBanned,
} from 'coral-framework/utils/user';
import { isSuspended, isBanned, getKarma } from 'coral-framework/utils/user';
import ButtonCopyToClipboard from './ButtonCopyToClipboard';
import ClickOutside from 'coral-framework/components/ClickOutside';
import {
@@ -25,29 +21,10 @@ import {
import ActionsMenu from 'coral-admin/src/components/ActionsMenu';
import ActionsMenuItem from 'coral-admin/src/components/ActionsMenuItem';
import UserInfoTooltip from './UserInfoTooltip';
import KarmaTooltip from './KarmaTooltip';
import t from 'coral-framework/services/i18n';
class UserDetail extends React.Component {
rejectThenReload = async info => {
await this.props.rejectComment(info);
this.props.data.refetch();
};
acceptThenReload = async info => {
await this.props.acceptComment(info);
this.props.data.refetch();
};
bulkAcceptThenReload = async () => {
await this.props.bulkAccept();
this.props.data.refetch();
};
bulkRejectThenReload = async () => {
await this.props.bulkReject();
this.props.data.refetch();
};
changeTab = tab => {
this.props.changeTab(tab);
};
@@ -99,7 +76,13 @@ class UserDetail extends React.Component {
renderLoaded() {
const {
root,
root: { me, user, totalComments, rejectedComments },
root: {
me,
user,
totalComments,
rejectedComments,
settings: { karmaThresholds },
},
activeTab,
selectedCommentIds,
toggleSelect,
@@ -110,6 +93,10 @@ class UserDetail extends React.Component {
unbanUser,
unsuspendUser,
modal,
acceptComment,
rejectComment,
bulkAccept,
bulkReject,
} = this.props;
// if totalComments is 0, you're dividing by zero
@@ -193,7 +180,7 @@ class UserDetail extends React.Component {
<div>
<ul className={styles.userDetailList}>
<li>
<li className={styles.userDetailItem}>
<Icon name="assignment_ind" />
<span className={styles.userDetailItem}>
{t('user_detail.member_since')}:
@@ -201,11 +188,24 @@ class UserDetail extends React.Component {
{new Date(user.created_at).toLocaleString()}
</li>
{user.profiles.map(({ id }) => (
<li key={id}>
<Icon name="email" />
<li className={styles.userDetailItem}>
<Icon name="email" />
<span className={styles.userDetailItem}>
{t('user_detail.email')}:
</span>
{user.email}{' '}
<ButtonCopyToClipboard
className={styles.copyButton}
icon="content_copy"
copyText={user.email}
/>
</li>
{user.profiles.map(({ provider, id }) => (
<li key={id} className={styles.userDetailItem}>
<Icon name="device_hub" />
<span className={styles.userDetailItem}>
{t('user_detail.email')}:
{capitalize(provider)} {t('user_detail.id')}:
</span>
{id}{' '}
<ButtonCopyToClipboard
@@ -232,18 +232,21 @@ class UserDetail extends React.Component {
{rejectedPercent.toFixed(1)}%
</span>
</li>
<li className={styles.stat}>
<span className={styles.statItem}>
{t('user_detail.reports')}
</span>
<span
className={cn(
styles.statReportResult,
styles[getReliability(user.reliable.flagger)]
)}
>
{capitalize(getReliability(user.reliable.flagger))}
</span>
<li className={cn(styles.stat, styles.karmaStat)}>
<div>
<span className={styles.statItem}>
{t('user_detail.karma')}
</span>
<span
className={cn(
styles.statKarmaResult,
styles[getKarma(user.reliable.commenter)]
)}
>
{user.reliable.commenterKarma}
</span>
</div>
<KarmaTooltip thresholds={karmaThresholds.comment} />
</li>
</ul>
</div>
@@ -286,7 +289,7 @@ class UserDetail extends React.Component {
'talk-admin-user-detail-history-tab'
)}
>
{t('user_detail.account_history')}
{t('user_detail.user_history')}
</Tab>
</TabBar>
@@ -304,12 +307,12 @@ class UserDetail extends React.Component {
loadMore={loadMore}
toggleSelect={toggleSelect}
viewUserDetail={viewUserDetail}
acceptComment={this.acceptThenReload}
rejectComment={this.rejectThenReload}
acceptComment={acceptComment}
rejectComment={rejectComment}
selectedCommentIds={selectedCommentIds}
toggleSelectAll={toggleSelectAll}
bulkAcceptThenReload={this.bulkAcceptThenReload}
bulkRejectThenReload={this.bulkRejectThenReload}
bulkAcceptThenReload={bulkAccept}
bulkRejectThenReload={bulkReject}
/>
</TabPane>
<TabPane
@@ -322,19 +325,19 @@ class UserDetail extends React.Component {
loadMore={loadMore}
toggleSelect={toggleSelect}
viewUserDetail={viewUserDetail}
acceptComment={this.acceptThenReload}
rejectComment={this.rejectThenReload}
acceptComment={acceptComment}
rejectComment={rejectComment}
selectedCommentIds={selectedCommentIds}
toggleSelectAll={toggleSelectAll}
bulkAcceptThenReload={this.bulkAcceptThenReload}
bulkRejectThenReload={this.bulkRejectThenReload}
bulkAcceptThenReload={bulkAccept}
bulkRejectThenReload={bulkReject}
/>
</TabPane>
<TabPane
tabId={'history'}
className={'talk-admin-user-detail-history-tab-pane'}
>
<AccountHistory user={user} />
<UserHistory user={user} />
</TabPane>
</TabContent>
</Drawer>
@@ -12,6 +12,7 @@ import CommentAnimatedEdit from './CommentAnimatedEdit';
import CommentLabels from '../containers/CommentLabels';
import ApproveButton from './ApproveButton';
import RejectButton from 'coral-admin/src/components/RejectButton';
import CommentDeletedTombstone from './CommentDeletedTombstone';
import t, { timeago } from 'coral-framework/services/i18n';
@@ -43,6 +44,19 @@ class UserDetailComment extends React.Component {
body: comment.body,
};
if (!comment.body) {
return (
<li
tabIndex={0}
className={cn(className, styles.root, {
[styles.rootSelected]: selected,
})}
>
<CommentDeletedTombstone />
</li>
);
}
return (
<li
tabIndex={0}
@@ -152,7 +166,7 @@ UserDetailComment.propTypes = {
comment: PropTypes.shape({
id: PropTypes.string.isRequired,
status: PropTypes.string.isRequired,
body: PropTypes.string.isRequired,
body: PropTypes.string,
actions: PropTypes.array,
created_at: PropTypes.string.isRequired,
asset: PropTypes.shape({
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { murmur3 } from 'murmurhash-js';
import styles from './AccountHistory.css';
import styles from './UserHistory.css';
import cn from 'classnames';
import flatten from 'lodash/flatten';
import orderBy from 'lodash/orderBy';
@@ -43,15 +43,15 @@ const readableDuration = (startDate, endDate) => {
const buildActionResponse = (typename, created_at, until, status) => {
switch (typename) {
case 'UsernameStatusHistory':
return t('account_history.username_status', status);
return t('user_history.username_status', status);
case 'BannedStatusHistory':
return status
? t('account_history.user_banned')
: t('account_history.ban_removed');
? t('user_history.user_banned')
: t('user_history.ban_removed');
case 'SuspensionStatusHistory':
return until
? t('account_history.suspended', readableDuration(created_at, until))
: t('account_history.suspension_removed');
? t('user_history.suspended', readableDuration(created_at, until))
: t('user_history.suspension_removed');
default:
return '-';
}
@@ -62,43 +62,41 @@ const getModerationValue = assignedBy =>
assignedBy.username
) : (
<span>
<Icon name="computer" /> {t('account_history.system')}
<Icon name="computer" /> {t('user_history.system')}
</span>
);
class AccountHistory extends React.Component {
class UserHistory extends React.Component {
render() {
const { user } = this.props;
const userHistory = buildUserHistory(user.state);
return (
<div>
<div className={cn(styles.table, 'talk-admin-account-history')}>
<div className={cn(styles.table, 'talk-admin-user-history')}>
<div
className={cn(
styles.headerRow,
'talk-admin-account-history-header-row'
'talk-admin-user-history-header-row'
)}
>
<div className={styles.headerRowItem}>{t('user_history.date')}</div>
<div className={styles.headerRowItem}>
{t('account_history.date')}
{t('user_history.action')}
</div>
<div className={styles.headerRowItem}>
{t('account_history.action')}
</div>
<div className={styles.headerRowItem}>
{t('account_history.taken_by')}
{t('user_history.taken_by')}
</div>
</div>
{userHistory.map(
({ __typename, created_at, assigned_by, until, status }) => (
<div
className={cn(styles.row, 'talk-admin-account-history-row')}
className={cn(styles.row, 'talk-admin-user-history-row')}
key={`${__typename}_${murmur3(created_at)}`}
>
<div
className={cn(
styles.item,
'talk-admin-account-history-row-date'
'talk-admin-user-history-row-date'
)}
>
{moment(new Date(created_at)).format('MMM DD, YYYY')}
@@ -107,7 +105,7 @@ class AccountHistory extends React.Component {
className={cn(
styles.item,
styles.action,
'talk-admin-account-history-row-status'
'talk-admin-user-history-row-status'
)}
>
{buildActionResponse(__typename, created_at, until, status)}
@@ -116,7 +114,7 @@ class AccountHistory extends React.Component {
className={cn(
styles.item,
styles.username,
'talk-admin-account-history-row-assigned-by'
'talk-admin-user-history-row-assigned-by'
)}
>
{getModerationValue(assigned_by)}
@@ -130,8 +128,8 @@ class AccountHistory extends React.Component {
}
}
AccountHistory.propTypes = {
UserHistory.propTypes = {
user: PropTypes.object.isRequired,
};
export default AccountHistory;
export default UserHistory;
@@ -12,7 +12,7 @@ import { compose } from 'react-apollo';
import t from 'coral-framework/services/i18n';
class BanUserDialogContainer extends Component {
banUser = async () => {
banUser = async ({ message }) => {
const {
userId,
commentId,
@@ -21,7 +21,7 @@ class BanUserDialogContainer extends Component {
setCommentStatus,
hideBanUserDialog,
} = this.props;
await banUser({ id: userId, message: '' });
await banUser({ id: userId, message });
hideBanUserDialog();
if (commentId && commentStatus && commentStatus !== 'REJECTED') {
await setCommentStatus({ commentId, status: 'REJECTED' });
+4 -5
View File
@@ -2,21 +2,20 @@ import { gql } from 'react-apollo';
import withQuery from 'coral-framework/hocs/withQuery';
import Header from '../components/Header';
import CommunityIndicator from '../routes/Community/containers/Indicator';
import ModerationIndicator from '../routes/Moderation/containers/Indicator';
// TODO: eventually we will readd modqueue counts
// import ModerationIndicator from '../routes/Moderation/containers/Indicator';
import { getDefinitionName } from 'coral-framework/utils';
export default withQuery(
gql`
query TalkAdmin_Header($nullID: ID) {
...${getDefinitionName(ModerationIndicator.fragments.root)}
query TalkAdmin_Header {
...${getDefinitionName(CommunityIndicator.fragments.root)}
}
${ModerationIndicator.fragments.root}
${CommunityIndicator.fragments.root}
`,
{
options: {
variables: { nullID: null },
// variables: { nullID: null },
},
}
)(Header);
+2 -2
View File
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withSignIn } from 'coral-framework/hocs';
import { withSignIn, withPopupAuthHandler } from 'coral-framework/hocs';
import { compose } from 'recompose';
import SignIn from '../components/SignIn';
@@ -55,4 +55,4 @@ SignInContainer.propTypes = {
requireRecaptcha: PropTypes.bool.isRequired,
};
export default compose(withSignIn)(SignInContainer);
export default compose(withSignIn, withPopupAuthHandler)(SignInContainer);
@@ -148,6 +148,7 @@ UserDetailContainer.propTypes = {
selectedCommentIds: PropTypes.array,
unbanUser: PropTypes.func.isRequired,
unsuspendUser: PropTypes.func.isRequired,
userId: PropTypes.string,
};
const LOAD_MORE_QUERY = gql`
@@ -178,12 +179,14 @@ export const withUserDetailQuery = withQuery(
id
username
created_at
email
profiles {
id
provider
}
reliable {
flagger
commenter
commenterKarma
}
state {
status {
@@ -224,6 +227,14 @@ export const withUserDetailQuery = withQuery(
}
${getSlotFragmentSpreads(slots, 'user')}
}
settings {
karmaThresholds {
comment {
reliable
unreliable
}
}
}
me {
id
}
@@ -245,7 +256,6 @@ export const withUserDetailQuery = withQuery(
options: ({ userId, statuses }) => {
return {
variables: { author_id: userId, statuses },
fetchPolicy: 'network-only',
};
},
skip: ownProps => !ownProps.userId,
+82 -2
View File
@@ -24,6 +24,25 @@ const userRoleFragment = gql`
}
`;
/**
* calculateReliability will determine the reliability of a karma score based on
* the settings for the karma type.
*
* @param {Number} karma - the current karma value/score for the given user
* @param {Object} thresholds - the karma thresholds to base the karma computation on
*/
const calculateReliability = (karma, { reliable, unreliable }) => {
if (karma >= reliable) {
return true;
}
if (karma <= unreliable) {
return false;
}
return null;
};
export default {
mutations: {
SetUserRole: ({ variables: { id, role } }) => ({
@@ -156,7 +175,9 @@ export default {
}
const updated = update(prev, {
users: {
nodes: { $apply: nodes => nodes.filter(node => node.id !== id) },
nodes: {
$apply: nodes => nodes.filter(node => node.id !== id),
},
},
});
return updated;
@@ -185,7 +206,9 @@ export default {
const updated = update(prev, {
...decrement,
flaggedUsers: {
nodes: { $apply: nodes => nodes.filter(node => node.id !== id) },
nodes: {
$apply: nodes => nodes.filter(node => node.id !== id),
},
},
});
return updated;
@@ -291,5 +314,62 @@ export default {
},
},
}),
SetCommentStatus: ({ variables: { status } }) => ({
updateQueries: {
CoralAdmin_UserDetail: prev => {
const increment = {
user: {
reliable: {
commenter: {
$set: calculateReliability(
prev.user.reliable.commenterKarma - 1,
prev.settings.karmaThresholds.comment
),
},
commenterKarma: {
$apply: count => count - 1,
},
},
},
rejectedComments: {
$apply: count => (count < prev.totalComments ? count + 1 : count),
},
};
const decrement = {
user: {
reliable: {
commenter: {
$set: calculateReliability(
prev.user.reliable.commenterKarma + 1,
prev.settings.karmaThresholds.comment
),
},
commenterKarma: {
$apply: count => count + 1,
},
},
},
rejectedComments: {
$apply: count => (count > 0 ? count - 1 : 0),
},
};
// If rejected then increment rejectedComments by one
if (status === 'REJECTED') {
const updated = update(prev, increment);
return updated;
}
// If approved then decrement rejectedComments by one
if (status === 'ACCEPTED') {
const updated = update(prev, decrement);
return updated;
}
return prev;
},
},
}),
},
};
+2 -1
View File
@@ -15,7 +15,8 @@ import { hideShortcutsNote } from './actions/moderation';
smoothscroll.polyfill();
function init({ store, localStorage }) {
if (localStorage && localStorage.getItem('coral:shortcutsNote') === 'hide') {
const shouldHide = localStorage.getItem('coral:shortcutsNote') === 'hide';
if (shouldHide) {
store.dispatch(hideShortcutsNote());
}
}
@@ -5,6 +5,7 @@ const initialState = {
isLoading: false,
data: {
settings: {
organizationContactEmail: '',
organizationName: '',
domains: {
whitelist: [],
@@ -19,6 +20,7 @@ const initialState = {
},
errors: {
organizationName: '',
organizationContactEmail: '',
username: '',
email: '',
password: '',
@@ -133,6 +133,7 @@ th.header:nth-child(2), th.header:nth-child(3) {
.roleDropdown {
width: 150px;
text-align: left;
}
.roleOption {
@@ -130,7 +130,9 @@ class People extends React.Component {
{user.username}
</button>
<span className={styles.email}>
{user.profiles.map(({ id }) => id)}
{user.email
? user.email
: user.profiles.map(p => p.id).join(', ')}
</span>
</td>
<td className="mdl-data-table__cell--non-numeric">
@@ -200,7 +202,7 @@ class People extends React.Component {
</td>
<td className="mdl-data-table__cell--non-numeric">
<Dropdown
className={cn(
toggleClassName={cn(
'talk-admin-community-people-dd-role',
styles.roleDropdown
)}
@@ -8,7 +8,14 @@ import SaveChangesDialog from './SaveChangesDialog';
class Configure extends React.Component {
render() {
const { canSave, currentUser, root, savePending, settings } = this.props;
const {
canSave,
currentUser,
root,
savePending,
settings,
clearPending,
} = this.props;
if (!can(currentUser, 'UPDATE_CONFIG')) {
return <p>{t('configure.access_message')}</p>;
@@ -17,6 +24,9 @@ class Configure extends React.Component {
const passProps = {
root,
settings,
savePending,
clearPending,
canSave,
};
return (
@@ -41,6 +51,9 @@ class Configure extends React.Component {
<Item itemId="tech" icon="code">
{t('configure.tech_settings')}
</Item>
<Item itemId="organization" icon="people">
{t('configure.organization_information')}
</Item>
</List>
<div className={styles.saveBox}>
{canSave ? (
@@ -81,6 +94,7 @@ Configure.propTypes = {
children: PropTypes.node.isRequired,
saveDialog: PropTypes.bool,
hideSaveDialog: PropTypes.func.isRequired,
clearPending: PropTypes.func.isRequired,
};
export default Configure;
@@ -0,0 +1,87 @@
.label {
display: block;
}
.detailList {
padding: 0;
margin: 0;
}
.detailLabel {
color: #000;
font-size: 1.1em;
font-weight: bold;
display: block;
margin-bottom: 4px;
}
.detailValue {
padding: 6px 0;
border: solid 1px transparent;
display: block;
font-size: 1.1em;
border-radius: 2px;
color: #424242;
box-sizing: border-box;
min-width: 300px;
}
.editable {
padding-left: 10px;
padding-right: 10px;
border-color: grey;
}
.detailItem {
margin-bottom: 16px;
list-style: none;
}
.button, .button:disabled {
background: white;
border: solid 1px grey;
}
.actionBox {
flex-grow: 0;
}
.cancelButton {
padding: 10px;
display: block;
color: #4f5c67;
font-weight: 500;
&:hover {
cursor: pointer;
}
}
.changedSave {
background-color: #00796B;
color: white;
}
.errorList {
list-style: none;
padding: 0;
margin: 0;
}
.errorItem {
padding: 5px 10px;
margin-bottom: 20px;
color: #b71c1c;
border-radius: 2px;
display: inline-block;
background: #F9D3CE;
}
.container {
display: flex;
}
.content {
flex-grow: 1;
padding-right: 40px;
}
@@ -0,0 +1,185 @@
import React from 'react';
import cn from 'classnames';
import { Button } from 'coral-ui';
import PropTypes from 'prop-types';
import styles from './OrganizationSettings.css';
import Slot from 'coral-framework/components/Slot';
import t from 'coral-framework/services/i18n';
import ConfigurePage from './ConfigurePage';
import ConfigureCard from 'coral-framework/components/ConfigureCard';
import validate from 'coral-framework/helpers/validate';
import errorMsj from 'coral-framework/helpers/error';
class OrganizationSettings extends React.Component {
state = { editing: false, errors: [] };
addError = err => {
if (this.state.errors.indexOf(err) === -1) {
this.setState(({ errors }) => ({
errors: errors.concat(err),
}));
}
};
removeError = err => {
this.setState(({ errors }) => ({
errors: errors.filter(i => i !== err),
}));
};
toggleEditing = () => {
this.setState(({ editing }) => ({
editing: !editing,
}));
};
disableEditing = () => {
this.setState(() => ({
editing: false,
}));
};
updateName = event => {
const updater = { organizationName: { $set: event.target.value } };
this.props.updatePending({ updater });
};
updateEmail = event => {
let error = null;
const email = event.target.value;
// Add a blocker error
if (!validate.email(email)) {
error = true;
this.addError('email');
} else {
this.removeError('email');
}
const updater = { organizationContactEmail: { $set: email } };
const errorUpdater = { organizationContactEmail: { $set: error } };
this.props.updatePending({ updater, errorUpdater });
};
cancelEditing = () => {
this.disableEditing();
this.props.clearPending();
};
save = async () => {
await this.props.savePending();
this.disableEditing();
};
displayErrors = (errors = []) => (
<ul className={styles.errorList}>
{errors.map((errKey, i) => (
<li key={`${i}_${errKey}`} className={styles.errorItem}>
{errorMsj[errKey]}
</li>
))}
</ul>
);
render() {
const { settings, slotPassthrough, canSave } = this.props;
const hasErrors = this.state.errors.length;
return (
<ConfigurePage title={t('configure.organization_information')}>
<p>{t('configure.organization_info_copy')}</p>
<p>{t('configure.organization_info_copy_2')}</p>
<ConfigureCard>
<div className={styles.container}>
<div className={styles.content}>
{this.displayErrors(this.state.errors)}
<ul className={styles.detailList}>
<li className={styles.detailItem}>
<label
className={styles.detailLabel}
id={t('configure.organization_name')}
>
{t('configure.organization_name')}
</label>
<input
type="text"
className={cn(styles.detailValue, {
[styles.editable]: this.state.editing,
})}
onChange={this.updateName}
value={settings.organizationName}
id={t('configure.organization_name')}
readOnly={!this.state.editing}
/>
</li>
<li className={styles.detailItem}>
<label
className={styles.detailLabel}
id={t('configure.organization_contact_email')}
>
{t('configure.organization_contact_email')}
</label>
<input
type="text"
className={cn(styles.detailValue, {
[styles.editable]: this.state.editing,
})}
onChange={this.updateEmail}
value={settings.organizationContactEmail || ''}
id={t('configure.organization_contact_email')}
readOnly={!this.state.editing}
/>
</li>
</ul>
</div>
{!this.state.editing ? (
<div className={styles.actionBox}>
<Button
className={styles.button}
icon="settings"
onClick={this.toggleEditing}
full
>
{t('configure.edit_info')}
</Button>
</div>
) : (
<div className={styles.actionBox}>
{canSave && !hasErrors ? (
<Button
raised
onClick={this.save}
className={styles.changedSave}
icon="check"
full
>
{t('configure.save')}
</Button>
) : (
<Button className={styles.button} disabled icon="check" full>
{t('configure.save')}
</Button>
)}
<a className={styles.cancelButton} onClick={this.cancelEditing}>
{t('cancel')}
</a>
</div>
)}
</div>
</ConfigureCard>
<Slot fill="adminOrganizationSettings" passthrough={slotPassthrough} />
</ConfigurePage>
);
}
}
OrganizationSettings.propTypes = {
savePending: PropTypes.func.isRequired,
clearPending: PropTypes.func.isRequired,
updatePending: PropTypes.func.isRequired,
errors: PropTypes.object.isRequired,
settings: PropTypes.object.isRequired,
slotPassthrough: PropTypes.object.isRequired,
canSave: PropTypes.bool.isRequired,
};
export default OrganizationSettings;
@@ -82,6 +82,20 @@ class StreamSettings extends React.Component {
this.props.updatePending({ updater });
};
updateDisableCommenting = () => {
const updater = {
disableCommenting: {
$set: !this.props.settings.disableCommenting,
},
};
this.props.updatePending({ updater });
};
updateDisableCommentingMessage = value => {
const updater = { disableCommentingMessage: { $set: value } };
this.props.updatePending({ updater });
};
updateAutoClose = () => {
const updater = {
autoCloseStream: { $set: !this.props.settings.autoCloseStream },
@@ -192,6 +206,25 @@ class StreamSettings extends React.Component {
&nbsp;
{t('configure.edit_comment_timeframe_text_post')}
</ConfigureCard>
<ConfigureCard
checked={settings.disableCommenting}
onCheckbox={this.updateDisableCommenting}
title={t('configure.disable_commenting_title')}
>
<p>{t('configure.disable_commenting_desc')}</p>
<div
className={cn(
styles.configSettingDisableCommenting,
settings.disableCommenting ? null : styles.hidden
)}
>
<MarkdownEditor
className={styles.descriptionBox}
onChange={this.updateDisableCommentingMessage}
value={settings.disableCommentingMessage}
/>
</div>
</ConfigureCard>
<ConfigureCard
checked={settings.autoCloseStream}
onCheckbox={this.updateAutoClose}
@@ -16,10 +16,12 @@ import {
hideSaveDialog,
} from '../../../actions/configure';
import Configure from '../components/Configure';
import OrganizationSettings from './OrganizationSettings';
import { withRouter } from 'react-router';
class ConfigureContainer extends React.Component {
state = { nextRoute: '' };
nextRoute = '';
unregisterLeaveHook = null;
savePending = async () => {
await this.props.updateSettings(this.props.pending);
@@ -39,18 +41,16 @@ class ConfigureContainer extends React.Component {
};
gotoNextRoute = () => {
const { nextRoute } = this.state;
if (nextRoute) {
this.props.router.push(nextRoute);
this.setState({ nextRoute: '' });
if (this.nextRoute) {
this.props.router.push(this.nextRoute);
this.nextRoute = '';
}
};
handleSectionChange = async section => {
const nextRoute = `/admin/configure/${section}`;
if (this.shouldShowSaveDialog()) {
await this.setState({ nextRoute });
if (this.hasPendingData()) {
this.nextRoute = nextRoute;
this.props.showSaveDialog();
} else {
// Just go to the section
@@ -58,20 +58,37 @@ class ConfigureContainer extends React.Component {
}
};
shouldShowSaveDialog = () => {
navigationPrompt = e => {
if (this.hasPendingData()) {
const confirmationMessage = 'Changes that you made may not be saved.';
e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
return confirmationMessage; // Gecko, WebKit, Chrome <34
}
};
hasPendingData = () => {
return !!Object.keys(this.props.pending).length;
};
routeLeave = ({ pathname }) => {
if (this.shouldShowSaveDialog()) {
this.setState({ nextRoute: pathname });
if (this.hasPendingData()) {
this.nextRoute = pathname;
this.props.showSaveDialog();
return false;
}
};
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routeLeave);
this.unregisterLeaveHook = this.props.router.setRouteLeaveHook(
this.props.route,
this.routeLeave
);
window.addEventListener('beforeunload', this.navigationPrompt);
}
componentWillUnmount() {
this.unregisterLeaveHook();
window.removeEventListener('beforeunload', this.navigationPrompt);
}
render() {
@@ -83,18 +100,21 @@ class ConfigureContainer extends React.Component {
return <Spinner />;
}
const activeSection = this.props.routes[3].path;
return (
<Configure
saveChanges={this.saveChanges}
discardChanges={this.discardChanges}
saveDialog={this.props.saveDialog}
activeSection={this.props.routes[3].path}
activeSection={activeSection}
hideSaveDialog={this.props.hideSaveDialog}
canSave={this.props.canSave}
currentUser={this.props.currentUser}
root={this.props.root}
settings={this.props.mergedSettings}
handleSectionChange={this.handleSectionChange}
clearPending={this.props.clearPending}
savePending={this.savePending}
>
{this.props.children}
@@ -110,10 +130,12 @@ const withConfigureQuery = withQuery(
...${getDefinitionName(StreamSettings.fragments.settings)}
...${getDefinitionName(TechSettings.fragments.settings)}
...${getDefinitionName(ModerationSettings.fragments.settings)}
...${getDefinitionName(OrganizationSettings.fragments.settings)}
}
...${getDefinitionName(StreamSettings.fragments.root)}
...${getDefinitionName(TechSettings.fragments.root)}
...${getDefinitionName(ModerationSettings.fragments.root)}
...${getDefinitionName(OrganizationSettings.fragments.root)}
}
${StreamSettings.fragments.root}
${StreamSettings.fragments.settings}
@@ -121,6 +143,8 @@ const withConfigureQuery = withQuery(
${TechSettings.fragments.settings}
${ModerationSettings.fragments.root}
${ModerationSettings.fragments.settings}
${OrganizationSettings.fragments.root}
${OrganizationSettings.fragments.settings}
`,
{
options: () => ({
@@ -0,0 +1,53 @@
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { compose, gql } from 'react-apollo';
import OrganizationSettings from '../components/OrganizationSettings';
import withFragments from 'coral-framework/hocs/withFragments';
import { getSlotFragmentSpreads } from 'coral-framework/utils';
import { updatePending } from '../../../actions/configure';
import { mapProps } from 'recompose';
const slots = ['adminOrganizationSettings'];
const mapStateToProps = state => ({
errors: state.configure.errors,
});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
updatePending,
},
dispatch
);
export default compose(
withFragments({
root: gql`
fragment TalkAdmin_OrganizationSettings_root on RootQuery {
__typename
${getSlotFragmentSpreads(slots, 'root')}
}
`,
settings: gql`
fragment TalkAdmin_OrganizationSettings_settings on Settings {
organizationName
organizationContactEmail
${getSlotFragmentSpreads(slots, 'settings')}
}
`,
}),
connect(mapStateToProps, mapDispatchToProps),
mapProps(({ root, settings, updatePending, errors, ...rest }) => ({
slotPassthrough: {
root,
settings,
updatePending,
errors,
},
updatePending,
settings,
errors,
...rest,
}))
)(OrganizationSettings);
@@ -39,6 +39,8 @@ export default compose(
autoCloseStream
closedTimeout
closedMessage
disableCommenting
disableCommentingMessage
${getSlotFragmentSpreads(slots, 'settings')}
}
`,
@@ -1,15 +1,16 @@
import React, { Component } from 'react';
import React from 'react';
import styles from './Install.css';
import { Wizard, WizardNav } from 'coral-ui';
import Layout from 'coral-admin/src/components/Layout';
import PropTypes from 'prop-types';
import InitialStep from './Steps/InitialStep';
import AddOrganizationName from './Steps/AddOrganizationName';
import OrganizationDetails from './Steps/OrganizationDetails';
import CreateYourAccount from './Steps/CreateYourAccount';
import PermittedDomainsStep from './Steps/PermittedDomainsStep';
import FinalStep from './Steps/FinalStep';
export default class Install extends Component {
class Install extends React.Component {
handleDomainsChange = value => {
this.props.updatePermittedDomains(value);
};
@@ -55,7 +56,7 @@ export default class Install extends Component {
goToStep={this.props.goToStep}
>
<InitialStep />
<AddOrganizationName
<OrganizationDetails
install={install}
handleSettingsChange={this.handleSettingsChange}
handleSettingsSubmit={this.handleSettingsSubmit}
@@ -81,3 +82,18 @@ export default class Install extends Component {
);
}
}
Install.propTypes = {
updatePermittedDomains: PropTypes.func.isRequired,
updateSettingsFormData: PropTypes.func.isRequired,
updateUserFormData: PropTypes.func.isRequired,
submitSettings: PropTypes.func.isRequired,
submitUser: PropTypes.func.isRequired,
install: PropTypes.object.isRequired,
nextStep: PropTypes.func.isRequired,
previousStep: PropTypes.func.isRequired,
goToStep: PropTypes.func.isRequired,
finishInstall: PropTypes.func.isRequired,
};
export default Install;
@@ -21,6 +21,17 @@ const AddOrganizationName = props => {
showErrors={install.showErrors}
errorMsg={install.errors.organizationName}
/>
<TextField
className={styles.TextField}
id="organizationContactEmail"
type="email"
label={t('install.create.organization_contact_email')}
onChange={handleSettingsChange}
showErrors={install.showErrors}
errorMsg={install.errors.organizationContactEmail}
/>
<Button
className="talk-install-step-2-save-button"
type="submit"
@@ -1,8 +1,7 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { compose } from 'react-apollo';
import Install from '../components/Install';
import {
@@ -18,7 +17,7 @@ import {
updatePermittedDomains,
} from '../../../actions/install';
class InstallContainer extends Component {
class InstallContainer extends React.Component {
componentDidMount() {
const { checkInstall } = this.props;
checkInstall(() => {
@@ -27,7 +26,21 @@ class InstallContainer extends Component {
}
render() {
return <Install {...this.props} />;
return (
<Install
install={this.props.install}
goToStep={this.props.goToStep}
nextStep={this.props.nextStep}
submitUser={this.props.submitUser}
checkInstall={this.props.checkInstall}
previousStep={this.props.previousStep}
finishInstall={this.props.finishInstall}
submitSettings={this.props.submitSettings}
updateUserFormData={this.props.updateUserFormData}
updateSettingsFormData={this.props.updateSettingsFormData}
updatePermittedDomains={this.props.updatePermittedDomains}
/>
);
}
}
@@ -35,6 +48,20 @@ InstallContainer.contextTypes = {
router: PropTypes.object,
};
InstallContainer.propTypes = {
install: PropTypes.object.isRequired,
goToStep: PropTypes.func.isRequired,
nextStep: PropTypes.func.isRequired,
submitUser: PropTypes.func.isRequired,
checkInstall: PropTypes.func.isRequired,
previousStep: PropTypes.func.isRequired,
finishInstall: PropTypes.func.isRequired,
submitSettings: PropTypes.func.isRequired,
updateUserFormData: PropTypes.func.isRequired,
updateSettingsFormData: PropTypes.func.isRequired,
updatePermittedDomains: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
install: state.install,
});
@@ -56,6 +83,4 @@ const mapDispatchToProps = dispatch =>
dispatch
);
export default compose(connect(mapStateToProps, mapDispatchToProps))(
InstallContainer
);
export default connect(mapStateToProps, mapDispatchToProps)(InstallContainer);
@@ -1,5 +1,4 @@
@custom-media --big-viewport (min-width: 780px);
.root {
border-bottom: 1px solid #e0e0e0;
font-size: 18px;
@@ -13,7 +12,6 @@
margin-top: 13px;
min-height: 0;
outline: 0;
/*
Fix rendering issues in Safari by promoting this
into its own layer.
@@ -21,7 +19,6 @@
https://www.pivotaltracker.com/story/show/151142211
*/
transform: translateZ(0);
&:last-child {
border-bottom: none;
}
@@ -39,7 +36,6 @@
display: flex;
align-items: center;
justify-content: space-between;
}
.author {
@@ -74,7 +70,7 @@
max-width: 500px;
font-weight: 300;
font-size: 16px;
word-break: break-all;
overflow-wrap: break-word;
}
.created {
@@ -85,13 +81,16 @@
font-weight: 300;
}
.deleted {
background-color: #f0f0f0;
}
.moderateArticle {
font-size: 14px;
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
max-width: 500px;
a {
display: inline-block;
color: #063b9a;
@@ -99,17 +98,15 @@
font-weight: 500;
letter-spacing: .5px;
margin-left: 10px;
font-size: 13px;
margin-left: 5px;
padding-bottom: 0px;
border-bottom: solid 1px;
line-height: 16px;
&:hover {
opacity: .9;
cursor: pointer;
}
}
}
}
@@ -134,12 +131,10 @@
cursor: pointer;
font-weight: normal;
white-space: nowrap;
&:hover {
text-decoration: underline;
opacity: .9;
}
i {
font-size: 12px;
position: relative;
@@ -168,7 +163,6 @@
align-items: center;
justify-content: flex-end;
margin-right: 14px;
i {
margin-right: 5px;
}
@@ -177,7 +171,6 @@
@media (--big-viewport) {
.root {
margin-bottom: 30px;
&:last-child {
border-bottom: 1px solid #e0e0e0;
}
@@ -186,7 +179,6 @@
.commentContent {
display: flex;
blockquote {
font-size: inherit;
line-height: inherit;
@@ -13,6 +13,7 @@ import IfHasLink from 'coral-admin/src/components/IfHasLink';
import cn from 'classnames';
import ApproveButton from 'coral-admin/src/components/ApproveButton';
import RejectButton from 'coral-admin/src/components/RejectButton';
import CommentDeletedTombstone from '../../../components/CommentDeletedTombstone';
import t, { timeago } from 'coral-framework/services/i18n';
@@ -75,6 +76,27 @@ class Comment extends React.Component {
asset: comment.asset,
};
if (!comment.body) {
return (
<li
tabIndex={0}
className={cn(
className,
'mdl-card',
selectionStateCSS,
styles.root,
{ [styles.selected]: selected, [styles.dangling]: dangling },
'talk-admin-moderate-comment',
styles.deleted
)}
id={`comment_${comment.id}`}
ref={this.handleRef}
>
<CommentDeletedTombstone />
</li>
);
}
return (
<li
tabIndex={0}
@@ -200,7 +222,7 @@ Comment.propTypes = {
comment: PropTypes.shape({
id: PropTypes.string.isRequired,
status: PropTypes.string.isRequired,
body: PropTypes.string.isRequired,
body: PropTypes.string,
action_summaries: PropTypes.array,
actions: PropTypes.array,
created_at: PropTypes.string.isRequired,
@@ -63,10 +63,6 @@ class Moderation extends Component {
this.props.toggleStorySearch(true);
};
getActiveTabCount = (props = this.props) => {
return props.root[`${props.activeTab}Count`];
};
moderate = accept => {
const {
acceptComment,
@@ -139,12 +135,14 @@ class Moderation extends Component {
const comments = root[activeTab];
const activeTabCount = this.getActiveTabCount();
const menuItems = Object.keys(queueConfig).map(queue => ({
key: queue,
name: queueConfig[queue].name,
icon: queueConfig[queue].icon,
count: root[`${queue}Count`],
indicator:
['premod', 'reported'].includes(queue) && root[queue].nodes.length > 0,
// TODO: Eventually we'll reintroduce counting
// count: root[`${props.queue}Count`]
}));
const slotPassthrough = {
@@ -189,7 +187,6 @@ class Moderation extends Component {
loadMore={this.loadMore}
commentBelongToQueue={this.props.commentBelongToQueue}
isLoadingMore={this.state.isLoadingMore}
commentCount={activeTabCount}
currentUserId={this.props.currentUser.id}
viewUserDetail={viewUserDetail}
selectCommentId={props.selectCommentId}
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import CountBadge from '../../../components/CountBadge';
import Indicator from '../../../components/Indicator';
import styles from './ModerationMenu.css';
import { Icon } from 'coral-ui';
import { Link } from 'react-router';
@@ -24,6 +24,7 @@ const ModerationMenu = ({ asset = {}, items, getModPath, activeTab }) => {
>
{items.map(queue => (
<Link
id={`talk-admin-moderate-tab-${queue.key}`}
key={queue.key}
to={getModPath(queue.key, asset.id)}
className={cn('mdl-tabs__tab', styles.tab, {
@@ -32,7 +33,7 @@ const ModerationMenu = ({ asset = {}, items, getModPath, activeTab }) => {
activeClassName={styles.active}
>
<Icon name={queue.icon} className={styles.tabIcon} /> {queue.name}{' '}
<CountBadge count={queue.count} />
{queue.indicator && <Indicator />}
</Link>
))}
</div>
@@ -15,6 +15,7 @@ import {
} from 'react-virtualized';
import throttle from 'lodash/throttle';
import key from 'keymaster';
import cn from 'classnames';
const hasComment = (nodes, id) => nodes.some(node => node.id === id);
@@ -204,7 +205,7 @@ class ModerationQueue extends React.Component {
}
componentDidUpdate(prev) {
const { commentCount, selectedCommentId } = this.props;
const { selectedCommentId, hasNextPage } = this.props;
const switchedToMultiMode = prev.singleView && !this.props.singleView;
const switchedMode = prev.singleView !== this.props.singleView;
@@ -212,7 +213,6 @@ class ModerationQueue extends React.Component {
prev.selectedCommentId !== selectedCommentId && selectedCommentId;
const moderatedLastComment =
prev.comments.length > 0 && this.getCommentCountWithoutDagling() === 0;
const hasMoreComment = commentCount > 0;
if (switchedToMultiMode) {
// Reflow virtual list.
@@ -223,7 +223,7 @@ class ModerationQueue extends React.Component {
this.scrollToSelectedComment();
}
if (moderatedLastComment && hasMoreComment) {
if (moderatedLastComment && hasNextPage) {
this.props.loadMore();
}
}
@@ -240,10 +240,7 @@ class ModerationQueue extends React.Component {
const index = view.findIndex(
({ id }) => id === this.props.selectedCommentId
);
if (
index === view.length - 1 &&
this.getCommentCountWithoutDagling() !== this.props.commentCount
) {
if (index === view.length - 1 && this.props.hasNextPage) {
await this.props.loadMore();
this.selectDown();
return;
@@ -384,6 +381,11 @@ class ModerationQueue extends React.Component {
...props
} = this.props;
const rootClassName = cn(
styles.root,
`talk-admin-moderate-queue-${this.props.activeTab}`
);
if (comments.length === 0) {
return (
<div className={styles.root}>
@@ -405,7 +407,7 @@ class ModerationQueue extends React.Component {
const comment = comments[index];
return (
<div className={styles.root}>
<div className={rootClassName}>
<Comment
root={this.props.root}
key={comment.id}
@@ -427,7 +429,7 @@ class ModerationQueue extends React.Component {
const view = this.state.view;
return (
<div className={styles.root}>
<div className={rootClassName}>
<ViewMore
viewMore={() => this.viewNewComments()}
count={comments.length - view.length}
@@ -467,7 +469,6 @@ ModerationQueue.propTypes = {
acceptComment: PropTypes.func.isRequired,
commentBelongToQueue: PropTypes.func.isRequired,
cleanUpQueue: PropTypes.func.isRequired,
commentCount: PropTypes.number.isRequired,
loadMore: PropTypes.func.isRequired,
singleView: PropTypes.bool,
isLoadingMore: PropTypes.bool,
@@ -314,11 +314,11 @@ class ModerationContainer extends Component {
const currentQueueConfig = Object.assign({}, this.props.queueConfig);
if (premodEnabled && root.newCount === 0) {
if (premodEnabled && root.new.nodes.length === 0) {
delete currentQueueConfig.new;
}
if (!premodEnabled && root.premodCount === 0) {
if (!premodEnabled && root.premod.nodes.length === 0) {
delete currentQueueConfig.premod;
}
@@ -402,7 +402,7 @@ const COMMENT_RESET_SUBSCRIPTION = gql`
const LOAD_MORE_QUERY = gql`
query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Cursor, $sortOrder: SORT_ORDER, $asset_id: ID, $tags:[String!], $statuses:[COMMENT_STATUS!], $action_type: ACTION_TYPE) {
comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sortOrder: $sortOrder, action_type: $action_type, tags: $tags}) {
comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sortOrder: $sortOrder, action_type: $action_type, tags: $tags, excludeDeleted: true}) {
nodes {
...${getDefinitionName(Comment.fragments.comment)}
}
@@ -432,6 +432,7 @@ const withModQueueQuery = withQuery(
${Object.keys(queueConfig).map(
queue => `
${queue}: comments(query: {
excludeDeleted: true,
statuses: ${
queueConfig[queue].statuses
? `[${queueConfig[queue].statuses.join(', ')}],`
@@ -455,9 +456,14 @@ const withModQueueQuery = withQuery(
}
`
)}
${Object.keys(queueConfig).map(
${
''
/*
TODO: eventually we'll reintroduce counting..
Object.keys(queueConfig).map(
queue => `
${queue}Count: commentCount(query: {
excludeDeleted: true,
statuses: ${
queueConfig[queue].statuses
? `[${queueConfig[queue].statuses.join(', ')}],`
@@ -476,7 +482,8 @@ const withModQueueQuery = withQuery(
asset_id: $asset_id,
})
`
)}
)*/
}
asset(id: $asset_id) @skip(if: $allAssets) {
id
title
@@ -92,9 +92,6 @@
.statusDropdown {
width: 150px;
}
.statusDropdownOption {
min-width: 100px;
text-align: left;
}
@@ -22,20 +22,12 @@ class Stories extends Component {
const closed = !!(closedAt && new Date(closedAt).getTime() < Date.now());
return (
<Dropdown
className={styles.statusDropdown}
toggleClassName={styles.statusDropdown}
value={closed}
onChange={value => this.props.onStatusChange(value, id)}
>
<Option
value={false}
label={t('streams.open')}
className={styles.statusDropdownOption}
/>
<Option
value={true}
label={t('streams.closed')}
className={styles.statusDropdownOption}
/>
<Option value={false} label={t('streams.open')} />
<Option value={true} label={t('streams.closed')} />
</Dropdown>
);
};
+27 -23
View File
@@ -3,32 +3,36 @@ import { getStaticConfiguration } from 'coral-framework/services/staticConfigura
import { createPostMessage } from 'coral-framework/services/postMessage';
document.addEventListener('DOMContentLoaded', () => {
try {
const staticConfig = getStaticConfiguration();
const { STATIC_ORIGIN: origin } = staticConfig;
const postMessage = createPostMessage(origin);
const staticConfig = getStaticConfiguration();
const { STATIC_ORIGIN: origin } = staticConfig;
const postMessage = createPostMessage(origin);
// Get the auth element and parse it as JSON by decoding it.
const auth = document.getElementById('auth');
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = auth.innerText;
// Get the auth element and parse it as JSON by decoding it.
const auth = document.getElementById('auth');
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = auth.innerText;
// Auth state is contained within the node.
const { err, data } = JSON.parse(doc.body.textContent);
if (err) {
// TODO: send back the error message.
console.error(err);
// Auth state is contained within the node.
const { err, data } = JSON.parse(doc.body.textContent);
if (err) {
const errDiv = document.createElement('div');
if (err.message) {
errDiv.innerText = `${err.name}: ${err.message}`;
} else {
// The data will contain a user and a token.
const { user, token } = data;
// Send the state back.
postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token });
errDiv.innerText = JSON.stringify(err);
}
} finally {
// Always close the window.
setTimeout(() => {
window.close();
}, 50);
document.body.appendChild(errDiv);
throw err;
}
// The data will contain a user and a token.
const { user, token } = data;
// Send the state back.
postMessage.post(HANDLE_SUCCESSFUL_LOGIN, { user, token });
// Close the window when all went well.
setTimeout(() => {
window.close();
}, 50);
});
-8
View File
@@ -1,8 +0,0 @@
import React from 'react';
import { render } from 'react-dom';
import { GraphQLDocs } from 'graphql-docs';
import fetcher from './services/fetcher';
// Render the application into the DOM
render(<GraphQLDocs fetcher={fetcher} />, document.querySelector('#root'));
-10
View File
@@ -1,10 +0,0 @@
export default function fetcher(query) {
return fetch(`${window.location.origin}/api/v1/graph/ql`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ query }),
}).then(res => res.json());
}
@@ -24,14 +24,20 @@ export default class Embed extends React.Component {
>
{t('embed_comments_tab')}
</Tab>,
<Tab
key="profile"
tabId="profile"
className="talk-embed-stream-profile-tab"
>
{t('framework.my_profile')}
</Tab>,
];
if (this.props.currentUser) {
tabs.push(
<Tab
key="profile"
tabId="profile"
className="talk-embed-stream-profile-tab"
>
{t('framework.my_profile')}
</Tab>
);
}
if (can(this.props.currentUser, 'UPDATE_ASSET_CONFIG')) {
tabs.push(
<Tab
@@ -43,6 +49,7 @@ export default class Embed extends React.Component {
</Tab>
);
}
return tabs;
}
@@ -16,9 +16,11 @@ class ExtendableTabPanel extends React.Component {
} = this.props;
return (
<div {...rest}>
<TabBar activeTab={activeTab} onTabClick={setActiveTab} sub={sub}>
{tabs}
</TabBar>
{tabs && (
<TabBar activeTab={activeTab} onTabClick={setActiveTab} sub={sub}>
{tabs}
</TabBar>
)}
{loading ? (
<div className={styles.spinnerContainer}>
<Spinner />
+8
View File
@@ -8,6 +8,14 @@ import reducers from './reducers';
import TalkProvider from 'coral-framework/components/TalkProvider';
import pluginsConfig from 'pluginsConfig';
// Resolves touch handling issues encountered on IOS Safari under certain
// circumstances. It may be related to issues reported here:
//
// https://stackoverflow.com/questions/12363742/touchstart-event-is-not-firing-inside-iframe-ios-6
//
// Further details: https://www.pivotaltracker.com/story/show/157794038
document.body.addEventListener('touchstart', () => {});
async function main() {
const context = await createContext({
reducers,
@@ -31,6 +31,7 @@
font-weight: bold;
font-size: 12px;
color: #757575;
cursor: pointer;
}
.commentSummary {
@@ -11,16 +11,6 @@ import { getTotalReactionsCount } from 'coral-framework/utils';
import t from 'coral-framework/services/i18n';
class Comment extends React.Component {
goToStory = () => {
this.props.navigate(this.props.comment.asset.url);
};
goToConversation = () => {
this.props.navigate(
`${this.props.comment.asset.url}?commentId=${this.props.comment.id}`
);
};
render() {
const { comment, root } = this.props;
const reactionCount = getTotalReactionsCount(comment.action_summaries);
@@ -76,8 +66,8 @@ class Comment extends React.Component {
<div className="my-comment-asset">
<a
className={cn(styles.assetURL, 'my-comment-anchor')}
href="#"
onClick={this.goToStory}
href={this.props.comment.asset.url}
target="_parent"
>
{t('common.story')}:{' '}
{comment.asset.title ? comment.asset.title : comment.asset.url}
@@ -87,7 +77,13 @@ class Comment extends React.Component {
<div className={styles.sidebar}>
<ul>
<li>
<a onClick={this.goToConversation} className={styles.viewLink}>
<a
className={styles.viewLink}
href={`${this.props.comment.asset.url}?commentId=${
this.props.comment.id
}`}
target="_parent"
>
<Icon name="open_in_new" className={styles.iconView} />
{t('view_conversation')}
</a>
@@ -1,14 +0,0 @@
.message {
padding: 10px 0 20px;
letter-spacing: 0.1px;
font-size: 13px;
line-height: 33px;
}
.message a {
color: black;
font-weight: bold;
cursor: pointer;
margin: 0px;
padding-bottom: 2px;
}
@@ -1,15 +0,0 @@
import React from 'react';
import styles from './NotLoggedIn.css';
import cn from 'classnames';
import t from 'coral-framework/services/i18n';
export default ({ showSignInDialog }) => (
<div className={cn(styles.message, 'talk-embed-stream-not-logged-in')}>
<div>
<a onClick={showSignInDialog}>{t('settings.sign_in')}</a>{' '}
{t('settings.to_access')}
</div>
<div>{t('from_settings_page')}</div>
</div>
);
@@ -4,13 +4,32 @@ import Slot from 'coral-framework/components/Slot';
import styles from './Profile.css';
import TabPanel from '../containers/TabPanel';
const Profile = ({ username, emailAddress, root, slotPassthrough }) => {
const DefaultProfileHeader = ({ username, emailAddress }) => (
<div className={styles.userInfo}>
<h2 className={styles.username}>{username}</h2>
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
</div>
);
DefaultProfileHeader.propTypes = {
username: PropTypes.string,
emailAddress: PropTypes.string,
};
const Profile = ({ id, username, emailAddress, root, slotPassthrough }) => {
return (
<div className="talk-my-profile talk-profile-container">
<div className={styles.userInfo}>
<h2 className={styles.username}>{username}</h2>
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
</div>
<Slot
fill="profileHeader"
size={1}
defaultComponent={DefaultProfileHeader}
passthrough={{
...slotPassthrough,
id,
username,
emailAddress,
}}
/>
<Slot fill="profileSections" passthrough={slotPassthrough} />
<TabPanel root={root} slotPassthrough={slotPassthrough} />
</div>
@@ -18,6 +37,7 @@ const Profile = ({ username, emailAddress, root, slotPassthrough }) => {
};
Profile.propTypes = {
id: PropTypes.string,
username: PropTypes.string,
emailAddress: PropTypes.string,
root: PropTypes.object,
@@ -2,27 +2,17 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose, gql } from 'react-apollo';
import { bindActionCreators } from 'redux';
import { withQuery } from 'coral-framework/hocs';
import NotLoggedIn from '../components/NotLoggedIn';
import { Spinner } from 'coral-ui';
import Profile from '../components/Profile';
import TabPanel from './TabPanel';
import { getDefinitionName } from 'coral-framework/utils';
import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
import { getSlotFragmentSpreads } from 'coral-framework/utils';
class ProfileContainer extends Component {
componentWillReceiveProps(nextProps) {
if (!this.props.currentUser && nextProps.currentUser) {
// Refetch after login.
this.props.data.refetch();
}
}
render() {
const { currentUser, showSignInDialog, root } = this.props;
const { currentUser, root } = this.props;
const { me } = this.props.root;
const loading = this.props.data.loading;
@@ -30,10 +20,6 @@ class ProfileContainer extends Component {
return <div>{this.props.data.error.message}</div>;
}
if (!currentUser) {
return <NotLoggedIn showSignInDialog={showSignInDialog} />;
}
if (loading || !me) {
return <Spinner />;
}
@@ -44,6 +30,7 @@ class ProfileContainer extends Component {
return (
<Profile
id={me.id}
username={me.username}
emailAddress={emailAddress}
root={root}
@@ -57,10 +44,9 @@ ProfileContainer.propTypes = {
data: PropTypes.object,
root: PropTypes.object,
currentUser: PropTypes.object,
showSignInDialog: PropTypes.func,
};
const slots = ['profileSections'];
const slots = ['profileSections', 'profileSettings', 'profileHeader'];
const withProfileQuery = withQuery(
gql`
@@ -68,6 +54,15 @@ const withProfileQuery = withQuery(
me {
id
username
state {
status {
username {
history {
created_at
}
}
}
}
}
...${getDefinitionName(TabPanel.fragments.root)}
${getSlotFragmentSpreads(slots, 'root')}
@@ -85,10 +80,6 @@ const mapStateToProps = state => ({
currentUser: state.auth.user,
});
const mapDispatchToProps = dispatch =>
bindActionCreators({ showSignInDialog }, dispatch);
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withProfileQuery
)(ProfileContainer);
export default compose(connect(mapStateToProps), withProfileQuery)(
ProfileContainer
);
@@ -214,7 +214,7 @@ AllCommentsPane.propTypes = {
asset: PropTypes.object,
currentUser: PropTypes.object,
postFlag: PropTypes.func,
postDontAgree: PropTypes.func,
postDontAgree: PropTypes.func.isRequired,
loadNewReplies: PropTypes.func,
deleteAction: PropTypes.func,
showSignInDialog: PropTypes.func,
@@ -27,6 +27,7 @@ import {
getActionSummary,
iPerformedThisAction,
isCommentActive,
isCommentDeleted,
getShallowChanges,
} from 'coral-framework/utils';
import t from 'coral-framework/services/i18n';
@@ -183,7 +184,7 @@ export default class Comment extends React.Component {
maxCharCount: PropTypes.number,
root: PropTypes.object,
loadMore: PropTypes.func,
postDontAgree: PropTypes.func,
postDontAgree: PropTypes.func.isRequired,
animateEnter: PropTypes.bool,
commentClassNames: PropTypes.array,
comment: PropTypes.object.isRequired,
@@ -409,6 +410,7 @@ export default class Comment extends React.Component {
charCountEnable,
showSignInDialog,
liveUpdates,
postDontAgree,
emit,
} = this.props;
return (
@@ -439,6 +441,7 @@ export default class Comment extends React.Component {
key={reply.id}
comment={reply}
emit={emit}
postDontAgree={postDontAgree}
/>
);
})}
@@ -574,7 +577,9 @@ export default class Comment extends React.Component {
'talk-stream-comment-header-tags-container'
)}
>
{isStaff(comment.tags) ? <TagLabel>Staff</TagLabel> : null}
{isStaff(comment.tags) ? (
<TagLabel>{t('community.staff')}</TagLabel>
) : null}
<Slot
className={cn(
@@ -740,10 +745,27 @@ export default class Comment extends React.Component {
const id = `c_${comment.id}`;
// props that are passed down the slots.
const slotPassthrough = {
action: 'deleted',
comment,
};
return (
<div className={rootClassName} id={id}>
{this.renderComment()}
{activeReplyBox === comment.id && this.renderReplyBox()}
{isCommentDeleted(comment) ? (
<Slot
fill="commentTombstone"
defaultComponent={CommentTombstone}
size={1}
passthrough={slotPassthrough}
/>
) : (
<div>
{this.renderComment()}
{activeReplyBox === comment.id && this.renderReplyBox()}
</div>
)}
{this.renderRepliesContainer()}
</div>
);
@@ -13,6 +13,8 @@ class CommentTombstone extends React.Component {
return t('framework.comment_is_ignored');
case 'reject':
return t('framework.comment_is_rejected');
case 'deleted':
return t('framework.comment_is_deleted');
default:
return t('framework.comment_is_hidden');
}
@@ -37,6 +39,7 @@ class CommentTombstone extends React.Component {
CommentTombstone.propTypes = {
action: PropTypes.string,
comment: PropTypes.object,
onUndo: PropTypes.func,
};
@@ -18,6 +18,10 @@ const InactiveCommentLabel = ({ status, className, ...rest }) => {
label = t('modqueue.rejected');
icon = 'close';
break;
case 'SYSTEM_WITHHELD':
label = t('modqueue.system_withheld');
icon = 'flag';
break;
default:
throw new Error(`Unknown inactive status ${status}`);
}
@@ -4,6 +4,7 @@ import StreamError from './StreamError';
import Comment from '../containers/Comment';
import BannedAccount from '../../../components/BannedAccount';
import ChangeUsername from '../containers/ChangeUsername';
import Markdown from 'coral-framework/components/Markdown';
import Slot from 'coral-framework/components/Slot';
import InfoBox from './InfoBox';
import { can } from 'coral-framework/services/perms';
@@ -181,7 +182,9 @@ class Stream extends React.Component {
setActiveReplyBox={setActiveReplyBox}
activeReplyBox={activeReplyBox}
notify={notify}
disableReply={asset.isClosed}
disableReply={
asset.isClosed || asset.settings.disableCommenting
}
postComment={postComment}
currentUser={currentUser}
postFlag={postFlag}
@@ -215,7 +218,7 @@ class Stream extends React.Component {
currentUser,
} = this.props;
const { keepCommentBox } = this.state;
const open = !asset.isClosed;
const open = !(asset.isClosed || asset.settings.disableCommenting);
const banned = get(currentUser, 'status.banned.status');
const suspensionUntil = get(currentUser, 'status.suspension.until');
@@ -293,7 +296,13 @@ class Stream extends React.Component {
)}
</div>
) : (
<p>{asset.settings.closedMessage}</p>
<div>
{asset.isClosed ? (
<p>{asset.settings.closedMessage}</p>
) : (
<Markdown content={asset.settings.disableCommentingMessage} />
)}
</div>
)}
<Slot fill="stream" passthrough={slotPassthrough} />
@@ -24,6 +24,7 @@ const slots = [
'commentAuthorName',
'commentAuthorTags',
'commentTimestamp',
'commentTombstone',
'commentContent',
];
@@ -265,7 +265,7 @@ StreamContainer.propTypes = {
commentClassNames: PropTypes.array,
setActiveStreamTab: PropTypes.func,
postFlag: PropTypes.func,
postDontAgree: PropTypes.func,
postDontAgree: PropTypes.func.isRequired,
deleteAction: PropTypes.func,
showSignInDialog: PropTypes.func,
currentUser: PropTypes.object,
@@ -372,6 +372,7 @@ const slots = [
'streamTabsPrepend',
'streamTabPanes',
'streamFilter',
'stream',
];
const fragments = {
@@ -433,6 +434,8 @@ const fragments = {
questionBoxIcon
closedTimeout
closedMessage
disableCommenting
disableCommentingMessage
charCountEnable
charCount
requireEmailConfirmation
+2 -2
View File
@@ -177,8 +177,8 @@ button.comment__action-button[disabled],
}
.talk-plugin-flags-popup-header {
font-weight: bolder;
font-size: 1.33rem;
font-weight: bold;
font-size: 1rem;
margin-bottom: 10px;
}
+7 -15
View File
@@ -15,9 +15,7 @@ export const checkLogin = () => (
rest('/auth')
.then(result => {
if (!result.user) {
if (localStorage) {
cleanAuthData(localStorage);
}
cleanAuthData(localStorage);
dispatch(checkLoginSuccess(null));
return;
}
@@ -52,10 +50,8 @@ const checkLoginSuccess = user => ({
});
export const setAuthToken = token => (dispatch, _, { localStorage }) => {
if (localStorage) {
localStorage.setItem('exp', jwtDecode(token).exp);
localStorage.setItem('token', token);
}
localStorage.setItem('exp', jwtDecode(token).exp);
localStorage.setItem('token', token);
// Dispatch the set auth token action. For some browsers and situations, we
// may not be able to persist the auth token any other way. Keep it in redux!
@@ -70,11 +66,8 @@ export const handleSuccessfulLogin = (user, token) => (
{ client, localStorage, postMessage }
) => {
const { exp } = jwtDecode(token);
if (localStorage) {
localStorage.setItem('exp', exp);
localStorage.setItem('token', token);
}
localStorage.setItem('exp', exp);
localStorage.setItem('token', token);
// Send the message via the messages service to the window.opener if it
// exists.
@@ -105,9 +98,8 @@ export const logout = () => async (
) => {
await rest('/auth', { method: 'DELETE' });
if (localStorage) {
cleanAuthData(localStorage);
}
// Clear the auth data persisted to localStorage.
cleanAuthData(localStorage);
// Reset the websocket.
client.resetWebsocket();
@@ -43,7 +43,7 @@ const ConfigureCard = ({
);
ConfigureCard.propTypes = {
title: PropTypes.string.isRequired,
title: PropTypes.string,
className: PropTypes.string,
onCheckbox: PropTypes.func,
checked: PropTypes.bool,
+11 -5
View File
@@ -37,7 +37,8 @@ export default class Popup extends Component {
this.onBlur();
};
// Use `onunload` instead of `onbeforeunload` which is not supported in IOS Safari.
// Use `onunload` instead of `onbeforeunload` which is not supported in iOS
// Safari.
this.ref.onunload = () => {
this.onUnload();
@@ -46,10 +47,15 @@ export default class Popup extends Component {
}
this.resetCallbackInterval = setInterval(() => {
if (this.ref && this.ref.onload === null) {
clearInterval(this.resetCallbackInterval);
this.resetCallbackInterval = null;
this.setCallbacks();
try {
if (this.ref && this.ref.onload === null) {
clearInterval(this.resetCallbackInterval);
this.resetCallbackInterval = null;
this.setCallbacks();
}
} catch (err) {
// We could be getting a security exception here if the login page
// gets redirected to another domain to authenticate.
}
}, 50);
@@ -1,5 +1,5 @@
import React from 'react';
const PropTypes = require('prop-types');
import PropTypes from 'prop-types';
import { ApolloProvider } from 'react-apollo';
class TalkProvider extends React.Component {
+4 -1
View File
@@ -25,6 +25,9 @@ export default {
'UnsuspendUserResponse',
'UpdateAssetSettingsResponse',
'UpdateAssetStatusResponse',
'UpdateSettingsResponse'
'UpdateSettingsResponse',
'ChangePasswordResponse',
'UpdateEmailAddressResponse',
'AttachLocalAuthResponse'
),
};
+25 -2
View File
@@ -116,7 +116,7 @@ export const withRemoveTag = withMutation(
asset_id: assetId,
item_type: itemType,
},
o3timisticResponse: {
optimisticResponse: {
removeTag: {
__typename: 'ModifyTagResponse',
errors: null,
@@ -169,7 +169,7 @@ export const withSetCommentStatus = withMutation(
},
update: proxy => {
const fragment = gql`
fragment Talk_SetCommentStatus on Comment {
fragment Talk_SetCommentStatus_Comment on Comment {
status
status_history {
type
@@ -182,9 +182,11 @@ export const withSetCommentStatus = withMutation(
const data = proxy.readFragment({ fragment, id: fragmentId });
data.status = status;
data.status_history = data.status_history
? data.status_history
: [];
data.status_history.push({
__typename: 'CommentStatusHistory',
type: status,
@@ -590,6 +592,27 @@ export const withUpdateSettings = withMutation(
}
);
export const withChangePassword = withMutation(
gql`
mutation ChangePassword($input: ChangePasswordInput!) {
changePassword(input: $input) {
...ChangePasswordResponse
}
}
`,
{
props: ({ mutate }) => ({
changePassword: input => {
return mutate({
variables: {
input,
},
});
},
}),
}
);
export const withUpdateAssetSettings = withMutation(
gql`
mutation UpdateAssetSettings($id: ID!, $input: AssetSettingsInput!) {
+1
View File
@@ -6,4 +6,5 @@ export default {
username: t('error.username'),
confirmPassword: t('error.confirm_password'),
organizationName: t('error.organization_name'),
organizationContactEmail: t('error.organization_contact_email'),
};
@@ -4,4 +4,5 @@ export default {
confirmPassword: () => true,
username: username => /^[a-zA-Z0-9_]+$/.test(username),
organizationName: org => /^[a-zA-Z0-9_ ]+$/.test(org),
organizationContactEmail: email => /^.+@.+\..+$/.test(email),
};
@@ -1,9 +1,9 @@
/* global __webpack_public_path__ */ // eslint-disable-line no-unused-vars
/* global __webpack_public_path__, __webpack_nonce__ */ // eslint-disable-line no-unused-vars
import { getStaticConfiguration } from 'coral-framework/services/staticConfiguration';
// Load the static url from the static configuration.
const { STATIC_URL } = getStaticConfiguration();
const { STATIC_URL, SCRIPT_NONCE } = getStaticConfiguration();
// Update the static url for the imported public path so dynamically imported
// chunks will use the correct path as defined by the process.env.STATIC_URL
@@ -14,3 +14,13 @@ const { STATIC_URL } = getStaticConfiguration();
// https://webpack.js.org/configuration/output/#output-publicpath
//
__webpack_public_path__ = STATIC_URL + 'static/';
// All dynamically included scripts that support nonce's will add this to their
// script tags.
//
// The __webpack_nonce__ can be referenced: https://webpack.js.org/guides/csp/
//
// Pending issues:
// - https://github.com/webpack-contrib/style-loader/pull/319
//
__webpack_nonce__ = SCRIPT_NONCE;
@@ -59,6 +59,7 @@ const withSetUsername = hoistStatics(WrappedComponent => {
}
const changeSet = { success: false, loading: false, error };
this.setState(changeSet);
throw error;
}
};
+80 -64
View File
@@ -1,7 +1,10 @@
import ta from 'timeago.js';
import { negotiateLanguages } from 'fluent-langneg/compat';
import has from 'lodash/has';
import get from 'lodash/get';
import merge from 'lodash/merge';
import first from 'lodash/first';
import isUndefined from 'lodash/isUndefined';
import moment from 'moment';
import 'moment/locale/ar';
@@ -9,33 +12,49 @@ import 'moment/locale/da';
import 'moment/locale/de';
import 'moment/locale/es';
import 'moment/locale/fr';
import 'moment/locale/nl';
import 'moment/locale/pt-br';
import { createStorage } from 'coral-framework/services/storage';
// timeago
import ta from 'timeago.js';
import arTA from 'timeago.js/locales/ar';
import daTA from 'timeago.js/locales/da';
import deTA from 'timeago.js/locales/de';
import esTA from 'timeago.js/locales/es';
import frTA from 'timeago.js/locales/fr';
import nlTA from 'timeago.js/locales/nl';
import pt_BRTA from 'timeago.js/locales/pt_BR';
import zh_CNTA from 'timeago.js/locales/zh_CN';
import zh_TWTA from 'timeago.js/locales/zh_TW';
import nl from 'timeago.js/locales/nl';
// locales
import ar from '../../../locales/ar.yml';
import en from '../../../locales/en.yml';
import da from '../../../locales/da.yml';
import de from '../../../locales/de.yml';
import es from '../../../locales/es.yml';
import fr from '../../../locales/fr.yml';
import nl_NL from '../../../locales/nl_NL.yml';
import pt_BR from '../../../locales/pt_BR.yml';
import zh_CN from '../../../locales/zh_CN.yml';
import zh_TW from '../../../locales/zh_TW.yml';
import nl_NL from '../../../locales/nl_NL.yml';
const defaultLanguage = process.env.TALK_DEFAULT_LANG;
const translations = {
// the list of languages that are whitelisted. If false, all languages that are
// supported by Talk will be enabled.
const whitelistedLanguages =
process.env.TALK_WHITELISTED_LANGUAGES &&
process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim());
// The default language. If the whitelisted languages is specified and the
// default language is not in that list, then the first language in the
// whitelisted list will be used as the default.
export const defaultLocale = whitelistedLanguages
? !whitelistedLanguages.includes(process.env.TALK_DEFAULT_LANG)
? whitelistedLanguages[0]
: process.env.TALK_DEFAULT_LANG
: process.env.TALK_DEFAULT_LANG;
export const translations = {
...ar,
...en,
...da,
@@ -48,69 +67,66 @@ const translations = {
...zh_TW,
};
let lang;
let timeagoInstance;
export const supportedLocales = Object.keys(translations);
function setLocale(storage, locale) {
try {
if (storage) {
storage.setItem('locale', locale);
}
} catch (err) {
console.error(err);
}
}
let LOCALE;
let TIMEAGO_INSTANCE;
function getLocale(storage) {
try {
return (
(storage && storage.getItem('locale')) ||
navigator.language ||
defaultLanguage
).split('-')[0];
} catch (err) {
console.error(err);
return null;
}
}
// detectLanguage will try to get the locale from storage if available,
// otherwise will try to get it from the navigator, otherwise, it will fallback
// to the default language.
const detectLanguage = () =>
first(
negotiateLanguages(
navigator.languages,
whitelistedLanguages || supportedLocales,
{
defaultLocale,
strategy: 'lookup',
}
)
);
export function setupTranslations() {
// Setup the translation framework with the storage.
const storage = createStorage('localStorage');
// locale
LOCALE = detectLanguage();
const locale = getLocale(storage);
setLocale(storage, locale);
// Setting moment
moment.locale(locale);
// Extract language key.
lang = locale.split('-')[0];
// Check if we have a translation in this language.
if (!(lang in translations)) {
lang = defaultLanguage;
}
// moment
moment.locale(LOCALE);
// timeago
ta.register('ar', arTA);
ta.register('es', esTA);
ta.register('da', daTA);
ta.register('de', deTA);
ta.register('fr', frTA);
ta.register('pt_BR', pt_BRTA);
ta.register('zh_CN', zh_CNTA);
ta.register('zh_TW', zh_TWTA);
ta.register('nl_NL', nl);
timeagoInstance = ta();
ta.register('nl-NL', nlTA);
ta.register('pt-BR', pt_BRTA);
ta.register('zh-CN', zh_CNTA);
ta.register('zh-TW', zh_TWTA);
TIMEAGO_INSTANCE = ta();
}
/**
* loadTranslations will load the new language pack into the existing ones.
*
* @param {Object} newTranslations translation object to merge into the existing
* languages.
*/
export function loadTranslations(newTranslations) {
// Merge the new translations into the existing translations.
merge(translations, newTranslations);
// Push new languages into the supportedLocales array.
Object.keys(newTranslations).forEach(language => {
if (!supportedLocales.includes(language)) {
supportedLocales.push(language);
}
});
}
export function timeago(time) {
return timeagoInstance.format(new Date(time), lang);
return TIMEAGO_INSTANCE.format(new Date(time), LOCALE);
}
/**
@@ -124,24 +140,24 @@ export function timeago(time) {
*/
export function t(key, ...replacements) {
let translation;
if (has(translations[lang], key)) {
translation = get(translations[lang], key);
if (has(translations[LOCALE], key)) {
translation = get(translations[LOCALE], key);
} else if (has(translations['en'], key)) {
translation = get(translations['en'], key);
console.warn(`${lang}.${key} language key not set`);
console.warn(`${LOCALE}.${key} language key not set`);
}
if (translation) {
// replace any {n} with the arguments passed to this method
replacements.forEach((str, i) => {
translation = translation.replace(new RegExp(`\\{${i}\\}`, 'g'), str);
});
return translation;
} else {
console.warn(`${lang}.${key} and en.${key} language key not set`);
if (!translation) {
console.warn(`${LOCALE}.${key} and en.${key} language key not set`);
return key;
}
// Handle replacements in the translation string.
return translation.replace(
/{(\d+)}/g,
(match, number) =>
!isUndefined(replacements[number]) ? replacements[number] : match
);
}
export default t;
@@ -56,10 +56,10 @@ export function createPostMessage(origin, scope = 'client') {
// Send the message.
target.postMessage(msg, origin);
},
subscribe: (handler, target = window) => {
subscribe(handler, target = window) {
// If this handler is already attached to the target, detach it.
if (has(listeners, [target, handler])) {
this.unsubscribeFromMessages(handler, target);
this.unsubscribe(handler, target);
}
// Wrap the listener with a origin check.
@@ -71,7 +71,7 @@ export function createPostMessage(origin, scope = 'client') {
// Attach the listener to the target.
target.addEventListener('message', listener);
},
unsubscribe: (handler, target = window) => {
unsubscribe(handler, target = window) {
if (!has(listeners, [target, handler])) {
return;
}
+104 -28
View File
@@ -1,40 +1,116 @@
import uuid from 'uuid/v4';
function getStorage(type) {
let storage;
try {
storage = window[type];
const x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
} catch (e) {
const ignore =
e instanceof DOMException &&
// everything except Firefox
(e.code === 22 ||
// SecurityError related to having 3rd party cookies disabled.
e.code === 18 ||
// Firefox
function testStorageAccess(storage) {
const key = '__storage_test__';
e.code === 1014 ||
// test name field too, because code might not be present
// Create a unique test value.
const expectedValue = String(Date.now());
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED');
if (!ignore) {
console.warn(e);
// Try to set, get, and remove that item.
storage.setItem(key, expectedValue);
const canSetGet = expectedValue === storage.getItem(key);
storage.removeItem(key);
if (!canSetGet) {
// We can't access the desired storage!
throw new Error('Storage access test failed');
}
}
// InMemoryStorage is a dumb implementation of the Storage interface that will
// not persist the data at all. It implements the Storage interface found:
//
// https://developer.mozilla.org/en-US/docs/Web/API/Storage
//
class InMemoryStorage {
constructor() {
this.storage = {};
}
get length() {
return Object.keys(this.storage).length;
}
key(n) {
if (this.length <= n) {
return undefined;
}
// When third party cookies are disabled, session storage is readable/
// writable, but localStorage is not. Try to get the sessionStorage to use.
if (type !== 'sessionStorage') {
return getStorage('sessionStorage');
return this.storage[Object.keys(this.storage)[n]];
}
getItem(key) {
return this.storage[key];
}
setItem(key, value) {
this.storage[key] = value;
try {
// Test sessionStorage. We could have been given access recently.
testStorageAccess(sessionStorage);
// Test passed! Set the item in sessionStorage.
sessionStorage.setItem(key, value);
console.log(
'Attempt to persist InMemoryStorage value to sessionStorage succeeded'
);
} catch (err) {
console.warn(
'Attempt to persist InMemoryStorage value to sessionStorage failed',
err
);
}
}
return storage;
removeItem(key) {
delete this.storage[key];
try {
// Test sessionStorage. We could have been given access recently.
testStorageAccess(sessionStorage);
// Test passed! Remove the item from sessionStorage.
sessionStorage.removeItem(key);
console.log(
'Attempt to persist InMemoryStorage delete to sessionStorage succeeded'
);
} catch (err) {
console.warn(
'Attempt to persist InMemoryStorage delete to sessionStorage failed',
err
);
}
}
}
// getStorage will test to see if the requested storage type is available, if it
// is not, it will try sessionStorage, and if that is also not available, it
// will fallback to InMemoryStorage.
function getStorage(type) {
try {
// Get the desired storage from the window and test it out.
const storage = window[type];
testStorageAccess(storage);
// Storage test was successful! Return it.
return storage;
} catch (err) {
// When third party cookies are disabled, session storage is readable/
// writable, but localStorage is not. Try to get the sessionStorage to use.
if (type !== 'sessionStorage') {
console.warn('Could not access', type, 'trying sessionStorage', err);
return getStorage('sessionStorage');
}
console.warn(
'Could not access sessionStorage falling back to InMemoryStorage',
err
);
}
// No acceptable storage could be found, returning the InMemoryStorage.
return new InMemoryStorage();
}
/**
+1
View File
@@ -6,6 +6,7 @@
border: none;
touch-action: manipulation;
padding: 0;
margin: 0;
overflow: hidden;
+33 -1
View File
@@ -1,6 +1,7 @@
import { gql } from 'react-apollo';
import t from 'coral-framework/services/i18n';
import union from 'lodash/union';
import get from 'lodash/get';
import { capitalize } from 'coral-framework/helpers/strings';
import assignWith from 'lodash/assignWith';
import mapValues from 'lodash/mapValues';
@@ -221,6 +222,13 @@ export function isCommentActive(commentStatus) {
return ['NONE', 'ACCEPTED'].indexOf(commentStatus) >= 0;
}
export function isCommentDeleted(comment) {
return (
get(comment, 'body', null) === null ||
get(comment, 'deleted_at', null) !== null
);
}
export function getShallowChanges(a, b) {
return union(Object.keys(a), Object.keys(b)).filter(key => a[key] !== b[key]);
}
@@ -237,7 +245,11 @@ export function getTotalReactionsCount(actionSummaries) {
// Like lodash merge but does not recurse into arrays.
export function mergeExcludingArrays(objValue, srcValue) {
if (typeof srcValue === 'object' && !Array.isArray(srcValue)) {
if (
typeof srcValue === 'object' &&
!Array.isArray(srcValue) &&
srcValue !== null
) {
return assignWith({}, objValue, srcValue, mergeExcludingArrays);
}
return srcValue;
@@ -261,3 +273,23 @@ export function translateError(error) {
}
return error.toString();
}
/**
* handlePopupAuth will optionally open a popup with the requested uri if the
* window is not already a popup.
*
* @param {String} uri the url to open the window? to
* @param {String} title the title of the new window? to open
* @param {String} features the features to use when opening a window?
*/
export function handlePopupAuth(
uri,
title = 'Login', // TODO: translate
features = 'menubar=0,resizable=0,width=500,height=550,top=200,left=500'
) {
if (window.opener) {
window.location = uri;
} else {
window.open(uri, title, features);
}
}

Some files were not shown because too many files have changed in this diff Show More