0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-05-19 23:40:07 +02:00

Commits vergleichen

...

249 Commits

Autor SHA1 Nachricht Datum
merefield 6454d5fd9b sync file with main 2024-02-01 10:56:19 +00:00
merefield b5c64e7379 remove file that does not exist in main 2024-02-01 10:54:16 +00:00
merefield fe0ba14dbd MERGE: of main 2024-02-01 08:30:36 +00:00
merefield 48d651c89a Merge branch 'stable' of github.com:paviliondev/discourse-custom-wizard into stable 2024-02-01 08:26:20 +00:00
Marcos fbb7f4ceef
Merge pull request #285 from paviliondev/ember_5
COMPATIBILITY: Support Discourse 3.2
2024-01-26 13:28:40 -04:00
Angus McLeod f29d1727c3 Update admin-wizards-manager.hbs 2024-01-26 16:22:32 +01:00
Angus McLeod 0a63aac3b2 Add meta topic id 2024-01-26 16:19:54 +01:00
Angus McLeod 61c5355dfc Bump version 2024-01-26 16:18:50 +01:00
Angus McLeod 389d02068c Fix deprecations and broken tests 2024-01-26 16:18:11 +01:00
Angus McLeod 41e240df09 FIX: Specs involving topic CRUD require users with auto_groups
1f72152e47
2023-12-20 14:05:28 +01:00
Angus McLeod 0229043906 FIX: categories need to be initialized so that CategorySelector defines the categoryId list
dcd81d56c0
2023-12-08 17:23:01 +01:00
Angus McLeod e3627e684a Add plugin outlet to the top of the admin wizards route 2023-12-08 10:44:27 +01:00
Robert 4178b337a7
Merge pull request #281 from paviliondev/improve_subscription_classes_rspec_handling
DEV: Integrate subscription gem classes in rspec suite
2023-12-07 16:38:20 +00:00
Robert 8ef30f9514
bump patch 2023-12-07 15:46:55 +00:00
Robert 36d348699d
Merge branch 'main' into improve_subscription_classes_rspec_handling 2023-12-07 15:02:14 +00:00
Angus McLeod 4d2dfb94b9 Update admin.scss 2023-12-05 08:55:31 +01:00
Marcos 60453176bc
Merge pull request #280 from paviliondev/improve_subscription_controls_ux
Update subscription admin ux
2023-12-04 14:51:06 -04:00
Marcos 371e404813 Merge branch 'main' into improve_subscription_controls_ux 2023-12-04 14:36:59 -04:00
Angus McLeod bda35c4a32 DEV: improve send message spec
Check that only one notification is being sent
2023-12-04 15:42:16 +01:00
Angus McLeod cd5649d1ef
Merge branch 'main' into improve_subscription_controls_ux 2023-12-04 15:28:13 +01:00
Angus McLeod 2ad9665e7f Bump plugin version 2023-11-25 13:17:27 +01:00
Angus McLeod 35021eb176 DEV: Integrate subscription gem classes in rspec suite
I've tweaked the subscription client gem so we can just use the gem's models and tables in this plugin's rspec, which makes duplicating and stubbing them unnecessary.

See further https://github.com/paviliondev/discourse_subscription_client
2023-11-25 13:16:55 +01:00
Angus McLeod 635700a51e DEV: custom fields concern has be refactored
6aa69bdaea
2023-11-25 11:35:21 +01:00
Angus McLeod 741491aa48 Change authorize/deauthorize to connect/disconnect 2023-11-17 17:28:58 +01:00
Angus McLeod 191aa08a29 Bump version 2023-11-17 16:18:52 +01:00
Angus McLeod 6c6e402153 Update subscription admin ux 2023-11-17 16:17:10 +01:00
Angus McLeod 7028471603
Merge pull request #266 from paviliondev/use_subscription_gem
DEV: switch to using subscription gem to avoid the need to rely on Subscription Client plugin
2023-11-17 14:03:40 +01:00
merefield f3ca0aaf90 Don't run a remote subsciption status update on every visit to Wizards admin route 2023-11-17 12:50:44 +00:00
merefield fe7b1ecb64 formatting tweak to prevent change of update button status disturbing layout 2023-11-17 12:06:23 +00:00
merefield 812d3d0554 prettier 2023-11-17 11:26:38 +00:00
merefield 591cb9b6ae IMPROVE: utilise button icon to signify update 2023-11-17 11:24:46 +00:00
merefield 320ebe3049 prettier 2023-11-17 10:00:09 +00:00
merefield cf1e661f5e restore client install check 2023-11-17 09:10:46 +00:00
merefield b0d91ccd3c IMPROVE: move Pavilion icon to dedicated file and implementation standard 2023-11-17 09:08:56 +00:00
merefield 4fd128f471 prettier 2023-11-16 17:58:35 +00:00
merefield a7d1d5a9fb fix more FE tests 2023-11-16 17:57:07 +00:00
merefield d297ccd35b prettier 2023-11-16 16:41:54 +00:00
merefield a468c2c868 prettier 2023-11-16 16:35:54 +00:00
merefield ee5ef5574f fix a FE test involving altered Composer 2023-11-16 16:33:46 +00:00
merefield df3e5b6494 COMPATIBILITY: resolve register unbound deprecation 2023-11-16 16:32:39 +00:00
merefield a575feca74 fix some tests 2023-11-15 16:42:53 +00:00
merefield 4444f48da7 prettier 2023-11-15 15:41:14 +00:00
merefield a58b13e9e4 only run remote sub update retrieve on update action 2023-11-15 15:36:21 +00:00
merefield a82af2e016 make init process async 2023-11-15 15:01:27 +00:00
merefield f6ce0f53ad linting 2023-11-15 14:39:42 +00:00
merefield 8e2b117321 make subscription update happen asynchronously on FE 2023-11-15 14:28:54 +00:00
merefield 6be518f0e1 first update local subscriptions before retrieving them 2023-11-15 13:33:02 +00:00
merefield bd712524c1 temp sub update debugging 2023-11-15 10:42:44 +00:00
merefield 2617a6214b merge in main 2023-11-15 10:30:09 +00:00
Angus McLeod 112a0eeee3
Merge pull request #274 from paviliondev/add_discourse_plugin_statistics
Add discourse_plugin_statistics plugin definition
2023-11-15 09:28:22 +01:00
Angus McLeod 5c5624321c
Merge branch 'main' into add_discourse_plugin_statistics 2023-11-14 13:18:57 +01:00
Angus McLeod 1d987647b6 Add note to readme 2023-11-14 13:18:11 +01:00
Angus McLeod c6a729ea72 DEV: PrettyText ctx load breaking change 2023-11-07 09:42:13 +01:00
Angus McLeod bd126d5580
Merge branch 'main' into add_discourse_plugin_statistics 2023-10-30 13:20:30 +08:00
Angus McLeod 9ab77c4b1f
Merge pull request #279 from paviliondev/fix_validations_form 2023-10-19 07:01:54 +08:00
merefield 69ecc7068b bump patch 2023-10-18 13:25:39 +01:00
merefield 2b121d009c COMPATIBILITY: resolve pluginId warning 2023-10-18 13:22:22 +01:00
merefield 8740622b8e COMPATIBILITY: resolve getOwner import deprecation 2023-10-18 13:15:10 +01:00
merefield 78d0cab761 FIX: realtime validations 2023-10-18 13:14:15 +01:00
Angus McLeod a848a4612e
Merge branch 'main' into add_discourse_plugin_statistics 2023-10-16 10:25:44 +08:00
Angus McLeod 9dacdd3eda
Merge pull request #277 from communiteq/master
Replaced documentation links
2023-10-16 09:23:09 +08:00
Angus McLeod 62f2baf9e7
Merge branch 'main' into master 2023-10-16 09:14:21 +08:00
Angus McLeod 3308c38b36 Bump version 2023-10-16 09:12:23 +08:00
Angus McLeod 8eee68a066 Fix prettier errors 2023-10-16 09:09:41 +08:00
Angus McLeod 4ffc0ff103
Merge pull request #278 from AndrewPrigorshnev/dev/stop-using-deprecated-cookAsync-function
DEV: Stop using the deprecated text.cookAsync function
2023-10-11 09:35:00 +08:00
Angus McLeod 757a195047 Bump version 2023-10-11 08:53:50 +08:00
Richard 244f7acea6 Replaced documentation links 2023-10-10 07:29:05 +00:00
Andrei Prigorshnev c052856947
Ensure compatibility 2023-10-09 21:12:14 +04:00
Andrei Prigorshnev ed75e62ebc
DEV: Stop using the deprecated text.cookAsync function 2023-10-09 21:03:51 +04:00
merefield 06e5b4baae try alternative subscription update 2023-10-09 14:02:07 +01:00
merefield 2b867ce678 FEATURE: add a sub refresh button 2023-10-09 13:39:10 +01:00
merefield 1824738bd4 css tweak 2023-10-07 08:53:00 +01:00
merefield 8dc04bda4c merge in of main 2023-10-07 08:22:10 +01:00
merefield d5d500f0d2 bump patch 2023-10-07 08:16:04 +01:00
merefield 0fcbcfb6d6 css tweak 2023-10-07 08:10:43 +01:00
Angus McLeod 1ee2f7d8ba
Merge pull request #276 from paviliondev/filter-categories-for-admin-staff
Filter categories for admin staff
2023-10-07 11:43:19 +08:00
jumagura 9656303c63 DEV: Refactor staff condition in category-chooser for simplicity 2023-10-06 22:35:36 -04:00
jumagura 61c4574908 bump version 2023-10-06 16:26:18 -04:00
jumagura 362c74cb44 DEV: Add exception to display all categories for admin and staff 2023-10-06 16:24:05 -04:00
merefield 9017871f2e linting 2023-10-06 16:37:24 +01:00
merefield 44f2394e75 add front end tests for authorisation and subscription status 2023-10-06 16:30:54 +01:00
Angus McLeod 7613626e9e Update stats gem version 2023-10-06 15:52:42 +08:00
Angus McLeod 4393bd9236 Bump gem stats version 2023-10-06 13:41:37 +08:00
Angus McLeod ab158e0fb7 Bump stats gem version 2023-10-05 14:28:49 +08:00
Angus McLeod 3c41443294 Bump stats gem version 2023-10-05 13:39:56 +08:00
Angus McLeod ba94f59cb7 Undo rubocop autoformat 2023-10-05 09:31:28 +08:00
merefield d8d8eeeb19 merge main, bump patch 2023-10-04 17:20:12 +01:00
Robert 6d6ffa5ea7
Merge pull request #272 from paviliondev/fix_submission_list_order_in_specs
FIX: explicitly order submission list for specs
2023-10-04 17:12:51 +01:00
Robert cef2cc1b65
bump patch 2023-10-04 16:57:09 +01:00
Robert c0c8b16130
Merge branch 'main' into fix_submission_list_order_in_specs 2023-10-04 16:52:51 +01:00
Angus McLeod 5816694456 Bump statistics gem version 2023-10-04 16:13:53 +08:00
Angus McLeod fceb539ab3 Update plugin.rb 2023-10-04 14:50:52 +08:00
Angus McLeod e29605c660 Update plugin.rb 2023-10-04 14:16:52 +08:00
Angus McLeod 6472b2aaa2 Add additional check in feature counter 2023-10-04 13:45:57 +08:00
Angus McLeod 2dd3f5fa72 Bump version 2023-10-04 13:13:58 +08:00
Angus McLeod 21d0357ffd Add discourse_plugin_statistics plugin definition 2023-10-04 13:09:52 +08:00
Angus McLeod 43007d8130
Merge pull request #273 from paviliondev/fix-wizard-topic-creation
FIX: Fix Topic Creation Restriction in Wizard
2023-10-04 09:10:03 +08:00
jumagura 7171e04e3e DEV: Add test of creating post when there are multiple actions 2023-10-03 13:56:45 -04:00
jumagura a5af0b109d DEV: Manage edge case not custom fields 2023-10-02 23:38:01 -04:00
jumagura 4ce82b0d17 fix linting 2023-10-02 22:46:31 -04:00
jumagura 6294f6f9c0 DEV: Add correct parameters for testing 2023-10-02 22:44:54 -04:00
jumagura 98391b565e DEV: Modify test for errors 2023-10-02 22:26:00 -04:00
jumagura 779912332a DEV: remove next condition 2023-10-02 22:25:20 -04:00
jumagura 1d2f75951f FIX: Use wizard_submission_id instead of new value 2023-10-02 22:05:28 -04:00
jumagura 3433bd4141 fix linting 2023-10-02 18:29:12 -04:00
jumagura dae803bf20 bump version 2023-10-02 18:25:36 -04:00
jumagura 24d7ca646a FIX: Refine Topic Creation Hook to Allow Wizard Multi-Step Functionality 2023-10-02 18:18:00 -04:00
Angus McLeod d5aa616ff8 DEV: Add explicit ordering to more specs 2023-09-30 09:46:25 +08:00
Angus McLeod 98b2d85e63 Bump version 2023-09-29 08:36:51 +08:00
Angus McLeod e02f78569a FIX: explicitly order submission list for specs 2023-09-29 08:33:39 +08:00
merefield e120a1a426 one more try 2023-09-28 17:56:27 +01:00
merefield fdfccf51e2 fix titles & labels on sub button 2023-09-28 17:10:11 +01:00
merefield e17f90c5fd fix title 2023-09-28 16:31:58 +01:00
merefield df9a3c6e6e fix title 2023-09-28 15:51:47 +01:00
merefield 4007fd9c65 fix localisation for deauthorize 2023-09-28 15:23:15 +01:00
merefield c8263ed6aa change name of subscription stubbing method to add clarity of intent 2023-09-28 14:27:24 +01:00
merefield 13fb5dc1ea remove redundant code 2023-09-28 13:48:18 +01:00
merefield da2a56adc6 specs: ensure sub client code is mocked out 2023-09-28 13:47:22 +01:00
merefield 4422badf6a locale changes 2023-09-28 12:27:49 +01:00
merefield c0082b82b9 instantiate mocked up interface for more tests 2023-09-28 12:13:45 +01:00
merefield 6aa68ebd5f overcome inheritance that was forcing table look up on tests 2023-09-28 10:07:57 +01:00
merefield 1a32862fd1 namespace fix 2023-09-25 17:00:39 +01:00
merefield c5d8003761 prettier 2023-09-25 16:10:15 +01:00
merefield ea02e53882 prettier 2023-09-25 16:07:41 +01:00
merefield 80fcddc45f fix front end tests 2023-09-25 15:41:01 +01:00
merefield 45db2270ec add FE get suppliers stub 2023-09-24 18:22:39 +01:00
merefield 43ad5785e1 update FE tests 2023-09-24 17:35:20 +01:00
merefield 8407227f53 update back-end tests 2023-09-24 17:18:40 +01:00
merefield 2c109c54f5 update front-end tests 2023-09-24 17:16:40 +01:00
merefield 0ad8616239 linting 2023-09-24 13:13:32 +01:00
merefield 6755c70d31 simplify buttons 2023-09-24 13:01:46 +01:00
merefield 648b976ee0 fix button close 2023-09-24 12:54:05 +01:00
merefield 1fdd78bc7e convert buttons to DButton 2023-09-24 12:52:42 +01:00
merefield c89dbbb7a8 linting 2023-09-24 12:43:20 +01:00
merefield 74a96af622 linting 2023-09-24 12:38:13 +01:00
merefield 0399cff6a5 remove redundant import 2023-09-24 12:27:28 +01:00
merefield 885fdd1215 remove redundant controller link 2023-09-24 12:26:26 +01:00
merefield 18001bebc1 rubocop 2023-09-24 12:20:57 +01:00
merefield 56181f65f4 linting 2023-09-24 12:16:41 +01:00
merefield 15f596e8ec merge in main 2023-09-24 12:12:23 +01:00
merefield db7d9c14bc strip out redundant code from admin wizards route and controller 2023-09-24 12:05:07 +01:00
merefield d5bd3c3c47 prettier 2023-09-24 11:58:20 +01:00
merefield 73e8b0a7fc remove debugging 2023-09-24 11:55:48 +01:00
merefield 5192e08893 change copy for deauthorize label 2023-09-24 10:58:59 +01:00
merefield 9cc65d24b5 revert 2023-09-24 10:46:00 +01:00
merefield dd7f2a7e52 attempted fix 2023-09-24 10:31:42 +01:00
merefield f97d15ac42 debug 2023-09-24 10:19:07 +01:00
merefield a8af37b334 remove redundant sub client check 2023-09-24 10:03:38 +01:00
merefield 7f245d6a59 fix spelling mistake 2023-09-24 10:02:52 +01:00
merefield e43fbd0b50 move subscription container to Glimmer 2023-09-24 10:01:08 +01:00
merefield 0b2e66ba0e tweak route 2023-09-24 09:11:37 +01:00
merefield 390f53a8a2 tweak route 2023-09-24 09:00:28 +01:00
merefield ca11dacf8e tweak route 2023-09-24 08:44:27 +01:00
merefield f012dc2407 fix file inclusion 2023-09-24 08:25:42 +01:00
merefield 26e4267d23 move subscription back-end call 2023-09-24 07:56:39 +01:00
merefield 6a1ead0322 debug 2023-09-24 07:45:12 +01:00
merefield eefbe0a1fc debug 2023-09-24 07:43:42 +01:00
merefield b1fddc33a7 evolve service 2023-09-23 22:52:46 +01:00
merefield a558e19a54 fix variable reference 2023-09-23 18:38:22 +01:00
merefield d6ca154668 rename service class 2023-09-23 18:33:18 +01:00
merefield b454340263 convert subscription mixin to service, colocate glimmer files 2023-09-23 18:30:11 +01:00
merefield 4f8ab0b249 fix 2023-09-22 21:04:42 +01:00
merefield 4f887a858e fix 2023-09-22 20:47:52 +01:00
merefield 2f206f60c7 remove redundant client installed check code 2023-09-22 17:08:03 +01:00
merefield 051d1dbcfd eslint 2023-09-22 14:38:06 +01:00
merefield 437709446e prettier 2023-09-22 14:35:50 +01:00
merefield baf533a8f4 clean up 2023-09-22 14:08:29 +01:00
merefield 76288932c8 Merge branch 'use_subscription_gem' of github.com:paviliondev/discourse-custom-wizard into use_subscription_gem 2023-09-22 14:05:47 +01:00
merefield b78914e4fd evolve 2023-09-22 14:05:05 +01:00
merefield 28f17045c5 debug 2023-09-22 11:22:27 +01:00
merefield 07bed7ec86 evolve 2023-09-22 11:02:44 +01:00
merefield bcd6f86fc8 debug 2023-09-22 10:20:22 +01:00
merefield f1e3db48a3 point to new sub client gem update, add deauthorize action 2023-09-22 08:17:52 +01:00
Angus McLeod 578c92e90e
Merge pull request #269 from paviliondev/composer-control-feature
Composer control feature
2023-09-21 10:43:24 +10:00
jumagura 3d104406fd REFACTOR: Improve test for category chooser when there is a create_topic_wizard customfield 2023-09-20 03:55:32 -04:00
jumagura 0eb6fb1ae0 REFACTOR: Move before_create_topic event handler to plugin.rb 2023-09-19 20:46:42 -04:00
jumagura 0992e9601c DEV: Make hide category default when custom wizard is selected 2023-09-19 14:17:06 -04:00
jumagura 10609f33e2 FIX: linting error 2023-09-19 14:00:04 -04:00
jumagura bb81c5700a DEV: Use Discourse Events instead of topic model 2023-09-19 13:57:11 -04:00
jumagura 03ef41f7f0 FIX: Linting error 2023-09-18 18:11:20 -04:00
jumagura bdd290f4e6 FIX: Linting error 2023-09-18 18:07:27 -04:00
jumagura 2ab15aaf86 FIX: linting error 2023-09-18 18:06:52 -04:00
jumagura de9dccf233 bump version 2023-09-18 17:46:41 -04:00
jumagura bb3f0c6252 DEV: Add acceptance tests for category filtering 2023-09-18 17:41:24 -04:00
jumagura 61309fd320 DEV: Add initializer logic to filter categories 2023-09-18 17:40:44 -04:00
jumagura b365b5dd4f DEV: Add custom_field 2023-09-18 17:40:07 -04:00
jumagura de03cbd15a DEV: Implement control to hide category from composer dropdown in specified categories 2023-09-18 17:39:50 -04:00
jumagura 29d7818a4a DEV: Add spec for validation 2023-09-18 17:36:21 -04:00
jumagura f2d1437cff DEV: Implement wizard replacement validation in Topic Creation 2023-09-18 17:35:38 -04:00
Angus McLeod 9ab4ca21c8
Merge pull request #268 from paviliondev/fix_export_size
FIX: avoid page limit on downloads
2023-09-16 16:03:15 +10:00
merefield 16109b01e7 bump patch 2023-09-15 16:19:09 +01:00
merefield 43cd090b17 FIX: avoid page limit on downloads 2023-09-15 16:15:31 +01:00
Angus McLeod 5f99dc226a
Merge pull request #267 from paviliondev/resolve_deprecations
COMPATIBILITY:  resolve deprecations expected in Ember upgrade for Discourse 3.2
2023-09-15 16:55:45 +10:00
merefield 2460685e65 remove unintentional comment 2023-09-15 07:04:17 +01:00
merefield c6fded7113 fix disabled behaviour of start time button 2023-09-14 21:08:20 +01:00
merefield 713c1bcaa5 fix test 2023-09-14 20:47:05 +01:00
merefield ffa37e895c fix test and test spelling 2023-09-14 20:35:30 +01:00
merefield 22fac139b6 linting 2023-09-14 20:08:10 +01:00
merefield 61ea75dcad remove debugger statement 2023-09-14 20:03:02 +01:00
merefield 766d3b5fc9 fix erroneous route transitions 2023-09-14 20:02:02 +01:00
merefield a786b5956b linting 2023-09-14 19:21:10 +01:00
merefield 794b7c9d5c add missing I18n imports 2023-09-14 19:19:20 +01:00
merefield 76c359be3b linting 2023-09-14 19:16:59 +01:00
merefield 6572b32706 move modals to glimmer components 2023-09-14 19:14:44 +01:00
merefield d71d9976b8 bump patch 2023-09-14 15:05:54 +01:00
merefield 27596a1624 linting 2023-09-14 15:03:15 +01:00
merefield 3c17ef574e linting 2023-09-14 14:59:22 +01:00
merefield 742239b023 add router service to controllers to avoid deprecation 2023-09-14 14:58:34 +01:00
merefield 33a320021f linting 2023-09-14 14:47:52 +01:00
merefield e6f44b7dfc resolve a batch of router deprecations 2023-09-14 14:42:12 +01:00
merefield 31f917ec80 fix replaceWith calling style deprecation 2023-09-14 14:34:18 +01:00
merefield 6c0d7a671e more this additions 2023-09-14 14:18:47 +01:00
merefield 31b2625a65 add this to avoid deprecation 2023-09-14 14:05:55 +01:00
merefield 3a0ba4589d wip 2023-09-08 19:14:36 +01:00
Robert bce0acbfd2
Merge pull request #263 from paviliondev/update-compatibility-main
DEV: Pin plugin for Discourse 3.1 stable
2023-09-08 16:31:17 +01:00
Robert b81bc762c7
Merge branch 'main' into update-compatibility-main 2023-09-08 16:21:00 +01:00
jumagura 785bce228e bump version 2023-09-08 10:02:12 -04:00
merefield c2ffa7699b wip 2023-09-08 10:54:41 +01:00
Angus McLeod 52efc15576
Merge pull request #265 from paviliondev/temp_ignore_redirect
FEATURE: implement a way to temporarily ignore redirect
2023-09-08 09:53:12 +02:00
merefield ebc0f706e3 remove redundant assignment 2023-09-08 07:18:31 +01:00
merefield 050a38a9d3 make code testable, add test 2023-09-08 07:13:52 +01:00
merefield 8649ab2286 bump patch 2023-09-06 16:27:40 +01:00
merefield 037132fb1a prettier 2023-09-06 16:26:30 +01:00
merefield 8332818616 FEATURE: implement way to temporarily ignore redirect 2023-09-06 13:29:21 +01:00
jumagura 36d6f9bc6f bump version 2023-09-05 12:52:11 -04:00
jumagura 121d60330a DEV: Pin plugin for Discourse 3.1 stable 2023-09-05 12:49:58 -04:00
jumagura 13a1538eb9 DEV: Update compatibility for main branch 2023-09-05 12:38:25 -04:00
merefield 27cde861b6 wip 2023-09-04 14:55:51 +01:00
Angus McLeod fee56c2d43
Merge pull request #261 from paviliondev/fix_submissions_data_export_content
SECURITY: remove sensitive user content from submissions export
2023-08-23 17:50:10 +02:00
merefield da4fe79aea bump patch 2023-08-23 14:35:58 +01:00
merefield 0a450d58f4 SECURITY: remove sensitive user content from submissions export 2023-08-23 14:33:56 +01:00
merefield 22edf53cde MERGE: main into stable for 3.0.x 2023-01-30 15:05:07 +00:00
Angus McLeod f5fdb98290 Merge branch 'main' into stable 2022-03-03 21:19:46 +01:00
Angus McLeod d3c8588b62 Merge branch 'main' into stable 2022-02-28 20:32:52 +01:00
Faizaan Gagan c6ec744b13 bump version, cleanup 2022-02-09 12:03:17 +05:30
Angus McLeod ec78229ba0 FIX: use request_store properly 2022-02-09 11:59:00 +05:30
Angus McLeod 5360cef214 Update plugin.rb 2022-02-09 11:58:23 +05:30
Faizaan Gagan 86ff55c33a FEATURE: allow tags from tag field to be confined to a tag group (#175)
* FEATURE: allow tag field to be confined to a tag group

* fixed linting

* bump minor version

* moved monkeypatch to a separate module

* use snake case for variable names

* added specs
2022-02-07 16:00:25 +05:30
angusmcleod 52fe6e2baa Merge branch 'main' into stable 2022-01-31 21:50:12 +08:00
Angus McLeod ecd1fdc5c7 FEATURE: Wizard Composer Mentionables Integration 2021-10-14 18:27:38 +05:30
Faizaan Gagan d696ccd982 Bump version according to policy 2021-10-06 15:36:15 +05:30
angusmcleod 8770266d3e DEV: add stable to github workflows
(cherry picked from commit d4c25d406b)
2021-10-06 17:49:53 +08:00
angusmcleod f537d8504b COMPATIBILITY: require all mixins for forwards compatibility 2021-10-05 11:55:20 +08:00
angusmcleod 72778884fa DEV: Update stable coverage percent 2021-10-05 10:51:10 +08:00
angusmcleod f13b017b83 COMPATIBILITY: backwards compatibility for wizard spec 2021-10-05 10:38:41 +08:00
angusmcleod 76c2fd511c DEV: remove group log settings change from create_group action
(cherry picked from commit 1edfcca78b)
2021-10-05 10:25:23 +08:00
angusmcleod 95b0758647 COMPATIBILITY: Add backwards compatibility for category serialization 2021-10-05 10:07:21 +08:00
Faizaan Gagan 21cf81b7a5 FEATURE: add resume wizard popup (#146)
* FEATURE: add resume wizard popup

* code cleanup, copy edits

* FIX: address functionality, setting and copy issues

@fzngagan a few issues fixed

1. The resume button wasn't working (old reference to ``resumeDialog`` remained in callback.
2. This needs a wizard setting
3. It's not necessary to serialize the first step separately. We have all the steps in ``steps`` and steps have indexes.
4. Button copy

* Fix linting

* Ensure aa submission exists

* Apply prettier

Co-authored-by: angusmcleod <angus@mcleod.org.au>
(cherry picked from commit 2678ee153d)
2021-10-05 09:18:18 +08:00
angusmcleod de2faf893f FIX: Minor bugfixes in manager and create_group action
(cherry picked from commit 208cb1229a)
2021-10-05 09:17:13 +08:00
105 geänderte Dateien mit 1536 neuen und 684 gelöschten Zeilen

Datei anzeigen

@ -1,3 +1,4 @@
3.2.0.beta2: 1ee2f7d8babafe32912372fbbfa50c89f5b09ba9
3.1.999: 1f35b80f85e5fd1efb7f4851f0845700432febdc
2.7.99: e07a57e398b6b1676ab42a7e34467556fca5416b
2.5.1: bb85b3a0d2c0ab6b59bcb405731c39089ec6731c

Datei anzeigen

@ -6,3 +6,9 @@ RSpec/ContextWording:
RSpec/DescribeClass:
Enabled: false
Discourse/TimeEqMatcher:
Enabled: false
Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
Enabled: false

Datei anzeigen

@ -4,7 +4,7 @@ The Custom Wizard Plugin lets you make forms for your Discourse forum. Better us
<img src="https://camo.githubusercontent.com/593432f1fc9658ffca104065668cc88fa21dffcd3002cb78ffd50c71f33a2523/68747470733a2f2f706176696c696f6e2d6173736574732e6e7963332e63646e2e6469676974616c6f6365616e7370616365732e636f6d2f706c7567696e732f77697a6172642d7265706f7369746f72792d62616e6e65722e706e67" alt="" data-canonical-src="https://pavilion-assets.nyc3.cdn.digitaloceanspaces.com/plugins/wizard-repository-banner.png" style="max-width: 100%;" width="400">
👋 Looking to report an issue? We're managing issues for this plugin using our [bug report wizard](https://coop.pavilion.tech/w/bug-report).
👋 Looking to report an issue? We're managing issues for this plugin using our [bug report wizard](https://pavilion.tech/products/discourse-custom-wizard-plugin/support/bug-report).
## Install
@ -12,16 +12,20 @@ If you're not sure how to install a plugin in Discourse, please follow the [plug
## Documentation
[Read the full documentation here](https://coop.pavilion.tech/c/82), or go directly to the relevant section
[Read the full documentation here](https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/), or go directly to the relevant section
- [Wizard Administration](https://coop.pavilion.tech/t/1602)
- [Wizard Settings](https://coop.pavilion.tech/t/1614)
- [Step Settings](https://coop.pavilion.tech/t/1735)
- [Field Settings](https://coop.pavilion.tech/t/1580)
- [Conditional Settings](https://coop.pavilion.tech/t/1673)
- [Field Interpolation](https://coop.pavilion.tech/t/1557)
- [Step Settings](https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/step-settings)
- [Field Settings](https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/field-settings)
- [Conditional Settings](https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/conditional-settings)
- [Field Interpolation](https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/field-interpolation)
- [Handling Dates and Times](https://coop.pavilion.tech/t/1708)
## Support
- [Report an issue](https://coop.pavilion.tech/w/bug-report)
- [Report an issue](https://pavilion.tech/products/discourse-custom-wizard-plugin/support/bug-report)
## Statistics
For improved service and development, this plugin collects some generalised quantitative data related to version and usage. No personal or sensitive information is gathered. Please email contact@pavilion.tech if you have any questions or concerns about our data collection.

Datei anzeigen

@ -2,16 +2,6 @@
class CustomWizard::AdminController < ::Admin::AdminController
before_action :ensure_admin
def index
subcription = CustomWizard::Subscription.new
render_json_dump(
subscribed: subcription.subscribed?,
subscription_type: subcription.type,
subscription_attributes: CustomWizard::Subscription.attributes,
subscription_client_installed: CustomWizard::Subscription.client_installed?
)
end
private
def find_wizard

Datei anzeigen

@ -22,7 +22,12 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
end
def download
send_data submission_list.submissions.to_json,
content = ActiveModel::ArraySerializer.new(
CustomWizard::Submission.list(@wizard).submissions,
each_serializer: CustomWizard::SubmissionSerializer
)
send_data content.to_json,
filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json",
content_type: "application/json",
disposition: "attachment"

Datei anzeigen

@ -0,0 +1,18 @@
# frozen_string_literal: true
class CustomWizard::SubscriptionController < ::Admin::AdminController
before_action :ensure_admin
def index
if params[:update_from_remote]
subscription = CustomWizard::Subscription.new(true)
else
subscription = CustomWizard::Subscription.new
end
render_json_dump(
subscribed: subscription.subscribed?,
subscription_type: subscription.type,
subscription_attributes: CustomWizard::Subscription.attributes,
)
end
end

Datei anzeigen

@ -5,7 +5,7 @@ import { makeArray } from "discourse-common/lib/helpers";
export default CategorySelector.extend({
classNames: ["category-selector", "wizard-category-selector"],
content: computed(
"categories.[]",
"categoryIds.[]",
"blacklist.[]",
"whitelist.[]",
function () {

Datei anzeigen

@ -12,12 +12,14 @@ import { alias } from "@ember/object/computed";
import Site from "discourse/models/site";
import { uploadIcon } from "discourse/lib/uploads";
import { dasherize } from "@ember/string";
import showModal from "discourse/lib/show-modal";
import InsertHyperlink from "discourse/components/modal/insert-hyperlink";
import { inject as service } from "@ember/service";
const IMAGE_MARKDOWN_REGEX =
/!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
export default ComposerEditor.extend({
modal: service(),
classNameBindings: ["fieldClass"],
allowUpload: true,
@ -198,9 +200,8 @@ export default ComposerEditor.extend({
if (this._lastSel) {
linkText = this._lastSel.value;
}
showModal("insert-hyperlink").setProperties({
linkText,
toolbarEvent,
this.modal.show(InsertHyperlink, {
model: { linkText, toolbarEvent },
});
},

Datei anzeigen

@ -3,6 +3,8 @@ import Category from "discourse/models/category";
import Component from "@ember/component";
export default Component.extend({
categories: [],
didInsertElement() {
const property = this.field.property || "id";
const value = this.field.value;

Datei anzeigen

@ -1,7 +1,7 @@
import Component from "@ember/component";
import { dasherize } from "@ember/string";
import discourseComputed from "discourse-common/utils/decorators";
import { cookAsync } from "discourse/lib/text";
import { cook } from "discourse/lib/text";
export default Component.extend({
classNameBindings: [
@ -14,7 +14,7 @@ export default Component.extend({
didReceiveAttrs() {
this._super(...arguments);
cookAsync(this.field.translatedDescription).then((cookedDescription) => {
cook(this.field.translatedDescription).then((cookedDescription) => {
this.set("cookedDescription", cookedDescription);
});
},

Datei anzeigen

@ -4,7 +4,7 @@ import I18n from "I18n";
import getUrl from "discourse-common/lib/get-url";
import { htmlSafe } from "@ember/template";
import { schedule } from "@ember/runloop";
import { cookAsync } from "discourse/lib/text";
import { cook } from "discourse/lib/text";
import CustomWizard, {
updateCachedWizard,
} from "discourse/plugins/discourse-custom-wizard/discourse/models/custom-wizard";
@ -25,10 +25,10 @@ export default Component.extend({
didReceiveAttrs() {
this._super(...arguments);
cookAsync(this.step.translatedTitle).then((cookedTitle) => {
cook(this.step.translatedTitle).then((cookedTitle) => {
this.set("cookedTitle", cookedTitle);
});
cookAsync(this.step.translatedDescription).then((cookedDescription) => {
cook(this.step.translatedDescription).then((cookedDescription) => {
this.set("cookedDescription", cookedDescription);
});
},

Datei anzeigen

@ -0,0 +1,34 @@
<DModal @closeModal={{@closeModal}} @title={{this.title}}>
{{#if loading}}
<LoadingSpinner size="large" />
{{else}}
<div class="edit-directory-columns-container">
{{#each @model.columns as |column|}}
<div class="edit-directory-column">
<div class="left-content">
<label class="column-name">
<Input @type="checkbox" @checked={{column.enabled}} />
{{directory-table-header-title
field=column.label
translated=true
}}
</label>
</div>
</div>
{{/each}}
</div>
{{/if}}
<div class="modal-footer">
<DButton
class="btn-primary"
@label="directory.edit_columns.save"
@action={{action "save"}}
/>
<DButton
class="btn-secondary reset-to-default"
@label="directory.edit_columns.reset_to_default"
@action={{action "resetToDefault"}}
/>
</div>
</DModal>

Datei anzeigen

@ -0,0 +1,17 @@
import Component from "@glimmer/component";
import { action } from "@ember/object";
import I18n from "I18n";
export default class AdminWizardsColumnComponent extends Component {
title = I18n.t("admin.wizard.edit_columns");
@action
save() {
this.args.closeModal();
}
@action
resetToDefault() {
this.args.model.reset();
}
}

Datei anzeigen

@ -0,0 +1,20 @@
<DModal
@closeModal={{@closeModal}}
class="next-session-time-modal"
@title={{this.title}}
>
<DateTimeInput
@date={{this.bufferedDateTime}}
@onChange={{action "dateTimeChanged"}}
@showTime="true"
@clearable="true"
/>
<div class="modal-footer">
<DButton
@action={{action "submit"}}
class="btn-primary"
@label="admin.wizard.after_time_modal.done"
@disabled={{this.submitDisabled}}
/>
</div>
</DModal>

Datei anzeigen

@ -0,0 +1,32 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import I18n from "I18n";
export default class NextSessionScheduledComponent extends Component {
@tracked bufferedDateTime;
title = I18n.t("admin.wizard.after_time_modal.title");
constructor() {
super(...arguments);
this.bufferedDateTime = this.args.model.dateTime
? moment(this.args.model.dateTime)
: moment(Date.now());
}
get submitDisabled() {
return moment().isAfter(this.bufferedDateTime);
}
@action
submit() {
const dateTime = this.bufferedDateTime;
this.args.model.update(moment(dateTime).utc().toISOString());
this.args.closeModal();
}
@action
dateTimeChanged(dateTime) {
this.bufferedDateTime = dateTime;
}
}

Datei anzeigen

@ -41,7 +41,8 @@ export default Component.extend(UndoChanges, {
};
}),
messageUrl: "https://discourse.pluginmanager.org/t/action-settings",
messageUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/action-settings",
@discourseComputed("action.type")
messageKey(type) {

Datei anzeigen

@ -27,7 +27,8 @@ export default Component.extend(UndoChanges, {
isTextType: or("isText", "isTextarea", "isComposer"),
isComposerPreview: equal("field.type", "composer_preview"),
categoryPropertyTypes: selectKitContent(["id", "slug"]),
messageUrl: "https://discourse.pluginmanager.org/t/field-settings",
messageUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/field-settings",
@discourseComputed("field.type")
validations(type) {

Datei anzeigen

@ -4,7 +4,7 @@ import {
default as discourseComputed,
observes,
} from "discourse-common/utils/decorators";
import { getOwner } from "discourse-common/lib/get-owner";
import { getOwner } from "@ember/application";
import { defaultSelectionType, selectionTypes } from "../lib/wizard-mapper";
import {
generateName,
@ -15,7 +15,7 @@ import {
import Component from "@ember/component";
import { bind, later } from "@ember/runloop";
import I18n from "I18n";
import Subscription from "../mixins/subscription";
import { inject as service } from "@ember/service";
const customFieldActionMap = {
topic: ["create_topic", "send_message"],
@ -27,8 +27,9 @@ const customFieldActionMap = {
const values = ["present", "true", "false"];
export default Component.extend(Subscription, {
export default Component.extend({
classNameBindings: [":mapper-selector", "activeType"],
subscription: service(),
showText: computed("activeType", function () {
return this.showInput("text");
@ -130,7 +131,11 @@ export default Component.extend(Subscription, {
return this.connector === "is";
}),
@discourseComputed("site.groups", "guestGroup", "subscriptionType")
@discourseComputed(
"site.groups",
"guestGroup",
"subscription.subscriptionType"
)
groups(groups, guestGroup, subscriptionType) {
let result = groups;
if (!guestGroup) {

Datei anzeigen

@ -0,0 +1,19 @@
<DButton
@icon={{this.updateIcon}}
@action={{this.update}}
class="btn update"
@disabled={{this.updating}}
@title="admin.wizard.subscription.update.title"
>
{{#if this.updating}}
{{loading-spinner size="small"}}
{{/if}}
</DButton>
<DButton
@action={{this.click}}
class="wizard-subscription-badge {{this.subscription.subscriptionType}}"
@title={{this.title}}
>
{{d-icon "pavilion-logo"}}
<span>{{this.label}}</span>
</DButton>

Datei anzeigen

@ -0,0 +1,46 @@
import { inject as service } from "@ember/service";
import { action, computed } from "@ember/object";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import I18n from "I18n";
export default class WizardSubscriptionBadge extends Component {
@service subscription;
@tracked updating = false;
@tracked updateIcon = "sync";
basePath = "/admin/plugins/subscription-client";
@computed("subscription.subscriptionType")
get i18nKey() {
return `admin.wizard.subscription.type.${
this.subscription.subscriptionType
? this.subscription.subscriptionType
: "none"
}`;
}
@computed("i18nKey")
get title() {
return `${this.i18nKey}.title`;
}
@computed("i18nKey")
get label() {
return I18n.t(`${this.i18nKey}.label`);
}
@action
click() {
window.open(this.subscription.subscriptionCtaLink, "_blank").focus();
}
@action
update() {
this.updating = true;
this.updateIcon = null;
this.subscription.updateSubscriptionStatus().finally(() => {
this.updateIcon = "sync";
this.updating = false;
});
}
}

Datei anzeigen

@ -1,30 +0,0 @@
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
import Subscription from "../mixins/subscription";
import DiscourseURL from "discourse/lib/url";
import I18n from "I18n";
export default Component.extend(Subscription, {
tagName: "a",
classNameBindings: [":wizard-subscription-badge", "subscriptionType"],
attributeBindings: ["title"],
@discourseComputed("subscriptionType")
i18nKey(type) {
return `admin.wizard.subscription.type.${type ? type : "none"}`;
},
@discourseComputed("i18nKey")
title(i18nKey) {
return I18n.t(`${i18nKey}.title`);
},
@discourseComputed("i18nKey")
label(i18nKey) {
return I18n.t(`${i18nKey}.label`);
},
click() {
DiscourseURL.routeTo(this.subscriptionLink);
},
});

Datei anzeigen

@ -0,0 +1,17 @@
<div
class="wizard-subscription-container
{{if this.subscription.subscribed 'subscribed'}}"
>
<div class="subscription-header">
<h4>{{i18n "admin.wizard.subscription.title"}}</h4>
<a href={{subscriptionLink}} title={{i18n subscribedTitle}}>
{{d-icon subscribedIcon}}
{{i18n subscribedLabel}}
</a>
</div>
<div class="subscription-settings">
{{yield}}
</div>
</div>

Datei anzeigen

@ -0,0 +1,26 @@
import Component from "@glimmer/component";
import { computed } from "@ember/object";
import { inject as service } from "@ember/service";
export default class WizardSubscriptionContainer extends Component {
@service subscription;
@computed("subscription.subscribed")
get subscribedIcon() {
return this.subscription.subscribed ? "check" : "times";
}
@computed("subscription.subscribed")
get subscribedLabel() {
return `admin.wizard.subscription.${
this.subscription.subscribed ? "subscribed" : "not_subscribed"
}.label`;
}
@computed("subscription.subscribed")
get subscribedTitle() {
return `admin.wizard.subscription.${
this.subscription.subscribed ? "subscribed" : "not_subscribed"
}.title`;
}
}

Datei anzeigen

@ -1,26 +0,0 @@
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
import Subscription from "../mixins/subscription";
export default Component.extend(Subscription, {
classNameBindings: [":wizard-subscription-container", "subscribed"],
@discourseComputed("subscribed")
subscribedIcon(subscribed) {
return subscribed ? "check" : "times";
},
@discourseComputed("subscribed")
subscribedLabel(subscribed) {
return `admin.wizard.subscription.${
subscribed ? "subscribed" : "not_subscribed"
}.label`;
},
@discourseComputed("subscribed")
subscribedTitle(subscribed) {
return `admin.wizard.subscription.${
subscribed ? "subscribed" : "not_subscribed"
}.title`;
},
});

Datei anzeigen

@ -1,36 +0,0 @@
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
import Subscription from "../mixins/subscription";
import I18n from "I18n";
export default Component.extend(Subscription, {
tagName: "a",
classNameBindings: [":btn", ":btn-pavilion-support", "subscriptionType"],
attributeBindings: ["title"],
@discourseComputed("subscribed")
i18nKey(subscribed) {
return `admin.wizard.subscription.cta.${
subscribed ? "subscribed" : "none"
}`;
},
@discourseComputed("subscribed")
icon(subscribed) {
return subscribed ? "far-life-ring" : "external-link-alt";
},
@discourseComputed("i18nKey")
title(i18nKey) {
return I18n.t(`${i18nKey}.title`);
},
@discourseComputed("i18nKey")
label(i18nKey) {
return I18n.t(`${i18nKey}.label`);
},
click() {
window.open(this.subscriptionCtaLink, "_blank").focus();
},
});

Datei anzeigen

@ -1,5 +1,5 @@
import SingleSelectComponent from "select-kit/components/single-select";
import Subscription from "../mixins/subscription";
import { inject as service } from "@ember/service";
import { filterValues } from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "I18n";
@ -12,8 +12,9 @@ const nameKey = function (feature, attribute, value) {
}
};
export default SingleSelectComponent.extend(Subscription, {
export default SingleSelectComponent.extend({
classNames: ["combo-box", "wizard-subscription-selector"],
subscription: service(),
selectKitOptions: {
autoFilterable: false,
@ -26,7 +27,7 @@ export default SingleSelectComponent.extend(Subscription, {
},
allowedSubscriptionTypes(feature, attribute, value) {
let attributes = this.subscriptionAttributes[feature];
let attributes = this.subscription.subscriptionAttributes[feature];
if (!attributes || !attributes[attribute]) {
return ["none"];
}
@ -59,10 +60,9 @@ export default SingleSelectComponent.extend(Subscription, {
name: I18n.t(nameKey(feature, attribute, value)),
subscriptionRequired,
};
if (subscriptionRequired) {
let subscribed = allowedSubscriptionTypes.includes(
this.subscriptionType
this.subscription.subscriptionType
);
let selectorKey = subscribed ? "subscribed" : "not_subscribed";
let selectorLabel = `admin.wizard.subscription.${selectorKey}.selector`;

Datei anzeigen

@ -0,0 +1,22 @@
<div class="supplier-authorize">
<WizardSubscriptionBadge />
{{#if authorized}}
{{conditional-loading-spinner size="small" condition=unauthorizing}}
<DButton
class="deauthorize"
@title="admin.wizard.subscription.deauthorize.title"
@disabled={{unauthorizing}}
@action={{this.deauthorize}}
>
{{i18n "admin.wizard.subscription.deauthorize.label"}}
</DButton>
{{else}}
<DButton
@icon="id-card"
class="btn-primary"
@label="admin.wizard.subscription.authorize.label"
@title="admin.wizard.subscription.authorize.title"
@action={{this.authorize}}
/>
{{/if}}
</div>

Datei anzeigen

@ -0,0 +1,53 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default class WizardSubscriptionStatus extends Component {
@service siteSettings;
@service subscription;
@tracked supplierId = null;
@tracked authorized = false;
@tracked unauthorizing = false;
basePath = "/admin/plugins/subscription-client/suppliers";
constructor() {
super(...arguments);
ajax(`${this.basePath}`)
.then((result) => {
this.supplierId = result.suppliers[0].id;
this.authorized = result.suppliers[0].authorized;
})
.finally(() => {
this.subscription.retrieveSubscriptionStatus();
});
}
@action
authorize() {
window.location.href = `${this.basePath}/authorize?supplier_id=${this.supplierId}&final_landing_path=/admin/wizards/wizard`;
}
@action
deauthorize() {
this.unauthorizing = true;
ajax(`${this.basePath}/authorize`, {
type: "DELETE",
data: {
supplier_id: this.supplierId,
},
})
.then((result) => {
this.supplierId = result.supplier.id;
this.authorized = !(result.supplier.authorized_at === null);
})
.finally(() => {
this.unauthorizing = false;
this.subscription.retrieveSubscriptionStatus();
})
.catch(popupAjaxError);
}
}

Datei anzeigen

@ -7,8 +7,11 @@ import { selectKitContent } from "../lib/wizard";
import { underscore } from "@ember/string";
import Controller from "@ember/controller";
import I18n from "I18n";
import { inject as service } from "@ember/service";
export default Controller.extend({
router: service(),
queryParams: ["refresh_list"],
loadingSubscriptions: false,
notAuthorized: not("api.authorized"),
@ -248,7 +251,7 @@ export default Controller.extend({
.catch(popupAjaxError)
.then((result) => {
if (result.success) {
this.transitionToRoute("adminWizardsApis").then(() => {
this.router.transitionTo("adminWizardsApis").then(() => {
this.send("refreshModel");
});
}

Datei anzeigen

@ -1,14 +0,0 @@
import Controller from "@ember/controller";
import ModalFunctionality from "discourse/mixins/modal-functionality";
export default Controller.extend(ModalFunctionality, {
actions: {
save() {
this.send("closeModal");
},
resetToDefault() {
this.get("model.reset")();
},
},
});

Datei anzeigen

@ -4,7 +4,8 @@ import CustomWizardCustomField from "../models/custom-wizard-custom-field";
export default Controller.extend({
messageKey: "create",
fieldKeys: ["klass", "type", "name", "serializers"],
documentationUrl: "https://discourse.pluginmanager.org/t/custom-fields",
documentationUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/custom-fields",
actions: {
addField() {

Datei anzeigen

@ -2,7 +2,8 @@ import Controller from "@ember/controller";
import { default as discourseComputed } from "discourse-common/utils/decorators";
export default Controller.extend({
documentationUrl: "https://thepavilion.io/t/2818",
documentationUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/",
@discourseComputed("wizardId")
wizardName(wizardId) {

Datei anzeigen

@ -7,7 +7,8 @@ import I18n from "I18n";
import { underscore } from "@ember/string";
export default Controller.extend({
messageUrl: "https://discourse.pluginmanager.org/t/wizard-manager",
messageUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/wizard-manager",
messageKey: "info",
messageIcon: "info-circle",
messageClass: "info",

Datei anzeigen

@ -2,11 +2,13 @@ import Controller from "@ember/controller";
import { empty } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed";
import showModal from "discourse/lib/show-modal";
import { inject as service } from "@ember/service";
import AdminWizardsColumnsModal from "../components/modal/admin-wizards-columns";
import CustomWizardAdmin from "../models/custom-wizard-admin";
import { formatModel } from "../lib/wizard-submission";
export default Controller.extend({
modal: service(),
downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download"),
noResults: empty("submissions"),
page: 0,
@ -57,7 +59,7 @@ export default Controller.extend({
},
showEditColumnsModal() {
return showModal("admin-wizards-columns", {
return this.modal.show(AdminWizardsColumnsModal, {
model: {
columns: this.get("fields"),
reset: () => {

Datei anzeigen

@ -2,7 +2,8 @@ import Controller from "@ember/controller";
import { default as discourseComputed } from "discourse-common/utils/decorators";
export default Controller.extend({
documentationUrl: "https://thepavilion.io/t/2818",
documentationUrl:
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/",
@discourseComputed("wizardId")
wizardName(wizardId) {

Datei anzeigen

@ -3,7 +3,8 @@ import {
observes,
} from "discourse-common/utils/decorators";
import { notEmpty } from "@ember/object/computed";
import showModal from "discourse/lib/show-modal";
import { inject as service } from "@ember/service";
import NextSessionScheduledModal from "../components/modal/next-session-scheduled";
import { generateId, wizardFieldList } from "../lib/wizard";
import { dasherize } from "@ember/string";
import { later, scheduleOnce } from "@ember/runloop";
@ -13,6 +14,7 @@ import I18n from "I18n";
import { filterValues } from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
export default Controller.extend({
modal: service(),
hasName: notEmpty("wizard.name"),
@observes("currentStep")
@ -126,15 +128,13 @@ export default Controller.extend({
},
setNextSessionScheduled() {
let controller = showModal("next-session-scheduled", {
this.modal.show(NextSessionScheduledModal, {
model: {
dateTime: this.wizard.after_time_scheduled,
update: (dateTime) =>
this.set("wizard.after_time_scheduled", dateTime),
},
});
controller.setup();
},
copyUrl() {

Datei anzeigen

@ -22,5 +22,5 @@ export default Controller.extend({
},
messageUrl:
"https://discourse.pluginmanager.org/c/discourse-custom-wizard/documentation",
"https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/",
});

Datei anzeigen

@ -1,9 +1,12 @@
import Controller from "@ember/controller";
import { equal, or } from "@ember/object/computed";
import { or } from "@ember/object/computed";
import { inject as service } from "@ember/service";
export default Controller.extend({
businessSubscription: equal("subscriptionType", "business"),
communitySubscription: equal("subscriptionType", "community"),
standardSubscription: equal("subscriptionType", "standard"),
showApi: or("businessSubscription", "communitySubscription"),
subscription: service(),
showApi: or(
"subscription.businessSubscription",
"subscription.communitySubscription"
),
});

Datei anzeigen

@ -1,7 +1,9 @@
import Controller from "@ember/controller";
import getUrl from "discourse-common/lib/get-url";
import { inject as service } from "@ember/service";
export default Controller.extend({
router: service(),
wizard: null,
step: null,
@ -15,12 +17,12 @@ export default Controller.extend({
const wizardId = this.get("wizard.id");
window.location.href = getUrl(`/w/${wizardId}/steps/${nextStepId}`);
} else {
this.transitionToRoute("customWizardStep", nextStepId);
this.router.transitionTo("customWizardStep", nextStepId);
}
},
goBack() {
this.transitionToRoute("customWizardStep", this.get("step.previous"));
this.router.transitionTo("customWizardStep", this.get("step.previous"));
},
showMessage(message) {

Datei anzeigen

@ -1,30 +0,0 @@
import { default as discourseComputed } from "discourse-common/utils/decorators";
import Controller from "@ember/controller";
export default Controller.extend({
title: "admin.wizard.after_time_modal.title",
setup() {
this.set(
"bufferedDateTime",
this.model.dateTime ? moment(this.model.dateTime) : moment(Date.now())
);
},
@discourseComputed("bufferedDateTime")
submitDisabled(dateTime) {
return moment().isAfter(dateTime);
},
actions: {
submit() {
const dateTime = this.get("bufferedDateTime");
this.get("model.update")(moment(dateTime).utc().toISOString());
this.send("closeModal");
},
dateTimeChanged(dateTime) {
this.set("bufferedDateTime", dateTime);
},
},
});

Datei anzeigen

@ -0,0 +1,21 @@
import I18n from "I18n";
import Handlebars from "handlebars";
export default function wizardCharCounter(body, maxLength) {
let bodyLength = body ? body.length : 0;
let finalString;
if (maxLength) {
let isOverMax = bodyLength > maxLength ? "true" : "false";
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
"wizard.x_characters",
{ count: parseInt(maxLength, 10) }
)}</div>`;
} else {
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
count: parseInt(bodyLength, 10),
})}</div>`;
}
return new Handlebars.SafeString(finalString);
}

Datei anzeigen

@ -1,25 +0,0 @@
import { registerUnbound } from "discourse-common/lib/helpers";
import I18n from "I18n";
import Handlebars from "handlebars";
export default registerUnbound(
"wizard-char-counter",
function (body, maxLength) {
let bodyLength = body ? body.length : 0;
let finalString;
if (maxLength) {
let isOverMax = bodyLength > maxLength ? "true" : "false";
finalString = `<div class="body-length" data-length=${bodyLength} data-over-max=${isOverMax}>${bodyLength} / ${I18n.t(
"wizard.x_characters",
{ count: parseInt(maxLength, 10) }
)}</div>`;
} else {
finalString = `<div class="body-length">${I18n.t("wizard.x_characters", {
count: parseInt(bodyLength, 10),
})}</div>`;
}
return new Handlebars.SafeString(finalString);
}
);

Datei anzeigen

@ -83,6 +83,21 @@ export default {
}
},
});
api.modifyClass("component:category-chooser", {
pluginId: "custom-wizard",
categoriesByScope(options = {}) {
let categories = this._super(options);
const currentUser = this.currentUser;
if (!currentUser?.staff) {
categories = categories.filter((category) => {
return !category.custom_fields?.create_topic_wizard;
});
}
return categories;
},
});
});
},
};

Datei anzeigen

@ -30,6 +30,7 @@ export default {
.concat(["loading"]);
if (
redirectToWizard &&
!data.url.includes("ignore_redirect") &&
data.currentRouteName !== "customWizardStep" &&
!excludedPaths.find((p) => {
return data.currentRouteName.indexOf(p) > -1;

Datei anzeigen

@ -1,5 +1,5 @@
import { get, set } from "@ember/object";
import { getOwner } from "discourse-common/lib/get-owner";
import { getOwnerWithFallback } from "discourse-common/lib/get-owner";
const wizard = {
basic: {
@ -279,7 +279,7 @@ export function filterValues(currentWizard, feature, attribute, values = null) {
return values;
}
const siteSettings = getOwner(this).lookup("service:site-settings");
const siteSettings = getOwnerWithFallback(this).lookup("service:site-settings");
if (siteSettings.wizard_apis_enabled) {
wizardSchema.action.types.send_to_api = {
api: null,

Datei anzeigen

@ -1,5 +1,5 @@
import Mixin from "@ember/object/mixin";
import { getOwner } from "discourse-common/lib/get-owner";
import { getOwner } from "@ember/application";
import { readOnly } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
@ -7,7 +7,7 @@ const PRODUCT_PAGE = "https://custom-wizard.pavilion.tech";
const SUPPORT_MESSAGE =
"https://coop.pavilion.tech/new-message?username=support&title=Custom%20Wizard%20Support";
const MANAGER_CATEGORY =
"https://discourse.pluginmanager.org/c/discourse-custom-wizard";
"https://pavilion.tech/products/discourse-custom-wizard-plugin/support";
export default Mixin.create({
subscriptionLandingUrl: PRODUCT_PAGE,

Datei anzeigen

@ -1,7 +1,10 @@
import CustomWizardApi from "../models/custom-wizard-api";
import DiscourseRoute from "discourse/routes/discourse";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model(params) {
if (params.name === "create") {
return CustomWizardApi.create({ isNew: true });
@ -12,7 +15,7 @@ export default DiscourseRoute.extend({
afterModel(model) {
if (model === null) {
return this.transitionTo("adminWizardsApi");
return this.router.transitionTo("adminWizardsApi");
}
},

Datei anzeigen

@ -1,7 +1,10 @@
import DiscourseRoute from "discourse/routes/discourse";
import CustomWizardApi from "../models/custom-wizard-api";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model() {
return CustomWizardApi.list();
},
@ -25,11 +28,11 @@ export default DiscourseRoute.extend({
actions: {
changeApi(apiName) {
this.controllerFor("adminWizardsApi").set("apiName", apiName);
this.transitionTo("adminWizardsApiShow", apiName);
this.router.transitionTo("adminWizardsApiShow", apiName);
},
afterDestroy() {
this.transitionTo("adminWizardsApi").then(() => this.refresh());
this.router.transitionTo("adminWizardsApi").then(() => this.refresh());
},
afterSave(apiName) {
@ -38,7 +41,7 @@ export default DiscourseRoute.extend({
createApi() {
this.controllerFor("adminWizardsApi").set("apiName", "create");
this.transitionTo("adminWizardsApiShow", "create");
this.router.transitionTo("adminWizardsApiShow", "create");
},
},
});

Datei anzeigen

@ -1,15 +1,18 @@
import CustomWizardLogs from "../models/custom-wizard-logs";
import DiscourseRoute from "discourse/routes/discourse";
import { A } from "@ember/array";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model(params) {
return CustomWizardLogs.list(params.wizardId);
},
afterModel(model) {
if (model === null) {
return this.transitionTo("adminWizardsLogs");
return this.router.transitionTo("adminWizardsLogs");
}
},

Datei anzeigen

@ -1,7 +1,10 @@
import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model() {
return ajax(`/admin/wizards/wizard`);
},
@ -18,7 +21,7 @@ export default DiscourseRoute.extend({
actions: {
changeWizard(wizardId) {
this.controllerFor("adminWizardsLogs").set("wizardId", wizardId);
this.transitionTo("adminWizardsLogsShow", wizardId);
this.router.transitionTo("adminWizardsLogsShow", wizardId);
},
},
});

Datei anzeigen

@ -2,15 +2,18 @@ import { A } from "@ember/array";
import CustomWizardAdmin from "../models/custom-wizard-admin";
import DiscourseRoute from "discourse/routes/discourse";
import { formatModel } from "../lib/wizard-submission";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model(params) {
return CustomWizardAdmin.submissions(params.wizardId);
},
afterModel(model) {
if (model === null) {
return this.transitionTo("adminWizardsSubmissions");
return this.router.transitionTo("adminWizardsSubmissions");
}
},

Datei anzeigen

@ -1,7 +1,10 @@
import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model() {
return ajax(`/admin/wizards/wizard`);
},
@ -18,7 +21,7 @@ export default DiscourseRoute.extend({
actions: {
changeWizard(wizardId) {
this.controllerFor("adminWizardsSubmissions").set("wizardId", wizardId);
this.transitionTo("adminWizardsSubmissionsShow", wizardId);
this.router.transitionTo("adminWizardsSubmissionsShow", wizardId);
},
},
});

Datei anzeigen

@ -2,8 +2,11 @@ import CustomWizardAdmin from "../models/custom-wizard-admin";
import { ajax } from "discourse/lib/ajax";
import DiscourseRoute from "discourse/routes/discourse";
import I18n from "I18n";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model(params) {
if (params.wizardId === "create") {
return { create: true };
@ -14,7 +17,7 @@ export default DiscourseRoute.extend({
afterModel(model) {
if (model.none) {
return this.transitionTo("adminWizardsWizard");
return this.router.transitionTo("adminWizardsWizard");
}
},

Datei anzeigen

@ -4,8 +4,11 @@ import EmberObject, { set } from "@ember/object";
import { A } from "@ember/array";
import { all } from "rsvp";
import { ajax } from "discourse/lib/ajax";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
router: service(),
model() {
return ajax("/admin/wizards/wizard");
},
@ -80,14 +83,14 @@ export default DiscourseRoute.extend({
this.controllerFor("adminWizardsWizard").set("wizardId", wizardId);
if (wizardId) {
this.transitionTo("adminWizardsWizardShow", wizardId);
this.router.transitionTo("adminWizardsWizardShow", wizardId);
} else {
this.transitionTo("adminWizardsWizard");
this.router.transitionTo("adminWizardsWizard");
}
},
afterDestroy() {
this.transitionTo("adminWizardsWizard").then(() => this.refresh());
this.router.transitionTo("adminWizardsWizard").then(() => this.refresh());
},
afterSave(wizardId) {
@ -96,7 +99,7 @@ export default DiscourseRoute.extend({
createWizard() {
this.controllerFor("adminWizardsWizard").set("wizardId", "create");
this.transitionTo("adminWizardsWizardShow", "create");
this.router.transitionTo("adminWizardsWizardShow", "create");
},
},
});

Datei anzeigen

@ -1,23 +1,12 @@
import DiscourseRoute from "discourse/routes/discourse";
import { ajax } from "discourse/lib/ajax";
import { inject as service } from "@ember/service";
export default DiscourseRoute.extend({
model() {
return ajax("/admin/wizards");
},
setupController(controller, model) {
controller.setProperties({
subscribed: model.subscribed,
subscriptionType: model.subscription_type,
subscriptionAttributes: model.subscription_attributes,
subscriptionClientInstalled: model.subscription_client_installed,
});
},
router: service(),
afterModel(model, transition) {
if (transition.targetName === "adminWizards.index") {
this.transitionTo("adminWizardsWizard");
this.router.transitionTo("adminWizardsWizard");
}
},
});

Datei anzeigen

@ -1,11 +1,14 @@
import { getCachedWizard } from "../models/custom-wizard";
import Route from "@ember/routing/route";
import { inject as service } from "@ember/service";
export default Route.extend({
router: service(),
beforeModel() {
const wizard = getCachedWizard();
if (wizard && wizard.permitted && !wizard.completed && wizard.start) {
this.replaceWith("customWizardStep", wizard.start);
this.router.replaceWith("customWizardStep", wizard.start);
}
},

Datei anzeigen

@ -3,14 +3,17 @@ import { getCachedWizard } from "../models/custom-wizard";
import Route from "@ember/routing/route";
import { scrollTop } from "discourse/mixins/scroll-top";
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
export default Route.extend({
router: service(),
beforeModel() {
const wizard = getCachedWizard();
this.set("wizard", wizard);
if (!wizard || !wizard.permitted || wizard.completed) {
this.replaceWith("customWizard");
this.router.replaceWith("customWizard");
}
},
@ -27,7 +30,7 @@ export default Route.extend({
afterModel(model) {
if (model.completed) {
return this.transitionTo("wizard.index");
return this.router.transitionTo("wizard.index");
}
return model.set("wizardId", this.wizard.id);
},

Datei anzeigen

@ -0,0 +1,65 @@
import Service from "@ember/service";
import { tracked } from "@glimmer/tracking";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
const PRODUCT_PAGE = "https://custom-wizard.pavilion.tech";
const SUPPORT_MESSAGE =
"https://coop.pavilion.tech/new-message?username=support&title=Custom%20Wizard%20Support";
const MANAGER_CATEGORY =
"https://coop.pavilion.tech/c/support/discourse-custom-wizard";
export default class SubscriptionService extends Service {
@tracked subscribed = false;
@tracked subscriptionType = "";
@tracked businessSubscription = false;
@tracked communitySubscription = false;
@tracked standardSubscription = false;
@tracked subscriptionAttributes = {};
async init() {
super.init(...arguments);
await this.retrieveSubscriptionStatus();
}
async retrieveSubscriptionStatus() {
let result = await ajax("/admin/wizards/subscription").catch(
popupAjaxError
);
this.subscribed = result.subscribed;
this.subscriptionType = result.subscription_type;
this.subscriptionAttributes = result.subscription_attributes;
this.businessSubscription = this.subscriptionType === "business";
this.communitySubscription = this.subscriptionType === "community";
this.standardSubscription = this.subscriptionType === "standard";
}
async updateSubscriptionStatus() {
let result = await ajax(
"/admin/wizards/subscription?update_from_remote=true"
).catch(popupAjaxError);
this.subscribed = result.subscribed;
this.subscriptionType = result.subscription_type;
this.subscriptionAttributes = result.subscription_attributes;
this.businessSubscription = this.subscriptionType === "business";
this.communitySubscription = this.subscriptionType === "community";
this.standardSubscription = this.subscriptionType === "standard";
}
get subscriptionCtaLink() {
switch (this.subscriptionType) {
case "none":
return PRODUCT_PAGE;
case "standard":
return SUPPORT_MESSAGE;
case "business":
return SUPPORT_MESSAGE;
case "community":
return MANAGER_CATEGORY;
default:
return PRODUCT_PAGE;
}
}
}

Datei anzeigen

@ -66,9 +66,12 @@
{{#each wizards as |wizard|}}
<tr data-wizard-id={{dasherize wizard.id}}>
<td>
{{#link-to "adminWizardsWizardShow" (dasherize wizard.id)}}
<LinkTo
@route="adminWizardsWizardShow"
@model={{dasherize wizard.id}}
>
{{wizard.name}}
{{/link-to}}
</LinkTo>
</td>
<td class="control-column">
<Input

Datei anzeigen

@ -1,3 +1,5 @@
<PluginOutlet @name="admin-wizards-top" @connectorTagName="div" />
{{#admin-nav}}
{{nav-item route="adminWizardsWizard" label="admin.wizard.nav_label"}}
{{nav-item
@ -18,8 +20,7 @@
}}
<div class="admin-actions">
{{wizard-subscription-badge}}
{{wizard-subscription-cta}}
<WizardSubscriptionStatus />
</div>
{{/admin-nav}}

Datei anzeigen

@ -14,7 +14,7 @@
<div class="setting-value">
{{wizard-subscription-selector
value=action.type
value=this.action.type
feature="action"
attribute="type"
onChange=(action "changeType")
@ -31,9 +31,9 @@
<div class="setting-value">
{{combo-box
value=action.run_after
value=this.action.run_after
content=runAfterContent
onChange=(action (mut action.run_after))
onChange=(action (mut this.action.run_after))
}}
</div>
</div>
@ -48,7 +48,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.title
inputs=this.action.title
property="title"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -67,10 +67,10 @@
<div class="setting-value">
{{combo-box
value=action.post
value=this.action.post
content=wizardFields
nameProperty="label"
onChange=(action (mut action.post))
onChange=(action (mut this.action.post))
options=(hash
none="admin.wizard.selector.placeholder.wizard_field"
isDisabled=showPostBuilder
@ -84,7 +84,7 @@
</div>
</div>
{{#if action.post_builder}}
{{#if this.action.post_builder}}
<div class="setting full">
<div class="setting-label">
<label>{{i18n "admin.wizard.action.post_builder.label"}}</label>
@ -92,7 +92,7 @@
<div class="setting-value editor">
{{wizard-text-editor
value=action.post_template
value=this.action.post_template
wizardFields=wizardFields
}}
</div>
@ -108,7 +108,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.category
inputs=this.action.category
property="category"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -131,7 +131,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.tags
inputs=this.action.tags
property="tags"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -153,7 +153,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.visible
inputs=this.action.visible
property="visible"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -171,7 +171,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.add_event
inputs=this.action.add_event
property="add_event"
onUpdate=(action "mappedFieldUpdated")
options=(hash wizardFieldSelection=true context="action")
@ -188,7 +188,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.add_location
inputs=this.action.add_location
property="add_location"
onUpdate=(action "mappedFieldUpdated")
options=(hash wizardFieldSelection=true context="action")
@ -206,7 +206,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.recipient
inputs=this.action.recipient
property="recipient"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -230,7 +230,7 @@
</div>
{{wizard-mapper
inputs=action.profile_updates
inputs=this.action.profile_updates
property="profile_updates"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -254,11 +254,11 @@
<div class="setting-value">
{{combo-box
value=action.api
value=this.action.api
content=availableApis
onChange=(action (mut action.api))
onChange=(action (mut this.action.api))
options=(hash
isDisabled=action.custom_title_enabled
isDisabled=this.action.custom_title_enabled
none="admin.wizard.action.send_to_api.select_an_api"
)
}}
@ -272,9 +272,9 @@
<div class="setting-value">
{{combo-box
value=action.api_endpoint
value=this.action.api_endpoint
content=availableEndpoints
onChange=(action (mut action.api_endpoint))
onChange=(action (mut this.action.api_endpoint))
options=(hash
isDisabled=apiEmpty
none="admin.wizard.action.send_to_api.select_an_endpoint"
@ -290,7 +290,7 @@
<div class="setting-value">
{{wizard-text-editor
value=action.api_body
value=this.action.api_body
previewEnabled=false
barEnabled=false
wizardFields=wizardFields
@ -308,7 +308,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.group
inputs=this.action.group
property="group"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -333,7 +333,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.url
inputs=this.action.url
property="url"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -357,7 +357,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.categories
inputs=this.action.categories
property="categories"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -381,7 +381,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.mute_remainder
inputs=this.action.mute_remainder
property="mute_remainder"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -402,11 +402,11 @@
<div class="setting-value">
{{combo-box
value=action.notification_level
value=this.action.notification_level
content=availableNotificationLevels
onChange=(action (mut action.notification_level))
onChange=(action (mut this.action.notification_level))
options=(hash
isDisabled=action.custom_title_enabled
isDisabled=this.action.custom_title_enabled
none="admin.wizard.action.watch_x.select_a_notification_level"
)
}}
@ -430,7 +430,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.usernames
inputs=this.action.usernames
property="usernames"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -452,7 +452,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.tags
inputs=this.action.tags
property="tags"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -476,11 +476,11 @@
<div class="setting-value">
{{combo-box
value=action.notification_level
value=this.action.notification_level
content=availableNotificationLevels
onChange=(action (mut action.notification_level))
onChange=(action (mut this.action.notification_level))
options=(hash
isDisabled=action.custom_title_enabled
isDisabled=this.action.custom_title_enabled
none="admin.wizard.action.watch_x.select_a_notification_level"
)
}}
@ -504,7 +504,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.usernames
inputs=this.action.usernames
property="usernames"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -526,7 +526,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.name
inputs=this.action.name
property="name"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -545,7 +545,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.full_name
inputs=this.action.full_name
property="full_name"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -564,7 +564,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.title
inputs=this.action.title
property="title"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -583,7 +583,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.bio_raw
inputs=this.action.bio_raw
property="bio_raw"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -602,7 +602,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.owner_usernames
inputs=this.action.owner_usernames
property="owner_usernames"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -622,7 +622,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.usernames
inputs=this.action.usernames
property="usernames"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -644,7 +644,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.grant_trust_level
inputs=this.action.grant_trust_level
property="grant_trust_level"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -665,7 +665,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.mentionable_level
inputs=this.action.mentionable_level
property="mentionable_level"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -686,7 +686,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.messageable_level
inputs=this.action.messageable_level
property="messageable_level"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -707,7 +707,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.visibility_level
inputs=this.action.visibility_level
property="visibility_level"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -728,7 +728,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.members_visibility_level
inputs=this.action.members_visibility_level
property="members_visibility_level"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -750,7 +750,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.name
inputs=this.action.name
property="name"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -770,7 +770,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.slug
inputs=this.action.slug
property="slug"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -790,7 +790,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.color
inputs=this.action.color
property="color"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -810,7 +810,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.text_color
inputs=this.action.text_color
property="text_color"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -832,7 +832,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.parent_category_id
inputs=this.action.parent_category_id
property="parent_category_id"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -853,7 +853,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.permissions
inputs=this.action.permissions
property="permissions"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -878,7 +878,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.custom_fields
inputs=this.action.custom_fields
property="custom_fields"
onUpdate=(action "mappedFieldUpdated")
options=(hash
@ -903,7 +903,7 @@
<div class="setting-value">
{{wizard-mapper
inputs=action.required
inputs=this.action.required
property="required"
onUpdate=(action "mappedFieldUpdated")
options=(hash

Datei anzeigen

@ -1,23 +1,23 @@
{{wizard-mapper-connector
connector=input.type
connectors=inputTypes
connector=this.input.type
connectors=this.inputTypes
inputTypes=true
inputType=inputType
inputType=this.inputType
connectorType="type"
options=options
onUpdate=onUpdate
options=this.options
onUpdate=this.onUpdate
}}
{{#if hasPairs}}
<div class="mapper-pairs mapper-block">
{{#each input.pairs as |pair|}}
{{#each this.input.pairs as |pair|}}
{{wizard-mapper-pair
pair=pair
last=pair.last
inputType=inputType
options=options
inputType=this.inputType
options=this.options
removePair=(action "removePair")
onUpdate=onUpdate
onUpdate=this.onUpdate
}}
{{/each}}
@ -32,27 +32,27 @@
{{#if hasOutput}}
{{#if hasPairs}}
{{wizard-mapper-connector
connector=input.output_connector
connectors=connectors
connector=this.input.output_connector
connectors=this.connectors
connectorType="output"
inputType=inputType
options=options
onUpdate=onUpdate
inputType=this.inputType
options=this.options
onUpdate=this.onUpdate
}}
{{/if}}
<div class="output mapper-block">
{{wizard-mapper-selector
selectorType="output"
inputType=input.type
value=input.output
activeType=input.output_type
options=options
onUpdate=onUpdate
inputType=this.input.type
value=this.input.output
activeType=this.input.output_type
options=this.options
onUpdate=this.onUpdate
}}
</div>
{{/if}}
<a role="button" class="remove-input" {{action remove input}}>
<a role="button" class="remove-input" {{action remove this.input}}>
{{d-icon "times"}}
</a>

Datei anzeigen

@ -7,7 +7,7 @@
<li>
<span class="setting-title">
<h4>{{i18n (concat "admin.wizard.field.validations." type)}}</h4>
<Input @type="checkbox" @checked={{this.props.status}} />
<Input @type="checkbox" @checked={{props.status}} />
{{i18n "admin.wizard.field.validations.enabled"}}
</span>
<div class="validation-container">
@ -36,7 +36,7 @@
<div class="setting-value">
<Input
@type="number"
@value={{this.props.time_n_value}}
@value={{props.time_n_value}}
class="time-n-value"
/>
{{combo-box

Datei anzeigen

@ -1,12 +0,0 @@
<div class="subscription-header">
<h4>{{i18n "admin.wizard.subscription.title"}}</h4>
<a href={{subscriptionLink}} title={{i18n subscribedTitle}}>
{{d-icon subscribedIcon}}
{{i18n subscribedLabel}}
</a>
</div>
<div class="subscription-settings">
{{yield}}
</div>

Datei anzeigen

@ -1 +0,0 @@
{{d-icon icon}}{{label}}

Datei anzeigen

@ -144,9 +144,9 @@
{{/if}}
{{#if isUser}}
{{#link-to "user" value.username}}
<LinkTo @route="user" @model={{value.username}}>
{{avatar value imageSize="tiny"}}
{{/link-to}}
</LinkTo>
{{/if}}
{{#if showUsername}}

Datei anzeigen

@ -1,35 +0,0 @@
{{#d-modal-body title="admin.wizard.edit_columns"}}
{{#if loading}}
{{loading-spinner size="large"}}
{{else}}
<div class="edit-directory-columns-container">
{{#each model.columns as |column|}}
<div class="edit-directory-column">
<div class="left-content">
<label class="column-name">
{{input type="checkbox" checked=column.enabled}}
{{directory-table-header-title
field=column.label
translated=true
}}
</label>
</div>
</div>
{{/each}}
</div>
{{/if}}
{{/d-modal-body}}
<div class="modal-footer">
{{d-button
class="btn-primary"
label="directory.edit_columns.save"
action=(action "save")
}}
{{d-button
class="btn-secondary reset-to-default"
label="directory.edit_columns.reset_to_default"
action=(action "resetToDefault")
}}
</div>

Datei anzeigen

@ -1,17 +0,0 @@
{{#d-modal-body class="next-session-time-modal" title=title}}
{{date-time-input
date=bufferedDateTime
onChange=(action "dateTimeChanged")
showTime=true
clearable=true
}}
{{/d-modal-body}}
<div class="modal-footer">
{{d-button
action=(action "submit")
class="btn-primary"
label="admin.wizard.after_time_modal.done"
disabled=submitDisabled
}}
</div>

Datei anzeigen

@ -43,14 +43,6 @@ $error: #ef1700;
}
}
.admin-wizards .admin-actions {
display: flex;
.btn-pavilion-support {
margin-left: 10px;
}
}
.wizard-message {
background-color: var(--primary-low);
width: 100%;
@ -831,25 +823,6 @@ $error: #ef1700;
vertical-align: middle;
}
.btn.btn-pavilion-support {
background: var(--pavilion-primary);
color: var(--pavilion-secondary);
.d-icon {
color: var(--pavilion-secondary);
}
&:hover,
&:focus {
background: darken($pavilion_primary, 5%);
&[href],
svg.d-icon {
color: darken($pavilion_secondary, 10%);
}
}
}
.wizard-subscription-container {
width: 100%;
padding: 1em;
@ -875,45 +848,49 @@ $error: #ef1700;
}
}
.wizard-subscription-badge {
.btn.wizard-subscription-badge {
display: inline-flex;
align-items: center;
max-height: 34px;
box-sizing: border-box;
position: relative;
cursor: pointer;
padding: 0.5em 0.65em;
background-color: rgba($primary-medium, 0.05);
border: 1.5px solid rgba($primary-medium, 0.5);
color: $primary-medium;
color: var(--secondary);
&:hover {
color: $primary-medium;
}
svg {
svg.d-icon-pavilion-logo {
width: 15px;
height: 15px;
margin-right: 0.45em;
margin-bottom: 0.15em;
color: var(--secondary);
}
&.none {
background-color: var(--subscription-none);
border: 1.5px solid var(--subscription-none);
}
&.standard {
background-color: rgba($subscription_standard, 0.05);
border: 1.5px solid rgba($subscription_standard, 0.5);
color: $subscription_standard;
background-color: var(--subscription-standard);
border: 1.5px solid var(--subscription-standard);
}
&.business {
background-color: $subscription_business;
border: 1.5px solid $subscription_business;
color: $secondary;
background-color: var(--subscription-business);
border: 1.5px solid var(--subscription-business);
}
&.community {
background-color: $subscription_community;
border: 1.5px solid $pavilion_primary;
color: $pavilion_primary;
background-color: var(--subscription-community);
border: 1.5px solid var(--pavilion-primary);
color: var(--pavilion-primary);
&:hover,
svg {
color: var(--pavilion-primary);
}
}
.d-icon {
@ -940,3 +917,32 @@ $error: #ef1700;
font-size: 0.75em;
}
}
.admin-wizards .admin-actions {
.supplier-authorize {
display: inline-flex;
button.update {
width: 40px;
}
.wizard-subscription-badge {
margin-right: 5px;
svg {
margin-right: 0.45em;
}
}
.btn-primary {
margin-right: 5px;
}
.deauthorize {
background-color: var(--secondary);
&:hover {
color: var(--primary);
}
}
}
}

Datei anzeigen

@ -2,6 +2,7 @@ $pavilion_primary: #3c1c8c;
$pavilion_secondary: #ffffff;
$pavilion_warning: rgb(243, 163, 61);
$subscription_none: $pavilion_primary;
$subscription_standard: $pavilion_primary;
$subscription_business: #333;
$subscription_community: #fff;
@ -10,6 +11,7 @@ $subscription_community: #fff;
--pavilion-primary: #{$pavilion_primary};
--pavilion-secondary: #{$pavilion_secondary};
--pavilion-warning: #{$pavilion_warning};
--subscription-none: #{$subscription_none};
--subscription-standard: #{$subscription_standard};
--subscription-business: #{$subscription_business};
--subscription-community: #{$subscription_community};

Datei anzeigen

@ -3,6 +3,16 @@ body.custom-wizard {
color: var(--primary);
font-size: 1.1em;
.sidebar-wrapper {
display: none;
}
#main-outlet-wrapper {
grid-template-areas: "sidebar content";
grid-template-columns: 0 minmax(0, 1fr);
gap: 0;
}
.wizard-column {
position: relative;
z-index: 11;

Datei anzeigen

@ -167,13 +167,13 @@ en:
destroy_complete: Destruction complete
subscription:
documentation: Check out the subscription documentation
authorize: "Authorize this forum to use your Custom Wizard subscription plan on %{server}."
not_subscribed: "You've authorized, but are not currently subscribed to a Custom Wizard plan on %{server}."
authorize: "Connect this forum to use your Custom Wizard subscription plan on %{server}."
not_subscribed: "You've connected, but are not currently subscribed to a Custom Wizard plan on %{server}."
subscription_expiring: "Your subscription is active, but will expire in the next 48 hours."
subscription_active: "Your subscription is active."
subscription_inactive: "Your subscription is inactive on this forum. Read more in <a href='https://thepavilion.io/t/3652'>the documentation</a>."
unauthorized: "You're unauthorized. If you have a subscription, it will become inactive in the next 48 hours."
unauthorize_failed: Failed to unauthorize.
subscription_inactive: "Your subscription is inactive on this forum. Read more in <a href='https://pavilion.tech/products/discourse-custom-wizard-plugin/documentation/'>the documentation</a>."
unauthorized: "You're not connected. If you have a subscription, it will become inactive in the next 48 hours."
unauthorize_failed: Failed to disconnect.
submissions:
select: "Select a wizard to see its submissions"
viewing: "You're viewing the submissions of the %{wizardName}"
@ -545,6 +545,14 @@ en:
subscription:
title: Subscriber Features
authorize:
label: Connect
title: Connect your subscription to this site
deauthorize:
label: Disconnect
title: Disconnect your subscription from this site
update:
title: "Update subscription status"
subscribed:
label: Subscribed
title: You're subscribed and can use these features
@ -555,25 +563,17 @@ en:
selector: not subscribed
type:
none:
label: Not Subscribed
label: Subscribe
title: There is no Custom Wizard subscription active on this forum.
business:
label: Business
label: Support
title: There is a Custom Wizard Business subscription active on this forum.
standard:
label: Standard
label: Support
title: There is a Custom Wizard Standard subscription active on this forum.
community:
label: Community
title: There is a Custom Wizard Community subscription active on this forum.
cta:
none:
label: Get a Subscription
title: Get a subscription for this forum.
subscribed:
label: Support
title: Get support for your subscription.
title: There is a Custom Wizard Community subscription active on this forum.
wizard_js:
group:

Datei anzeigen

@ -55,6 +55,8 @@ en:
liquid_syntax_error: "Liquid syntax error in %{attribute}: %{message}"
subscription: "%{type} %{property} usage is not supported on your subscription"
not_permitted_for_guests: "%{object_id} is not permitted when guests can access the wizard"
error_messages:
wizard_replacing_composer: "Category not allowed for topic creation."
site_settings:
custom_wizard_enabled: "Enable custom wizards."

Datei anzeigen

@ -14,6 +14,7 @@ Discourse::Application.routes.append do
scope module: 'custom_wizard', constraints: AdminConstraint.new do
get 'admin/wizards' => 'admin#index'
get 'admin/wizards/subscription' => 'subscription#index'
get 'admin/wizards/wizard' => 'admin_wizard#index'
get 'admin/wizards/wizard/create' => 'admin#index'

Datei anzeigen

@ -234,16 +234,16 @@ class ::CustomWizard::CustomField
external = []
CLASSES.keys.each do |klass|
field_types = klass.to_s.classify.constantize.custom_field_types
meta_data = klass.to_s.classify.constantize.send('custom_field_meta_data')
if field_types.present?
field_types.each do |name, type|
if meta_data.present?
meta_data.each do |name, data|
unless list.any? { |field| field.name === name }
field = new(
'external',
name: name,
klass: klass,
type: type
type: data.type
)
external.push(field)
end

Datei anzeigen

@ -131,6 +131,8 @@ class CustomWizard::Submission
params[:key] = list_actor_id if list_actor_id
query = PluginStoreRow.where(params)
query = query.order(order_by) if order_by
result = OpenStruct.new(submissions: [], total: nil)
query.each do |record|

Datei anzeigen

@ -1,4 +1,6 @@
# frozen_string_literal: true
require "discourse_subscription_client"
class CustomWizard::Subscription
PRODUCT_HIERARCHY = %w[
community
@ -104,25 +106,27 @@ class CustomWizard::Subscription
attr_accessor :product_id,
:product_slug
def initialize
if CustomWizard::Subscription.client_installed?
result = DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard")
def initialize(update = false)
if update
::DiscourseSubscriptionClient::Subscriptions.update
end
if result&.any?
ids_and_slugs = result.subscriptions.map do |subscription|
{
id: subscription.product_id,
slug: result.products[subscription.product_id]
}
end
result = ::DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard")
id_and_slug = ids_and_slugs.sort do |a, b|
PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug])
end.first
@product_id = id_and_slug[:id]
@product_slug = id_and_slug[:slug]
if result&.any?
ids_and_slugs = result.subscriptions.map do |subscription|
{
id: subscription.product_id,
slug: result.products[subscription.product_id]
}
end
id_and_slug = ids_and_slugs.sort do |a, b|
PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug])
end.first
@product_id = id_and_slug[:id]
@product_slug = id_and_slug[:slug]
end
@product_slug ||= ENV["CUSTOM_WIZARD_PRODUCT_SLUG"]
@ -157,7 +161,7 @@ class CustomWizard::Subscription
return :none unless subscribed?
return :business if business?
return :standard if standard?
return :community if community?
:community if community?
end
def subscribed?
@ -176,6 +180,7 @@ class CustomWizard::Subscription
product_slug === "community"
end
# TODO candidate for removal once code that depends on it externally is no longer used.
def self.client_installed?
defined?(DiscourseSubscriptionClient) == 'constant' && DiscourseSubscriptionClient.class == Module
end

Datei anzeigen

@ -128,7 +128,7 @@ class ::CustomWizard::UpdateValidator
return @ctx if @ctx
@ctx = PrettyText.v8
PrettyText.ctx_load(@ctx, "#{Rails.root}/vendor/assets/javascripts/moment.js")
@ctx.load("#{Rails.root}/vendor/assets/javascripts/moment.js")
@ctx
end
end

Datei anzeigen

@ -0,0 +1,98 @@
# frozen_string_literal: true
module DiscoursePluginStatistics
class Plugin
def self.discourse_custom_wizard
subscription_features = {
wizard: {
save_submissions: 0,
after_signup: 0,
prompt_completion: 0,
required: 0,
permitted: 0,
},
step: {
required_data: 0,
permitted_params: 0,
force_final: 0
},
field: {
condition: 0,
type: {
text: 0,
textarea: 0,
text_only: 0,
date: 0,
time: 0,
date_time: 0,
number: 0,
checkbox: 0,
dropdown: 0,
composer: 0,
composer_preview: 0,
url: 0,
upload: 0,
tag: 0,
category: 0,
group: 0,
user_selector: 0,
},
realtime_validations: 0
},
action: {
type: {
create_topic: 0,
send_message: 0,
update_profile: 0,
open_composer: 0,
route_to: 0,
send_to_api: 0,
watch_categories: 0,
watch_tags: 0,
add_to_group: 0,
create_group: 0,
create_category: 0,
}
}
}
increment_feature_count = lambda do |type, key, value|
if key == 'type'
if !subscription_features[type.to_sym][:type][value.to_sym].nil?
subscription_features[type.to_sym][:type][value.to_sym] += 1
end
else
if !subscription_features[type.to_sym][key.to_sym].nil?
subscription_features[type.to_sym][key.to_sym] += 1
end
end
end
CustomWizard::Template.list.each do |template|
template.each do |key, value|
increment_feature_count.call(:wizard, key, value)
end
template['steps'].each do |step|
step.each do |key, value|
increment_feature_count.call(:step, key, value)
end
step['fields'].each do |field|
field.each do |key, value|
increment_feature_count.call(:field, key, value)
end
end
end
template['actions'].each do |action|
action.each do |key, value|
increment_feature_count.call(:action, key, value)
end
end
end
{
total_wizards: CustomWizard::Template.list.size,
subscription_type: CustomWizard::Subscription.type.to_s,
subscription_features: subscription_features
}
end
end
end

Datei anzeigen

@ -1,15 +1,19 @@
# frozen_string_literal: true
# name: discourse-custom-wizard
# about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more.
# version: 2.4.19
# version: 2.6.0
# authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos
# url: https://github.com/paviliondev/discourse-custom-wizard
# contact_emails: development@pavilion.tech
# subscription_url: https://coop.pavilion.tech
# meta_topic_id: 73345
gem 'liquid', '5.0.1', require: true
gem "discourse_subscription_client", "0.1.1", require_name: "discourse_subscription_client"
gem 'discourse_plugin_statistics', '0.1.0.pre7', require: true
register_asset 'stylesheets/common/admin.scss'
register_asset 'stylesheets/common/wizard.scss'
register_svg_icon 'pavilion-logo'
enabled_site_setting :custom_wizard_enabled
@ -35,6 +39,7 @@ after_initialize do
../lib/custom_wizard/engine.rb
../config/routes.rb
../app/controllers/custom_wizard/admin/admin.rb
../app/controllers/custom_wizard/admin/subscription.rb
../app/controllers/custom_wizard/admin/wizard.rb
../app/controllers/custom_wizard/admin/submissions.rb
../app/controllers/custom_wizard/admin/api.rb
@ -73,6 +78,7 @@ after_initialize do
../lib/custom_wizard/api/log_entry.rb
../lib/custom_wizard/liquid_extensions/first_non_empty.rb
../lib/custom_wizard/exceptions/exceptions.rb
../lib/discourse_plugin_statistics/plugin.rb
../app/serializers/custom_wizard/api/authorization_serializer.rb
../app/serializers/custom_wizard/api/basic_endpoint_serializer.rb
../app/serializers/custom_wizard/api/endpoint_serializer.rb
@ -236,4 +242,14 @@ after_initialize do
end
DiscourseEvent.trigger(:custom_wizard_ready)
on(:before_create_topic) do |topic_params, user|
category = topic_params.category
wizard_submission_id = topic_params.custom_fields&.[]('wizard_submission_id')
if category&.custom_fields&.[]('create_topic_wizard').present? && wizard_submission_id.blank?
raise Discourse::InvalidParameters.new(
I18n.t('wizard.error_messages.wizard_replacing_composer')
)
end
end
end

Datei anzeigen

@ -158,7 +158,7 @@ describe CustomWizard::Action do
action.perform
expect(action.result.success?).to eq(true)
expect(TopicCustomField.exists?(name: custom_field_name, value: custom_field_value)).to eq(true)
expect(TopicCustomField.exists?(name: custom_field_name)).to eq(true)
end
end
@ -253,11 +253,14 @@ describe CustomWizard::Action do
end
it '#send_message' do
Jobs.run_immediately!
target_user = Fabricate(:user)
send_message['recipient'][0]['output'][0] = target_user.username
wizard_template['actions'] << send_message
update_template(wizard_template)
User.create(username: 'angus1', email: "angus1@email.com")
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update
@ -273,18 +276,29 @@ describe CustomWizard::Action do
)
expect(topic.exists?).to eq(true)
expect(topic.first.topic_allowed_users.first.user.username).to eq('angus1')
expect(topic.first.topic_allowed_users.first.user.username).to eq(target_user.username)
expect(post.exists?).to eq(true)
expect(target_user.reload.notifications.count).to eq(1)
end
it '#send_message allows using multiple targets' do
Jobs.run_immediately!
user1 = Fabricate(:user)
user2 = Fabricate(:user)
group1 = Fabricate(:group)
group2 = Fabricate(:group)
send_message_multi['recipient'][0]['output'] = [
user1.username,
user2.username,
group1.name,
group2.name
]
wizard_template['actions'] << send_message_multi
update_template(wizard_template)
update_template(wizard_template)
User.create(username: 'angus1', email: "angus1@email.com")
User.create(username: 'faiz', email: "faiz@email.com")
Group.create(name: "cool_group")
Group.create(name: 'cool_group_1')
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update
@ -300,9 +314,11 @@ describe CustomWizard::Action do
)
expect(topic.exists?).to eq(true)
expect(topic.first.all_allowed_users.map(&:username)).to include('angus1', 'faiz')
expect(topic.first.allowed_groups.map(&:name)).to include('cool_group', 'cool_group_1')
expect(topic.first.all_allowed_users.map(&:username)).to include(user1.username, user2.username)
expect(topic.first.allowed_groups.map(&:name)).to include(group1.name, group2.name)
expect(post.exists?).to eq(true)
expect(user1.reload.notifications.count).to eq(1)
expect(user2.reload.notifications.count).to eq(1)
end
it "send_message works with guests are permitted" do
@ -450,4 +466,29 @@ describe CustomWizard::Action do
expect(action.result.success?).to eq(true)
expect(Topic.find(action.result.output).custom_fields["topic_custom_field"]).to eq("t")
end
context 'creating a topic when there are multiple actions' do
it 'works' do
wizard_template['actions'] << create_topic
wizard_template['actions'] << send_message
update_template(wizard_template)
wizard = CustomWizard::Builder.new(@template[:id], user).build
wizard.create_updater(
wizard.steps.first.id,
step_1_field_1: 'Topic Title',
step_1_field_2: 'topic body'
).update
wizard.create_updater(wizard.steps.second.id, {}).update
wizard.create_updater(wizard.steps.last.id, step_3_field_3: category.id)
.update
User.create(username: 'angus1', email: 'angus1@email.com')
wizard.create_updater(wizard.steps[0].id, {}).update
wizard.create_updater(wizard.steps[1].id, {}).update
topic = Topic.where(title: 'Topic Title', category_id: category.id)
expect(topic.exists?).to eq(true)
expect(
Post.where(topic_id: topic.pluck(:id), raw: 'topic body').exists?
).to eq(true)
end
end
end

Datei anzeigen

@ -259,11 +259,11 @@ describe CustomWizard::CustomField do
expect(CustomWizard::CustomField.list_by(:serializers, ['post']).length).to eq(0)
end
it "lists custom field records added by other plugins " do
it "custom field records added by other plugins " do
expect(CustomWizard::CustomField.external_list.length).to be > 2
end
it "lists all custom field records" do
it "all custom field records" do
expect(CustomWizard::CustomField.full_list.length).to be > 2
end
end

Datei anzeigen

@ -13,43 +13,7 @@ describe CustomWizard::Subscription do
}
}
after do
undefine_client_classes
end
it "detects the subscription client" do
undefine_client_classes
expect(described_class.client_installed?).to eq(false)
end
context "without a subscription client" do
it "is not subscribed" do
expect(described_class.subscribed?).to eq(false)
end
it "has none type" do
subscription = described_class.new
expect(subscription.type).to eq(:none)
end
it "non subscriber features are included" do
expect(described_class.includes?(:wizard, :after_signup, true)).to eq(true)
end
it "subscriber features are not included" do
expect(described_class.includes?(:wizard, :permitted, {})).to eq(false)
end
end
context "with subscription client" do
before do
define_client_classes
end
it "detects the subscription client" do
expect(described_class.client_installed?).to eq(true)
end
context "with subscription client gem mocked out" do
context "without a subscription" do
before do
DiscourseSubscriptionClient.stubs(:find_subscriptions).returns(nil)
@ -69,11 +33,12 @@ describe CustomWizard::Subscription do
end
context "with subscriptions" do
def get_subscription_result(product_ids)
result = DiscourseSubscriptionClient::Subscriptions::Result.new
result.supplier = SubscriptionClientSupplier.new(product_slugs)
result.supplier = SubscriptionClientSupplier.new(products: product_slugs)
result.resource = SubscriptionClientResource.new
result.subscriptions = product_ids.map { |product_id| SubscriptionClientSubscription.new(product_id) }
result.subscriptions = product_ids.map { |product_id| ::SubscriptionClientSubscription.new(product_id: product_id) }
result.products = product_slugs
result
end

Datei anzeigen

@ -0,0 +1,82 @@
# frozen_string_literal: true
describe DiscoursePluginStatistics::Plugin do
let(:template_json) { get_wizard_fixture("wizard") }
describe "#discourse_custom_wizard" do
before do
enable_subscription('standard')
CustomWizard::Template.save(template_json, skip_jobs: true)
template_json_2 = template_json.dup
template_json_2["id"] = 'super_mega_fun_wizard_2'
CustomWizard::Template.save(template_json_2, skip_jobs: true)
@data = DiscoursePluginStatistics::Plugin.discourse_custom_wizard
end
it "includes a total wizard count" do
expect(@data[:total_wizards]).to eq(2)
end
it "includes the subscription type" do
expect(@data[:subscription_type]).to eq('standard')
end
it "includes a count of features being used across all wizards" do
expect(@data[:subscription_features]).to eq(
wizard: {
save_submissions: 2,
after_signup: 2,
prompt_completion: 2,
required: 0,
permitted: 0,
},
step: {
required_data: 0,
permitted_params: 0,
force_final: 0
},
field: {
condition: 0,
type: {
text: 2,
textarea: 2,
text_only: 2,
date: 2,
time: 2,
date_time: 2,
number: 2,
checkbox: 2,
dropdown: 2,
composer: 0,
composer_preview: 0,
url: 0,
upload: 0,
tag: 0,
category: 0,
group: 0,
user_selector: 0,
},
realtime_validations: 0
},
action: {
type: {
create_topic: 2,
send_message: 0,
update_profile: 2,
open_composer: 2,
route_to: 2,
send_to_api: 0,
watch_categories: 0,
watch_tags: 0,
add_to_group: 0,
create_group: 0,
create_category: 0,
}
}
)
end
end
end

Datei anzeigen

@ -20,7 +20,7 @@ describe "custom field extensions" do
context "topic" do
it "registers topic custom fields" do
topic
expect(Topic.get_custom_field_type("topic_field_1")).to eq(:boolean)
expect(Topic.get_custom_field_descriptor("topic_field_1").type).to eq(:boolean)
end
it "adds topic custom fields to the topic_view serializer" do
@ -53,7 +53,7 @@ describe "custom field extensions" do
context "post" do
it "registers post custom fields" do
post
expect(Post.get_custom_field_type("post_field_1")).to eq(:integer)
expect(Post.get_custom_field_descriptor("post_field_1").type).to eq(:integer)
end
it "adds post custom fields to the post serializer" do
@ -83,7 +83,7 @@ describe "custom field extensions" do
context "category" do
it "registers" do
category
expect(Category.get_custom_field_type("category_field_1")).to eq(:json)
expect(Category.get_custom_field_descriptor("category_field_1").type).to eq(:json)
end
it "adds custom fields to the basic category serializer" do
@ -103,7 +103,7 @@ describe "custom field extensions" do
context "group" do
it "registers" do
group
expect(Group.get_custom_field_type("group_field_1")).to eq(:string)
expect(Group.get_custom_field_descriptor("group_field_1").type).to eq(:string)
end
it "adds custom fields to the basic group serializer" do

Datei anzeigen

@ -0,0 +1,45 @@
# frozen_string_literal: true
describe Topic, type: :model do
fab!(:category_with_wizard) do
Fabricate(:category, custom_fields: { create_topic_wizard: 'true' })
end
fab!(:category_without_wizard) { Fabricate(:category) }
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
let(:valid_attrs) { Fabricate.attributes_for(:topic) }
context 'with a create_topic_wizard custom field in the category' do
it 'will not allow creating a topic directly' do
expect do
TopicCreator.create(
user,
Guardian.new(user),
valid_attrs.merge(
title: 'A valid and sufficiently long title for testing',
category: category_with_wizard.id,
raw: 'hello this is a test topic with category with custom fields'
)
)
end.to raise_error(
Discourse::InvalidParameters,
'Category not allowed for topic creation.'
)
end
end
context 'without a create_topic_wizard custom field in the category' do
it 'will allow creating a topic directly' do
expect do
TopicCreator.create(
user,
Guardian.new(user),
valid_attrs.merge(
category: category_without_wizard.id,
title: 'Another valid and sufficiently long title for testing',
raw: 'This is the body of a valid topic'
)
)
end.not_to raise_error
end
end
end

Datei anzeigen

@ -5,7 +5,7 @@ module DiscourseSubscriptionClient
end
end
class SubscriptionClientSupplier
SubscriptionClientSupplier = Class.new Object do
attr_reader :product_slugs
def initialize(product_slugs)
@ -13,10 +13,10 @@ class SubscriptionClientSupplier
end
end
class SubscriptionClientResource
SubscriptionClientResource = Class.new Object do
end
class SubscriptionClientSubscription
SubscriptionClientSubscription = Class.new Object do
attr_reader :product_id
def initialize(product_id)

Datei anzeigen

@ -23,12 +23,3 @@ def disable_subscriptions
CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(false)
end
end
def undefine_client_classes
Object.send(:remove_const, :DiscourseSubscriptionClient) if Object.constants.include?(:DiscourseSubscriptionClient)
Object.send(:remove_const, :SubscriptionClientSubscription) if Object.constants.include?(:SubscriptionClientSubscription)
end
def define_client_classes
load File.expand_path("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/subscription_client.rb", __FILE__)
end

Datei anzeigen

@ -9,6 +9,7 @@ describe CustomWizard::AdminApiController do
end
it "does not save if user does not have relevant subscription" do
disable_subscriptions
put "/admin/wizards/api/:name.json", params: api_json.to_h
expect(response.status).to eq(400)
end

Datei anzeigen

@ -1,6 +1,6 @@
# frozen_string_literal: true
describe CustomWizard::AdminController do
describe CustomWizard::SubscriptionController do
fab!(:admin_user) { Fabricate(:user, admin: true) }
it "requires an admin" do
@ -16,28 +16,24 @@ describe CustomWizard::AdminController do
context "without a subscription" do
before do
disable_subscriptions
define_client_classes
end
it "returns the right subscription details" do
get "/admin/wizards.json"
get "/admin/wizards/subscription.json"
expect(response.parsed_body["subscribed"]).to eq(false)
expect(response.parsed_body["subscription_attributes"]).to eq(CustomWizard::Subscription.attributes.as_json)
expect(response.parsed_body["subscription_client_installed"]).to eq(true)
end
end
context "with a subscription" do
before do
enable_subscription("standard")
define_client_classes
end
it "returns the right subscription details" do
get "/admin/wizards.json"
get "/admin/wizards/subscription.json"
expect(response.parsed_body["subscribed"]).to eq(true)
expect(response.parsed_body["subscription_type"]).to eq("standard")
expect(response.parsed_body["subscription_client_installed"]).to eq(true)
end
end
end

Datei anzeigen

@ -8,9 +8,8 @@ describe CustomWizard::AdminWizardController do
let(:category) { Fabricate(:category, custom_fields: { create_topic_wizard: template['name'].parameterize(separator: "_") }) }
before do
CustomWizard::Template.save(template, skip_jobs: true)
enable_subscription("standard")
CustomWizard::Template.save(template, skip_jobs: true)
template_2 = template.dup
template_2["id"] = 'super_mega_fun_wizard_2'
template_2["permitted"] = template_2['permitted']

Datei anzeigen

@ -24,7 +24,7 @@ describe CustomWizard::SubmissionSerializer do
it 'should return submission attributes' do
wizard = CustomWizard::Wizard.create(template_json["id"])
list = CustomWizard::Submission.list(wizard, page: 0)
list = CustomWizard::Submission.list(wizard, page: 0, order_by: 'id')
json_array = ActiveModel::ArraySerializer.new(
list.submissions,
@ -40,7 +40,7 @@ describe CustomWizard::SubmissionSerializer do
it "should return field values, types and labels" do
wizard = CustomWizard::Wizard.create(template_json["id"])
list = CustomWizard::Submission.list(wizard, page: 0)
list = CustomWizard::Submission.list(wizard, page: 0, order_by: 'id')
json_array = ActiveModel::ArraySerializer.new(
list.submissions,

Datei anzeigen

@ -1,24 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg
width="300px"
height="300px"
viewBox="0 0 300 300"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<g
<symbol
id="pavilion-logo"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
viewBox="0 0 300 300"
stroke-width="35"
stroke="currentColor"
fill="currentColor"
>
<path
id="Combined-Shape"
stroke="currentColor"
stroke-width="35"
d="M41.1381822,291.00006 L40.5778853,130.009744 M258.850727,291.638415 L259.290397,130.37133 M36.0002279,140.721678 L139.995368,36.2122772 M263.350577,141.009083 L138.927245,16.2478517"
></path>
</g>
</svg>
<span>{{label}}</span>
</symbol>
</svg>

Vorher

Breite:  |  Höhe:  |  Größe: 602 B

Nachher

Breite:  |  Höhe:  |  Größe: 512 B

Datei anzeigen

@ -1,19 +1,21 @@
import {
acceptance,
query,
queryAll,
visible,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, fillIn, findAll, visit, waitUntil } from "@ember/test-helpers";
import { click, fillIn, visit, waitUntil } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import {
getCustomFields,
getSuppliers,
getUnsubscribedAdminWizards,
getWizard,
} from "../helpers/admin-wizard";
import { Promise } from "rsvp";
acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
acceptance("Admin | Custom Fields Unsubscribed", function (needs) {
needs.user();
needs.settings({
custom_wizard_enabled: true,
@ -24,7 +26,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
server.get("/admin/wizards/wizard", () => {
return helper.response(getWizard);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getUnsubscribedAdminWizards);
});
server.get("/admin/wizards/custom-fields", () => {
@ -36,6 +38,9 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
server.delete("/admin/wizards/custom-fields/topic_custom_field", () => {
return helper.response({ success: "OK" });
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliers);
});
});
async function selectTypeAndSerializerAndFillInName(
@ -89,9 +94,9 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
test("Navigate to custom fields tab", async (assert) => {
await visit("/admin/wizards/custom-fields");
assert.ok(find("table"));
assert.ok(query("table"));
assert.ok(
findAll("table tbody tr").length === 4,
queryAll("table tbody tr").length === 4,
"Display loaded custom fields"
);
assert.ok(
@ -120,10 +125,10 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
'.admin-wizard-container details:has(summary[name="Filter by: Select a class"])'
);
await dropdown1.expand();
let enabledOptions1 = findAll(
let enabledOptions1 = queryAll(
'.admin-wizard-container details:has(summary[name="Filter by: Select a class"]) ul li:not(.disabled)'
);
let disabledOptions1 = findAll(
let disabledOptions1 = queryAll(
'.admin-wizard-container details:has(summary[name="Filter by: Select a class"]) ul li.disabled'
);
assert.equal(
@ -140,10 +145,10 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
'.admin-wizard-container details:has(summary[name="Filter by: Select a type"])'
);
await dropdown2.expand();
let enabledOptions2 = findAll(
let enabledOptions2 = queryAll(
'.admin-wizard-container details:has(summary[name="Filter by: Select a type"]) ul li:not(.disabled)'
);
let disabledOptions2 = findAll(
let disabledOptions2 = queryAll(
'.admin-wizard-container details:has(summary[name="Filter by: Select a type"]) ul li.disabled'
);
assert.equal(
@ -170,7 +175,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
".admin-wizard-container details.multi-select"
);
await serializerDropdown.expand();
let enabledOptions1 = findAll(
let enabledOptions1 = queryAll(
".admin-wizard-container details.multi-select ul li"
);
assert.equal(
@ -185,7 +190,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
await dropdown2.expand();
await click('.select-kit-collection li[data-value="post"]');
await serializerDropdown.expand();
let enabledOptions2 = findAll(
let enabledOptions2 = queryAll(
".admin-wizard-container details.multi-select ul li"
);
assert.equal(
@ -198,7 +203,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
test("Create Topic and Post custom fields", async (assert) => {
await visit("/admin/wizards/custom-fields");
assert.ok(
findAll("table tbody tr").length === 4,
queryAll("table tbody tr").length === 4,
"Display loaded custom fields"
);
await click(".admin-wizard-controls .btn-icon-text");
@ -263,7 +268,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
"Post custom field name is displayed"
);
assert.ok(
findAll("table tbody tr").length === 6,
queryAll("table tbody tr").length === 6,
"Display added custom fields"
);
});
@ -326,7 +331,7 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
test("Delete Topic custom field", async (assert) => {
await visit("/admin/wizards/custom-fields");
assert.ok(
findAll("table tbody tr").length === 4,
queryAll("table tbody tr").length === 4,
"Display loaded custom fields"
);
await click(".admin-wizard-controls .btn-icon-text");
@ -345,13 +350,13 @@ acceptance("Admin | Custom Fields Unsuscribed", function (needs) {
await click(".actions .save");
await waitForSaveMessage();
assert.ok(
findAll("table tbody tr").length === 5,
queryAll("table tbody tr").length === 5,
"Display added custom fields"
);
await click(".admin-wizard-container tbody tr:first-child button");
await click(".actions .destroy");
assert.ok(
findAll("table tbody tr").length === 4,
queryAll("table tbody tr").length === 4,
"Display custom fields without deleted fields"
);
});

Datei anzeigen

@ -1,8 +1,13 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import {
acceptance,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, findAll, visit } from "@ember/test-helpers";
import { click, visit } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import {
getSuppliers,
getUnsubscribedAdminWizards,
getWizard,
getWizardTestingLog,
@ -23,12 +28,15 @@ acceptance("Admin | Logs", function (needs) {
server.get("/admin/wizards/logs/this_is_testing_wizard", () => {
return helper.response(getWizardTestingLog);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getUnsubscribedAdminWizards);
});
server.get("/admin/wizards/wizard", () => {
return helper.response(getWizard);
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliers);
});
});
test("viewing logs fields tab", async (assert) => {
await visit("/admin/wizards/logs");
@ -51,19 +59,19 @@ acceptance("Admin | Logs", function (needs) {
),
"it displays logs for a selected wizard"
);
assert.ok(find("table"));
assert.ok(findAll("table tbody tr").length === 2, "Displays logs list");
assert.ok(queryAll("table"));
assert.ok(queryAll("table tbody tr").length === 2, "Displays logs list");
await click(".refresh.btn");
assert.ok(find("table"));
assert.ok(queryAll("table"));
assert.ok(
findAll("table tbody tr").length === 2,
queryAll("table tbody tr").length === 2,
"Refresh button works correctly"
);
await wizards.expand();
await click('[data-name="Select a wizard"]');
const wizardContainerDiv = find(".admin-wizard-container");
const wizardContainerDiv = queryAll(".admin-wizard-container");
assert.ok(wizardContainerDiv.children().length === 0, "the div is empty");
});
});

Datei anzeigen

@ -2,6 +2,7 @@ import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, find, findAll, visit, waitUntil } from "@ember/test-helpers";
import {
getSuppliers,
getUnsubscribedAdminWizards,
getWizard,
getWizardTestingLog,
@ -18,7 +19,7 @@ acceptance("Admin | Manager", function (needs) {
server.get("/admin/wizards/manager/this_is_testing_wizard", () => {
return helper.response(getWizardTestingLog);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getUnsubscribedAdminWizards);
});
server.get("/admin/wizards/wizard", () => {
@ -33,6 +34,9 @@ acceptance("Admin | Manager", function (needs) {
failures: [],
});
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliers);
});
});
async function waitForDestructionAndResetMessage() {
await waitUntil(

Datei anzeigen

@ -1,9 +1,14 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import {
acceptance,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, findAll, visit } from "@ember/test-helpers";
import { click, visit } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import {
getAnotherWizardSubmission,
getSuppliers,
getUnsubscribedAdminWizards,
getWizard,
getWizardSubmissions,
@ -28,12 +33,15 @@ acceptance("Admin | Submissions", function (needs) {
server.get("/admin/wizards/submissions/another_wizard", () => {
return helper.response(getAnotherWizardSubmission);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getUnsubscribedAdminWizards);
});
server.get("/admin/wizards/wizard", () => {
return helper.response(getWizard);
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliers);
});
});
test("View submissions fields tab and content", async (assert) => {
await visit("/admin/wizards/submissions");
@ -57,7 +65,7 @@ acceptance("Admin | Submissions", function (needs) {
"it displays submissions for a selected wizard"
);
const submissions = getWizardSubmissions.submissions; // Get submissions data from your JSON file
const rows = findAll("table tbody tr");
const rows = queryAll("table tbody tr");
for (let i = 0; i < submissions.length; i++) {
const dateCell = rows[i].querySelector("td:nth-child(1)");
@ -84,14 +92,14 @@ acceptance("Admin | Submissions", function (needs) {
);
}
assert.ok(
findAll("table tbody tr").length >= 1,
queryAll("table tbody tr").length >= 1,
"Displays submissions list"
);
await wizards.expand();
await click('[data-name="Select a wizard"]');
const wizardContainerDiv = find(".admin-wizard-container");
assert.ok(wizardContainerDiv.children().length === 0, "the div is empty");
const wizardContainerDiv = query(".admin-wizard-container");
assert.ok(wizardContainerDiv.children.length === 0, "the div is empty");
});
test("View submissions tab for another wizard with more steps", async (assert) => {
await visit("/admin/wizards/submissions");
@ -108,7 +116,7 @@ acceptance("Admin | Submissions", function (needs) {
);
const submissions = getAnotherWizardSubmission.submissions; // Get submissions data from your JSON file
const rows = findAll("table tbody tr");
const rows = queryAll("table tbody tr");
for (let i = 0; i < submissions.length; i++) {
const dateCell = rows[i].querySelector("td:nth-child(1)");
@ -143,7 +151,7 @@ acceptance("Admin | Submissions", function (needs) {
}
assert.ok(
findAll("table tbody tr").length >= 1,
queryAll("table tbody tr").length >= 1,
"Displays submissions list for another wizard"
);
});
@ -154,9 +162,9 @@ acceptance("Admin | Submissions", function (needs) {
await wizards.selectRowByValue("this_is_testing_wizard");
await click(".open-edit-columns-btn");
assert.dom(".modal-inner-container").exists("Modal is displayed");
assert.dom(".d-modal__body").exists("Modal is displayed");
const userCheckbox = find(
const userCheckbox = queryAll(
".edit-directory-columns-container .edit-directory-column:nth-child(2) .left-content .column-name input"
);
assert.ok(userCheckbox, "User checkbox is present");
@ -173,7 +181,7 @@ acceptance("Admin | Submissions", function (needs) {
.doesNotIncludeText("User", "User column is not displayed");
await click(".open-edit-columns-btn");
const submittedAtCheckbox = find(
const submittedAtCheckbox = queryAll(
".edit-directory-columns-container .edit-directory-column:nth-child(1) .left-content .column-name input"
);
assert.ok(submittedAtCheckbox, "Submitted At checkbox is present");
@ -211,7 +219,7 @@ acceptance("Admin | Submissions", function (needs) {
await wizards.expand();
await wizards.selectRowByValue("this_is_testing_wizard");
const downloadLinks = findAll(".download-link");
const downloadLinks = queryAll(".download-link");
assert.ok(downloadLinks.length > 1, "Download links are present");
const downloadLink = downloadLinks[1];

Datei anzeigen

@ -1,4 +1,8 @@
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import {
acceptance,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, currentURL, fillIn, visit } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -6,6 +10,7 @@ import {
getBusinessAdminWizard,
getCustomFields,
getNewApi,
getSuppliers,
getWizard,
putNewApi,
} from "../helpers/admin-wizard";
@ -21,7 +26,7 @@ acceptance("Admin | API tab", function (needs) {
server.get("/admin/wizards/wizard", () => {
return helper.response(getWizard);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getBusinessAdminWizard);
});
server.get("/admin/wizards/custom-fields", () => {
@ -45,11 +50,14 @@ acceptance("Admin | API tab", function (needs) {
server.get("/admin/wizards/api/new_api", () => {
return helper.response(getNewApi);
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliers);
});
});
test("Visit API tab and fill data", async function (assert) {
await visit("/admin/wizards/api");
const list = find(".admin-controls li");
const list = queryAll(".admin-controls li");
const count = list.length;
assert.equal(count, 6, "There should be 6 admin tabs");

Datei anzeigen

@ -1,6 +1,8 @@
import {
acceptance,
exists,
query,
queryAll,
visible,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
@ -11,6 +13,7 @@ import {
getBusinessAdminWizard,
getCreatedWizard,
getCustomFields,
getSuppliersAuthorized,
getWizard,
} from "../helpers/admin-wizard";
@ -28,7 +31,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
server.get("/admin/wizards/custom-fields", () => {
return helper.response(getCustomFields);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getBusinessAdminWizard);
});
server.get("/admin/wizards/api", () => {
@ -49,15 +52,30 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
server.get("/admin/wizards/wizard/new_wizard_for_testing", () => {
return helper.response(getCreatedWizard);
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliersAuthorized);
});
});
test("Displaying all tabs including API", async (assert) => {
await visit("/admin/wizards");
const list = find(".admin-controls li");
const list = queryAll(".admin-controls li");
const count = list.length;
assert.equal(count, 6, "There should be 6 admin tabs");
});
test("shows authorized and subscribed", async (assert) => {
await visit("/admin/wizards");
assert.notOk(
exists(".supplier-authorize .btn-primary:not(.update)"),
"the authorize button is shown."
);
assert.strictEqual(
query("button.wizard-subscription-badge span").innerText.trim(),
"Support"
);
});
test("creating a new wizard", async (assert) => {
await visit("/admin/wizards/wizard");
await click(".admin-wizard-controls button");
@ -75,10 +93,11 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
wizardTitle,
"The title input is inserted"
);
const wizardLink = find("div.wizard-url a");
const wizardLink = queryAll("div.wizard-url a");
assert.equal(wizardLink.length, 1, "Wizard link was created");
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
1,
"Wizard subscription features are accesible"
);
@ -86,7 +105,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
'.wizard-subscription-container .subscription-settings .setting-value input[type="checkbox"]'
);
assert.ok(
find(
queryAll(
'.wizard-subscription-container .subscription-settings .setting-value input[type="checkbox"]'
).is(":checked"),
"subscription feature available"
@ -95,7 +114,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
// Step 2: Creating a step section
await click(".step .link-list button");
const stepOneText = "step_1 (step_1)";
const stepOneBtn = find(`.step button:contains(${stepOneText})`);
const stepOneBtn = queryAll(`.step button:contains(${stepOneText})`);
assert.equal(stepOneBtn.length, 1, "Creating a step");
const stepTitle = "step title";
await fillIn(".wizard-custom-step input[name='title']", stepTitle);
@ -107,7 +126,8 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
"The step button changes according to title"
);
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
2,
"Steps subscription features are accesible"
);
@ -119,7 +139,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
"clear button is not rendered"
);
const fieldOneText = "step_1_field_1 (step_1_field_1)";
const fieldOneBtn = find(`.field button:contains(${fieldOneText})`);
const fieldOneBtn = queryAll(`.field button:contains(${fieldOneText})`);
assert.equal(fieldOneBtn.length, 1, "Creating a field");
const fieldTitle = "field title";
await fillIn(".wizard-custom-field input[name='label']", fieldTitle);
@ -154,7 +174,8 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
"Text tipe for field correctly selected"
);
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
3,
"Field subscription features are accesible"
);
@ -163,7 +184,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) {
await click(".action .link-list button");
const actionOneText = "action_1 (action_1)";
const actionOneBtn = find(`.action button:contains(${actionOneText})`);
const actionOneBtn = queryAll(`.action button:contains(${actionOneText})`);
assert.equal(actionOneBtn.length, 1, "Creating an action");
assert.ok(
query(

Datei anzeigen

@ -1,16 +1,19 @@
import {
acceptance,
exists,
query,
queryAll,
visible,
} from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
import { click, currentURL, fillIn, findAll, visit } from "@ember/test-helpers";
import { click, currentURL, fillIn, visit } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import {
getAdminTestingWizard,
getCreatedWizard,
getCustomFields,
getStandardAdminWizard,
getSuppliersAuthorized,
getWizard,
} from "../helpers/admin-wizard";
@ -28,7 +31,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
server.get("/admin/wizards/custom-fields", () => {
return helper.response(getCustomFields);
});
server.get("/admin/wizards", () => {
server.get("/admin/wizards/subscription", () => {
return helper.response(getStandardAdminWizard);
});
server.get("/admin/wizards/api", () => {
@ -49,15 +52,30 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
server.get("/admin/wizards/wizard/new_wizard_for_testing", () => {
return helper.response(getCreatedWizard);
});
server.get("/admin/plugins/subscription-client/suppliers", () => {
return helper.response(getSuppliersAuthorized);
});
});
test("Displaying all tabs except API", async (assert) => {
await visit("/admin/wizards");
const list = find(".admin-controls li");
const list = queryAll(".admin-controls li");
const count = list.length;
assert.equal(count, 5, "There should be 5 admin tabs");
});
test("shows authorized and subscribed", async (assert) => {
await visit("/admin/wizards");
assert.notOk(
exists(".supplier-authorize .btn-primary:not(.update)"),
"the authorize button not shown."
);
assert.strictEqual(
query("button.wizard-subscription-badge span").innerText.trim(),
"Support"
);
});
test("creating a new wizard", async (assert) => {
await visit("/admin/wizards/wizard");
await click(".admin-wizard-controls button");
@ -75,14 +93,15 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
wizardTitle,
"The title input is inserted"
);
const wizardLink = find("div.wizard-url a");
const wizardLink = queryAll("div.wizard-url a");
assert.equal(wizardLink.length, 1, "Wizard link was created");
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
1,
"Wizard subscription features are accesible"
);
const subsFeature = find(
const subsFeature = queryAll(
".wizard-subscription-container .subscription-settings .setting-value input"
);
await click(
@ -92,7 +111,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
// ("Step 2: Creating a step section")
await click(".step .link-list button");
const stepOneText = "step_1 (step_1)";
const stepOneBtn = find(`.step button:contains(${stepOneText})`);
const stepOneBtn = queryAll(`.step button:contains(${stepOneText})`);
assert.equal(stepOneBtn.length, 1, "Creating a step");
const stepTitle = "step title";
await fillIn(".wizard-custom-step input[name='title']", stepTitle);
@ -104,7 +123,8 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
"The step button changes according to title"
);
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
2,
"Steps subscription features are accesible"
);
@ -115,7 +135,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
"clear button is not rendered"
);
const fieldOneText = "step_1_field_1 (step_1_field_1)";
const fieldOneBtn = find(`.field button:contains(${fieldOneText})`);
const fieldOneBtn = queryAll(`.field button:contains(${fieldOneText})`);
assert.equal(fieldOneBtn.length, 1, "Creating a field");
const fieldTitle = "field title";
await fillIn(".wizard-custom-field input[name='label']", fieldTitle);
@ -150,14 +170,15 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
"Text tipe for field correctly selected"
);
assert.equal(
find(".wizard-subscription-container a:contains('Subscribed')").length,
queryAll(".wizard-subscription-container a:contains('Subscribed')")
.length,
3,
"Field subscription features are accesible"
);
// ("Step 4: Creating a action section")
await click(".action .link-list button");
const actionOneText = "action_1 (action_1)";
const actionOneBtn = find(`.action button:contains(${actionOneText})`);
const actionOneBtn = queryAll(`.action button:contains(${actionOneText})`);
assert.equal(actionOneBtn.length, 1, "Creating an action");
assert.ok(
query(
@ -169,10 +190,10 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
".wizard-custom-action .setting-value .select-kit"
);
await actionTypeDropdown.expand();
const listEnabled = findAll(
const listEnabled = queryAll(
".wizard-custom-action .setting .setting-value ul li:not(.disabled)"
);
const listDisabled = findAll(
const listDisabled = queryAll(
".wizard-custom-action .setting .setting-value ul li.disabled"
);
assert.ok(
@ -190,7 +211,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
),
"Create type action correctly selected"
);
let listTopicSettings = findAll(
let listTopicSettings = queryAll(
".admin-wizard-container .wizard-custom-action .setting"
);
assert.ok(
@ -199,7 +220,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
);
await actionTypeDropdown.expand();
await actionTypeDropdown.selectRowByValue("send_message");
listTopicSettings = findAll(
listTopicSettings = queryAll(
".admin-wizard-container .wizard-custom-action .setting"
);
assert.ok(
@ -208,7 +229,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
);
await actionTypeDropdown.expand();
await actionTypeDropdown.selectRowByValue("watch_categories");
listTopicSettings = findAll(
listTopicSettings = queryAll(
".admin-wizard-container .wizard-custom-action .setting"
);
assert.ok(
@ -217,7 +238,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) {
);
await actionTypeDropdown.expand();
await actionTypeDropdown.selectRowByValue("add_to_group");
listTopicSettings = findAll(
listTopicSettings = queryAll(
".admin-wizard-container .wizard-custom-action .setting"
);
assert.ok(

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen