lesli 5.0.13 → 5.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/lesli_manifest.js +3 -6
- data/app/assets/images/lesli/brand/app-icon.svg +45 -39
- data/app/assets/javascripts/lesli/application.js +1 -0
- data/app/controllers/lesli/abouts_controller.rb +16 -14
- data/app/controllers/lesli/application_controller.rb +13 -0
- data/app/controllers/lesli/application_devise_controller.rb +10 -12
- data/app/controllers/lesli/application_lesli_controller.rb +12 -11
- data/app/controllers/lesli/apps_controller.rb +6 -0
- data/app/controllers/lesli/roles_controller.rb +2 -2
- data/app/helpers/lesli/general_helper.rb +18 -5
- data/app/helpers/lesli/html_helper.rb +8 -0
- data/app/helpers/lesli/navigation_helper.rb +30 -11
- data/app/helpers/lesli/system_helper.rb +2 -2
- data/app/helpers/lesli/turbo_helper.rb +58 -0
- data/app/interfaces/lesli/customization_interface.rb +42 -0
- data/app/interfaces/lesli/requester_interface.rb +103 -0
- data/app/interfaces/lesli/responder_interface.rb +127 -0
- data/app/lib/date2.rb +1 -199
- data/app/lib/lesli/courier.rb +54 -0
- data/app/mailers/lesli/application_lesli_mailer.rb +32 -59
- data/app/mailers/lesli/devise_mailer.rb +16 -8
- data/app/models/concerns/account_initializer.rb +27 -68
- data/app/models/concerns/lesli/has_activities.rb +29 -0
- data/app/models/concerns/user_extensions.rb +34 -19
- data/app/models/concerns/user_security.rb +4 -4
- data/app/models/lesli/account.rb +13 -20
- data/{lib/scss/layouts/application-container.scss → app/models/lesli/item/activity.rb} +11 -8
- data/app/models/lesli/role/{power.rb → action.rb} +6 -4
- data/app/models/lesli/role.rb +7 -15
- data/app/models/lesli/shared/catalog.rb +20 -0
- data/app/models/lesli/shared/dashboard.rb +1 -1
- data/app/models/lesli/user/activity.rb +5 -0
- data/app/models/lesli/user/detail.rb +5 -5
- data/app/models/lesli/user/{log.rb → journal.rb} +3 -3
- data/app/models/lesli/user/{power.rb → role.rb} +2 -3
- data/app/models/lesli/user/session.rb +3 -4
- data/app/models/lesli/user.rb +50 -46
- data/app/operators/lesli/controller_operator.rb +3 -1
- data/app/operators/lesli/{role_descriptor_operator.rb → role_operator.rb} +51 -28
- data/app/operators/lesli/user_registration_operator.rb +3 -2
- data/app/services/lesli/application_lesli_service.rb +8 -4
- data/app/services/lesli/role/action_service.rb +58 -0
- data/app/services/lesli/role_service.rb +232 -0
- data/app/services/lesli/{user_session_service.rb → user/session_service.rb} +23 -14
- data/app/services/lesli/user_service.rb +85 -1
- data/app/views/lesli/apps/show.html.erb +52 -0
- data/app/views/lesli/layouts/application-devise.html.erb +5 -7
- data/app/views/lesli/layouts/application-lesli.html.erb +18 -24
- data/app/views/lesli/partials/_application-analytics.html.erb +2 -2
- data/app/views/lesli/partials/_application-data.html.erb +3 -77
- data/app/views/lesli/partials/_application-head.html.erb +7 -4
- data/app/views/lesli/partials/_application-lesli-annoouncements.html.erb +49 -0
- data/app/views/lesli/partials/_application-lesli-header.html.erb +73 -49
- data/app/views/lesli/partials/_application-lesli-javascript.html.erb +3 -16
- data/app/views/lesli/partials/_application-lesli-navigation.html.erb +12 -9
- data/app/views/lesli/partials/{_application-lesli-notices.html.erb → _application-lesli-notifications.html.erb} +10 -8
- data/app/views/lesli/partials/_application-lesli-scss.html.erb +1 -1
- data/app/views/lesli/partials/_application-lesli-sidebar.html.erb +1 -1
- data/app/views/lesli/partials/_application-public-javascript.html.erb +1 -4
- data/app/views/lesli/shared/dashboards/_show.html.erb +63 -0
- data/app/views/lesli/wrappers/_application-devise.html.erb +4 -6
- data/config/importmap.rb +14 -0
- data/config/initializers/lesli.rb +20 -12
- data/config/initializers/lesli_migration_helpers.rb +61 -0
- data/config/locales/translations.en.yml +1 -26
- data/config/locales/translations.es.yml +1 -26
- data/config/locales/translations.fr.yml +1 -26
- data/config/locales/translations.it.yml +1 -26
- data/config/locales/translations.pt.yml +1 -26
- data/config/routes.rb +3 -1
- data/db/migrate/v1/{0010000110_create_lesli_accounts.rb → 0000000110_create_lesli_accounts.rb} +13 -12
- data/db/migrate/v1/0000000210_create_lesli_roles.rb +65 -0
- data/db/migrate/v1/0000000310_create_lesli_users.rb +99 -0
- data/db/migrate/v1/{0010000610_create_lesli_system_controllers.rb → 0000100110_create_lesli_system_controllers.rb} +3 -3
- data/db/migrate/v1/{0010000710_create_lesli_system_controller_actions.rb → 0000100210_create_lesli_system_controller_actions.rb} +3 -4
- data/{lib/scss/layouts/application-content.scss → db/migrate/v1/0000110310_create_lesli_account_settings.rb} +8 -6
- data/{app/models/lesli/user/agent.rb → db/migrate/v1/0000110410_create_lesli_account_activities.rb} +3 -3
- data/db/migrate/v1/0000120210_create_lesli_role_actions.rb +45 -0
- data/db/migrate/v1/{0010001410_create_lesli_account_logs.rb → 0000120310_create_lesli_role_privileges.rb} +8 -8
- data/db/{tables/0010003810_create_user_shortcuts.rb → migrate/v1/0000130210_create_lesli_user_roles.rb} +9 -12
- data/db/migrate/v1/0000130310_create_lesli_user_sessions.rb +56 -0
- data/db/{seed/production.rb → migrate/v1/0000130410_create_lesli_user_activities.rb} +7 -4
- data/db/{tables/0010001110_create_account_locations.rb → migrate2/0000100510_create_lesli_account_locations.rb} +6 -6
- data/db/{tables/0010001510_create_account_currencies.rb → migrate2/0000100610_create_lesli_account_currencies.rb} +4 -4
- data/db/seed/{development/accounts.rb → accounts.rb} +6 -2
- data/db/seed/{production/users.rb → users.rb} +4 -10
- data/db/seed/{tools.rb → xyz.rb} +2 -7
- data/db/seeds.rb +3 -2
- data/db/structure/00000020_catalogs.json +0 -0
- data/lib/generators/{application_lesli_generator.rb → application_lesli_generator_base.rb} +4 -4
- data/lib/generators/lesli/spec/spec_generator.rb +2 -2
- data/lib/generators/lesli/view/USAGE +8 -0
- data/lib/generators/lesli/view/templates/spec-factory.template +17 -0
- data/lib/generators/lesli/view/templates/spec-model.template +70 -0
- data/lib/generators/lesli/view/view_generator.rb +25 -0
- data/lib/lesli/configuration.rb +7 -10
- data/lib/lesli/engine.rb +22 -3
- data/lib/lesli/r_spec.rb +5 -2
- data/lib/lesli/routing.rb +42 -9
- data/lib/lesli/version.rb +2 -2
- data/lib/lesli.rb +11 -0
- data/lib/migrate/common.rb +94 -0
- data/lib/migrate/items/action_structure.rb +51 -0
- data/{db/migrate/v1/0010001210_create_lesli_account_activities.rb → lib/migrate/items/activity_structure.rb} +18 -16
- data/lib/migrate/items/attachment_structure.rb +62 -0
- data/{app/views/lesli/partials/_application-lesli-engines.html.erb → lib/migrate/items/discussion_structure.rb} +19 -27
- data/lib/migrate/items/subscriber_structure.rb +49 -0
- data/lib/migrate/items/version_structure.rb +53 -0
- data/lib/migrate/shared/account_structure.rb +21 -0
- data/lib/migrate/shared/catalog_structure.rb +30 -0
- data/lib/migrate/shared/dashboard_structure.rb +54 -0
- data/lib/migrate/shared/setting_structure.rb +20 -0
- data/lib/rspec/config/spec_coverage.rb +95 -0
- data/{db/migrate/v1/0010001110_create_lesli_account_settings.rb → lib/rspec/factories/lesli_account.rb} +10 -7
- data/{db/seed/development.rb → lib/rspec/factories/lesli_role.rb} +30 -3
- data/{db/seed/test.rb → lib/rspec/factories/lesli_user.rb} +32 -3
- data/lib/rspec/fixtures/files/lesli-icon.png +0 -0
- data/lib/rspec/fixtures/files/test_file_1.docx +0 -0
- data/{db/tables/0010001610_create_account_currency_exchange_rates.rb → lib/rspec/helpers/lesli_helper.rb} +21 -21
- data/lib/rspec/helpers/rails_helper.rb +134 -0
- data/lib/rspec/helpers/response_request_helper.rb +214 -0
- data/lib/rspec/helpers/response_service_helper.rb +66 -0
- data/lib/rspec/helpers/spec_helper.rb +99 -0
- data/lib/rspec/lesli_api_tester.rb +133 -0
- data/lib/rspec/lesli_service_tester.rb +46 -0
- data/{db/tables/0010001410_create_account_files.rb → lib/rspec/testers/controller.rb} +31 -20
- data/lib/rspec/testers/model.rb +36 -0
- data/lib/rspec/testers/request.rb +84 -0
- data/lib/tasks/lesli/db.rake +5 -3
- data/lib/tasks/lesli/git.rake +28 -32
- data/lib/tasks/lesli/github.rake +89 -0
- data/lib/tasks/lesli_tasks.rake +3 -3
- data/readme.md +28 -17
- metadata +134 -394
- data/app/assets/fonts/lesli/Domine/Domine-Variable.ttf +0 -0
- data/app/assets/fonts/lesli/Domine/OFL.txt +0 -97
- data/app/assets/fonts/lesli/MaterialDesign/icons.woff2 +0 -0
- data/app/assets/fonts/lesli/Montserrat/Montserrat-Variable.ttf +0 -0
- data/app/assets/fonts/lesli/OpenSans/OpenSans-Variable.ttf +0 -0
- data/app/assets/fonts/lesli/Remix/remixicon.eot +0 -0
- data/app/assets/fonts/lesli/Remix/remixicon.glyph.json +0 -1
- data/app/assets/fonts/lesli/Remix/remixicon.svg +0 -7633
- data/app/assets/fonts/lesli/Remix/remixicon.symbol.svg +0 -11
- data/app/assets/fonts/lesli/Remix/remixicon.ttf +0 -0
- data/app/assets/fonts/lesli/Remix/remixicon.woff +0 -0
- data/app/assets/fonts/lesli/Remix/remixicon.woff2 +0 -0
- data/app/assets/fonts/lesli/Roboto/LICENSE.txt +0 -202
- data/app/assets/fonts/lesli/Roboto/Roboto-Black.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-BlackItalic.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Bold.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-BoldItalic.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Italic.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Light.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-LightItalic.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Medium.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-MediumItalic.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Regular.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-Thin.ttf +0 -0
- data/app/assets/fonts/lesli/Roboto/Roboto-ThinItalic.ttf +0 -0
- data/app/assets/icons/lesli/engine-admin.svg +0 -1
- data/app/assets/icons/lesli/engine-audit.svg +0 -1
- data/app/assets/icons/lesli/engine-babel.svg +0 -1
- data/app/assets/icons/lesli/engine-bell.svg +0 -1
- data/app/assets/icons/lesli/engine-books.svg +0 -1
- data/app/assets/icons/lesli/engine-calendar.svg +0 -1
- data/app/assets/icons/lesli/engine-dashboard.svg +0 -1
- data/app/assets/icons/lesli/engine-dispatcher.svg +0 -1
- data/app/assets/icons/lesli/engine-focus.svg +0 -1
- data/app/assets/icons/lesli/engine-kb.svg +0 -1
- data/app/assets/icons/lesli/engine-leaf.svg +0 -1
- data/app/assets/icons/lesli/engine-lesli.svg +0 -1
- data/app/assets/icons/lesli/engine-letter.svg +0 -1
- data/app/assets/icons/lesli/engine-mailer.svg +0 -1
- data/app/assets/icons/lesli/engine-one.svg +0 -1
- data/app/assets/icons/lesli/engine-profile.svg +0 -1
- data/app/assets/icons/lesli/engine-proposal.svg +0 -1
- data/app/assets/icons/lesli/engine-scraper.svg +0 -1
- data/app/assets/icons/lesli/engine-security.svg +0 -1
- data/app/assets/icons/lesli/engine-shared.svg +0 -1
- data/app/assets/icons/lesli/engine-shield.svg +0 -1
- data/app/assets/icons/lesli/engine-storage.svg +0 -1
- data/app/assets/icons/lesli/engine-support.svg +0 -1
- data/app/assets/icons/lesli/engine-talk.svg +0 -1
- data/app/assets/icons/lesli/engine-team.svg +0 -1
- data/app/assets/icons/lesli/engine-time.svg +0 -1
- data/app/assets/icons/lesli/locale-en.svg +0 -1
- data/app/assets/icons/lesli/locale-es.svg +0 -1
- data/app/assets/icons/lesli/locale-fr.svg +0 -1
- data/app/assets/icons/lesli/locale-it.svg +0 -1
- data/app/assets/icons/lesli/locale-pt.svg +0 -1
- data/app/assets/icons/readme.md +0 -10
- data/app/assets/javascripts/lesli/templates/application.js +0 -14
- data/app/assets/javascripts/lesli/templates/public.js +0 -14
- data/app/assets/stylesheets/lesli/templates/application.css +0 -2918
- data/app/assets/stylesheets/lesli/templates/public.css +0 -1
- data/app/controllers/lesli/interfaces/application/authorization.rb +0 -107
- data/app/controllers/lesli/interfaces/application/customization.rb +0 -46
- data/app/controllers/lesli/interfaces/application/logger.rb +0 -134
- data/app/controllers/lesli/interfaces/application/requester.rb +0 -84
- data/app/controllers/lesli/interfaces/application/responder.rb +0 -132
- data/app/controllers/lesli/interfaces/controllers/actions.rb +0 -250
- data/app/controllers/lesli/interfaces/controllers/activities.rb +0 -215
- data/app/controllers/lesli/interfaces/controllers/discussions.rb +0 -270
- data/app/controllers/lesli/interfaces/controllers/files.rb +0 -467
- data/app/controllers/lesli/interfaces/controllers/subscribers.rb +0 -234
- data/app/lib/lesli/system.rb +0 -110
- data/app/models/lesli/cloud_object/action.rb +0 -70
- data/app/models/lesli/cloud_object/activity.rb +0 -311
- data/app/models/lesli/cloud_object/custom_field.rb +0 -158
- data/app/models/lesli/cloud_object/discussion.rb +0 -219
- data/app/models/lesli/cloud_object/subscriber.rb +0 -186
- data/app/operators/lesli/descriptor_privilege_operator.rb +0 -75
- data/app/views/lesli/emails/devise_mailer/confirmation_instructions.html.erb +0 -23
- data/app/views/lesli/emails/devise_mailer/reset_password_instructions.html.erb +0 -23
- data/app/views/lesli/partials/_application-lesli-icons.html.erb +0 -1
- data/config/initializers/devise.rb +0 -336
- data/db/seed/development/users.rb +0 -52
- data/db/seed/production/accounts.rb +0 -50
- data/db/structure/00000000_people.json +0 -34
- data/db/structure/00000003_actions.json +0 -14
- data/db/structure/00000004_activities.json +0 -20
- data/db/structure/00000005_discussions.json +0 -8
- data/db/structure/00000006_files.json +0 -32
- data/db/structure/00000007_subscribers.json +0 -11
- data/db/structure/00000501_dashboards.json +0 -14
- data/db/structure/00000502_dashboard_components.json +0 -23
- data/db/tables/0010003410_create_user_activities.rb +0 -51
- data/db/tables/0010003710_create_user_codes.rb +0 -43
- data/db/tables/0010004110_create_user_tokens.rb +0 -45
- data/db/tables/0010005610_create_role_activities.rb +0 -50
- data/db/tables/0010009010_create_feedbacks.rb +0 -56
- data/lib/mailer_previews/devise_mailer_preview.rb +0 -49
- data/lib/scss/cloud-objects/discussion.scss +0 -80
- data/lib/scss/cloud-objects/file.scss +0 -138
- data/lib/scss/components/keypad.scss +0 -109
- data/lib/scss/elements/autocomplete.scss +0 -72
- data/lib/scss/elements/card.scss +0 -37
- data/lib/scss/elements/empty.scss +0 -43
- data/lib/scss/elements/file-uploader.scss +0 -74
- data/lib/scss/elements/gallery.scss +0 -98
- data/lib/scss/elements/input-tag.scss +0 -73
- data/lib/scss/elements/loading.scss +0 -63
- data/lib/scss/elements/map.scss +0 -107
- data/lib/scss/elements/navbar.scss +0 -115
- data/lib/scss/elements/table.scss +0 -118
- data/lib/scss/elements/toolbar.scss +0 -66
- data/lib/scss/fonts/families.scss +0 -47
- data/lib/scss/fonts/mdicons.scss +0 -82
- data/lib/scss/fonts/remixicons.scss +0 -2602
- data/lib/scss/helpers/display.scss +0 -44
- data/lib/scss/helpers/tooltip.scss +0 -91
- data/lib/scss/layouts/application-announcements.scss +0 -40
- data/lib/scss/layouts/application-component.scss +0 -39
- data/lib/scss/layouts/application-engines.scss +0 -125
- data/lib/scss/layouts/application-footer.scss +0 -102
- data/lib/scss/layouts/application-header.scss +0 -91
- data/lib/scss/layouts/application-navigation.scss +0 -79
- data/lib/scss/layouts/application-search.scss +0 -71
- data/lib/scss/layouts/application-sidebar.scss +0 -219
- data/lib/scss/overrides/notification.scss +0 -75
- data/lib/scss/overrides/sweetalert.scss +0 -106
- data/lib/scss/pages/devise-simple.scss +0 -89
- data/lib/scss/pages/devise.scss +0 -179
- data/lib/scss/pages/invites.scss +0 -81
- data/lib/scss/panels/panel-announcements.scss +0 -56
- data/lib/scss/panels/panel-notification.scss +0 -67
- data/lib/scss/panels/panel-profile.scss +0 -62
- data/lib/scss/panels/panel-support-ticket.scss +0 -56
- data/lib/scss/panels/panel-tasks.scss +0 -41
- data/lib/scss/settings/variables.scss +0 -148
- data/lib/scss/shared/workflow-status-progress.scss +0 -135
- data/lib/scss/templates/application.scss +0 -127
- data/lib/scss/templates/component.scss +0 -39
- data/lib/scss/templates/dashboards.scss +0 -53
- data/lib/scss/templates/empty.scss +0 -42
- data/lib/scss/templates/pdf.scss +0 -45
- data/lib/scss/templates/public.scss +0 -72
- data/lib/vue/application.js +0 -285
- data/lib/vue/cloudobjects/discussion/content.vue +0 -62
- data/lib/vue/cloudobjects/discussion/element.vue +0 -170
- data/lib/vue/cloudobjects/discussion/filters.vue +0 -108
- data/lib/vue/cloudobjects/discussion/new.vue +0 -134
- data/lib/vue/cloudobjects/discussion.vue +0 -99
- data/lib/vue/cloudobjects/stores/discussion.js +0 -212
- data/lib/vue/layouts/application-announcements.vue +0 -78
- data/lib/vue/layouts/application-component.vue +0 -38
- data/lib/vue/layouts/application-container.vue +0 -48
- data/lib/vue/layouts/application-engines.vue +0 -66
- data/lib/vue/layouts/application-footer.vue +0 -123
- data/lib/vue/layouts/application-header.vue +0 -252
- data/lib/vue/layouts/application-navbar.vue +0 -110
- data/lib/vue/layouts/application-search.vue +0 -86
- data/lib/vue/layouts/application-sidebar.vue +0 -63
- data/lib/vue/pages/errors/app.js +0 -32
- data/lib/vue/pages/invites/app.js +0 -76
- data/lib/vue/pages/mfas/application.js +0 -77
- data/lib/vue/pages/onboarding/application.js +0 -45
- data/lib/vue/pages/onboarding/components/address.vue +0 -120
- data/lib/vue/pages/onboarding/components/buttons.vue +0 -67
- data/lib/vue/pages/onboarding/components/contact.vue +0 -148
- data/lib/vue/pages/onboarding/components/date-time.vue +0 -265
- data/lib/vue/pages/onboarding/components/finish.vue +0 -62
- data/lib/vue/pages/onboarding/components/general-info.vue +0 -93
- data/lib/vue/pages/onboarding/components/indicators.vue +0 -78
- data/lib/vue/pages/onboarding/components/welcome.vue +0 -66
- data/lib/vue/pages/onboarding/show.vue +0 -67
- data/lib/vue/pages/onboarding/store.js +0 -165
- data/lib/vue/pages/otps/application.js +0 -90
- data/lib/vue/pages/passes/application.js +0 -80
- data/lib/vue/pages/websites/application.js +0 -34
- data/lib/vue/panels/panel-announcements.vue +0 -248
- data/lib/vue/panels/panel-bell-notifications.vue +0 -102
- data/lib/vue/panels/panel-files.vue +0 -281
- data/lib/vue/panels/panel-profile.vue +0 -76
- data/lib/vue/panels/panel-support-tickets.vue +0 -163
- data/lib/vue/panels/panel-tasks.vue +0 -124
- data/lib/vue/panels/stores/bell-notifications.js +0 -46
- data/lib/vue/panels/stores/support-tickets.js +0 -103
- data/lib/vue/public.js +0 -83
- data/lib/vue/refactor/shared/cloudobjects/action.vue +0 -193
- data/lib/vue/refactor/shared/cloudobjects/file/grid.vue +0 -215
- data/lib/vue/refactor/shared/cloudobjects/file/list.vue +0 -106
- data/lib/vue/refactor/shared/cloudobjects/file.vue +0 -145
- data/lib/vue/refactor/shared/workflows2/apps/actions/form.vue +0 -232
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/chatroom-form.vue +0 -103
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/cloud-object-clone-form.vue +0 -125
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/cloud-object-file-form.vue +0 -102
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/email-form.vue +0 -190
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/notification-form.vue +0 -124
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/send-cloud-object-file.vue +0 -170
- data/lib/vue/refactor/shared/workflows2/apps/actions/forms/task-form.vue +0 -258
- data/lib/vue/refactor/shared/workflows2/apps/actions/index.vue +0 -146
- data/lib/vue/refactor/shared/workflows2/apps/checks/form.vue +0 -200
- data/lib/vue/refactor/shared/workflows2/apps/checks/index.vue +0 -160
- data/lib/vue/refactor/shared/workflows2/apps/index.vue +0 -177
- data/lib/vue/refactor/shared/workflows2/apps/new.vue +0 -97
- data/lib/vue/refactor/shared/workflows2/apps/show.vue +0 -146
- data/lib/vue/refactor/shared/workflows2/components/associations.vue +0 -215
- data/lib/vue/refactor/shared/workflows2/components/chart.vue +0 -91
- data/lib/vue/refactor/shared/workflows2/components/workflow-form.vue +0 -466
- data/lib/vue/refactor/shared/workflows2/components/workflow-status-dropdown.vue +0 -129
- data/lib/vue/refactor/stores/cloudobjects/action.js +0 -181
- data/lib/vue/refactor/stores/cloudobjects/file.js +0 -205
- data/lib/vue/refactor/stores/entities/announcements.js +0 -75
- data/lib/vue/refactor/stores/entities/dashboard.js +0 -251
- data/lib/vue/refactor/stores/entities/workflow.js +0 -185
- data/lib/vue/refactor/stores/panels/announcements.js +0 -153
- data/lib/vue/refactor/stores/panels/notification.js +0 -114
- data/lib/vue/refactor/stores/panels/task.js +0 -66
- data/lib/vue/refactor/stores/panels/tickets.js +0 -129
- data/lib/vue/refactor/stores/role.js +0 -243
- data/lib/vue/refactor/stores/translations.json +0 -60
- data/lib/vue/refactor/stores/users.js +0 -98
- data/lib/vue/shared/dashboards/apps/edit.vue +0 -215
- data/lib/vue/shared/dashboards/apps/index.vue +0 -112
- data/lib/vue/shared/dashboards/apps/new.vue +0 -89
- data/lib/vue/shared/dashboards/apps/show.vue +0 -88
- data/lib/vue/shared/dashboards/components/form.vue +0 -246
- data/lib/vue/shared/services/firebase.js +0 -163
- data/lib/vue/shared/services/translator.js +0 -87
- data/lib/vue/shared/stores/command.js +0 -154
- data/lib/vue/shared/stores/dashboard.js +0 -253
- data/lib/vue/shared/stores/layout.js +0 -61
- data/lib/vue/shared/stores/systemController.js +0 -67
- data/lib/vue/shared/stores/users.js +0 -57
- data/lib/vue/stores/translations.json +0 -177
- data/lib/vue/translation.js +0 -45
- data/lib/webpack/base.js +0 -191
- data/lib/webpack/core.js +0 -93
- data/lib/webpack/engines.js +0 -167
- data/lib/webpack/root.js +0 -105
- data/lib/webpack/version.js +0 -78
- data/vendor/bulma/LICENSE +0 -21
- data/vendor/bulma/bulma.sass +0 -10
- data/vendor/bulma/css/bulma-rtl.css +0 -11851
- data/vendor/bulma/css/bulma-rtl.min.css +0 -1
- data/vendor/bulma/css/bulma.css +0 -11851
- data/vendor/bulma/css/bulma.min.css +0 -1
- data/vendor/bulma/sass/base/_all.sass +0 -6
- data/vendor/bulma/sass/base/animations.sass +0 -5
- data/vendor/bulma/sass/base/generic.sass +0 -145
- data/vendor/bulma/sass/base/helpers.sass +0 -1
- data/vendor/bulma/sass/base/minireset.sass +0 -79
- data/vendor/bulma/sass/components/_all.sass +0 -15
- data/vendor/bulma/sass/components/breadcrumb.sass +0 -77
- data/vendor/bulma/sass/components/card.sass +0 -103
- data/vendor/bulma/sass/components/dropdown.sass +0 -83
- data/vendor/bulma/sass/components/level.sass +0 -79
- data/vendor/bulma/sass/components/media.sass +0 -59
- data/vendor/bulma/sass/components/menu.sass +0 -59
- data/vendor/bulma/sass/components/message.sass +0 -101
- data/vendor/bulma/sass/components/modal.sass +0 -117
- data/vendor/bulma/sass/components/navbar.sass +0 -446
- data/vendor/bulma/sass/components/pagination.sass +0 -167
- data/vendor/bulma/sass/components/panel.sass +0 -121
- data/vendor/bulma/sass/components/tabs.sass +0 -176
- data/vendor/bulma/sass/elements/_all.sass +0 -16
- data/vendor/bulma/sass/elements/box.sass +0 -26
- data/vendor/bulma/sass/elements/button.sass +0 -357
- data/vendor/bulma/sass/elements/container.sass +0 -29
- data/vendor/bulma/sass/elements/content.sass +0 -162
- data/vendor/bulma/sass/elements/form.sass +0 -1
- data/vendor/bulma/sass/elements/icon.sass +0 -46
- data/vendor/bulma/sass/elements/image.sass +0 -73
- data/vendor/bulma/sass/elements/notification.sass +0 -52
- data/vendor/bulma/sass/elements/other.sass +0 -31
- data/vendor/bulma/sass/elements/progress.sass +0 -73
- data/vendor/bulma/sass/elements/table.sass +0 -134
- data/vendor/bulma/sass/elements/tag.sass +0 -140
- data/vendor/bulma/sass/elements/title.sass +0 -70
- data/vendor/bulma/sass/form/_all.sass +0 -9
- data/vendor/bulma/sass/form/checkbox-radio.sass +0 -22
- data/vendor/bulma/sass/form/file.sass +0 -184
- data/vendor/bulma/sass/form/input-textarea.sass +0 -66
- data/vendor/bulma/sass/form/select.sass +0 -88
- data/vendor/bulma/sass/form/shared.sass +0 -60
- data/vendor/bulma/sass/form/tools.sass +0 -215
- data/vendor/bulma/sass/grid/_all.sass +0 -5
- data/vendor/bulma/sass/grid/columns.sass +0 -513
- data/vendor/bulma/sass/grid/tiles.sass +0 -36
- data/vendor/bulma/sass/helpers/_all.sass +0 -12
- data/vendor/bulma/sass/helpers/color.sass +0 -39
- data/vendor/bulma/sass/helpers/flexbox.sass +0 -35
- data/vendor/bulma/sass/helpers/float.sass +0 -10
- data/vendor/bulma/sass/helpers/other.sass +0 -14
- data/vendor/bulma/sass/helpers/overflow.sass +0 -2
- data/vendor/bulma/sass/helpers/position.sass +0 -7
- data/vendor/bulma/sass/helpers/spacing.sass +0 -31
- data/vendor/bulma/sass/helpers/typography.sass +0 -103
- data/vendor/bulma/sass/helpers/visibility.sass +0 -122
- data/vendor/bulma/sass/layout/_all.sass +0 -6
- data/vendor/bulma/sass/layout/footer.sass +0 -11
- data/vendor/bulma/sass/layout/hero.sass +0 -153
- data/vendor/bulma/sass/layout/section.sass +0 -17
- data/vendor/bulma/sass/utilities/_all.sass +0 -9
- data/vendor/bulma/sass/utilities/animations.sass +0 -1
- data/vendor/bulma/sass/utilities/controls.sass +0 -49
- data/vendor/bulma/sass/utilities/derived-variables.sass +0 -114
- data/vendor/bulma/sass/utilities/extends.sass +0 -25
- data/vendor/bulma/sass/utilities/functions.sass +0 -135
- data/vendor/bulma/sass/utilities/initial-variables.sass +0 -79
- data/vendor/bulma/sass/utilities/mixins.sass +0 -303
- data/vendor/lesli-css/_index.scss +0 -34
- data/vendor/lesli-css/lesli.scss +0 -51
- data/vendor/lesli-css/license +0 -28
- data/vendor/lesli-css/src/base/fonts.scss +0 -50
- data/vendor/lesli-css/src/base/normalize.scss +0 -118
- data/vendor/lesli-css/src/components/blockquote.scss +0 -61
- data/vendor/lesli-css/src/components/columns.scss +0 -92
- data/vendor/lesli-css/src/components/container.scss +0 -47
- data/vendor/lesli-css/src/components/navigation.scss +0 -59
- data/vendor/lesli-css/src/functions/colors.scss +0 -184
- data/vendor/lesli-css/src/helpers/units.scss +0 -44
- data/vendor/lesli-css/src/mixins/breakpoint.scss +0 -184
- data/vendor/lesli-css/src/mixins/flex.scss +0 -80
- data/vendor/lesli-css/src/mixins/scrollbar.scss +0 -46
- data/vendor/lesli-css/src/settings/variables.scss +0 -26
- data/vendor/lesli-css/tests/base/normalize.spec.scss +0 -125
- data/vendor/lesli-css/tests/functions/colors.spec.scss +0 -117
- data/vendor/lesli-css/tests/mixins/breakpoint.spec.scss +0 -429
- data/vendor/lesli-css/tests/mixins/scrollbar.spec.scss +0 -82
- data/vendor/lesli-css/vendor/normalize.scss +0 -351
- data/vendor/remixicon/License +0 -201
- data/vendor/remixicon/fonts/remixicon.css +0 -2583
- /data/{vendor/lesli-css/src/components/grid.scss → app/assets/stylesheets/lesli/application.css} +0 -0
- /data/db/migrate/v1/{0010001010_create_lesli_account_details.rb → 0000110210_create_lesli_account_details.rb} +0 -0
- /data/db/structure/{00000008_custom_fields.json → 00000300_custom_fields.json} +0 -0
- /data/lib/assets/javascripts/lesli/{i18n.js → i18n_js} +0 -0
@@ -1,311 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
|
-
Lesli
|
4
|
-
|
5
|
-
Copyright (c) 2023, Lesli Technologies, S. A.
|
6
|
-
|
7
|
-
This program is free software: you can redistribute it and/or modify
|
8
|
-
it under the terms of the GNU General Public License as published by
|
9
|
-
the Free Software Foundation, either version 3 of the License, or
|
10
|
-
(at your option) any later version.
|
11
|
-
|
12
|
-
This program is distributed in the hope that it will be useful,
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
GNU General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU General Public License
|
18
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
19
|
-
|
20
|
-
Lesli · Ruby on Rails Development Platform.
|
21
|
-
|
22
|
-
Made with ♥ by https://www.lesli.tech
|
23
|
-
Building a better future, one line of code at a time.
|
24
|
-
|
25
|
-
@contact hello@lesli.tech
|
26
|
-
@website https://www.lesli.tech
|
27
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
28
|
-
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
30
|
-
// ·
|
31
|
-
|
32
|
-
=end
|
33
|
-
module Lesli
|
34
|
-
class CloudObject::Activity < ApplicationRecord
|
35
|
-
self.abstract_class = true
|
36
|
-
|
37
|
-
belongs_to :user_creator, class_name: "::User", foreign_key: "users_id", optional: true
|
38
|
-
|
39
|
-
# This enum can be overrided by the model that inherits from CloudObject::Activity
|
40
|
-
enum category: {
|
41
|
-
action_list: "action_list",
|
42
|
-
action_create: "action_create",
|
43
|
-
action_show: "action_show",
|
44
|
-
action_update: "action_update",
|
45
|
-
action_destroy: "action_destroy",
|
46
|
-
action_status: "action_status",
|
47
|
-
action_workflow_action_failed: "action_workflow_action_failed",
|
48
|
-
action_email_sent: "action_email_sent",
|
49
|
-
action_create_file: "action_create_file",
|
50
|
-
action_update_file: "action_update_file",
|
51
|
-
action_destroy_file: "action_destroy_file",
|
52
|
-
action_not_found_file: "action_not_found_file",
|
53
|
-
}
|
54
|
-
|
55
|
-
# @return [User] This method will always return nil
|
56
|
-
# @description At the current time, this is a dummy method that returns nil, so the function is_editable_by? in
|
57
|
-
# ApplicationLesliRecord will work without issues
|
58
|
-
def user_main
|
59
|
-
return nil
|
60
|
-
end
|
61
|
-
|
62
|
-
# @return [Class] The class of the association 'belongs_to'
|
63
|
-
# @description All activities belong to a *cloud_object*. This method returns the specific class of
|
64
|
-
# that cloud_object.
|
65
|
-
# @example
|
66
|
-
# puts DeutscheLeibrenten::Project::Activity.cloud_object_model.new # This will display an instance of DeutscheLeibrenten::Project
|
67
|
-
def self.cloud_object_model
|
68
|
-
self.reflect_on_association(:cloud_object).klass
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
#######################################################################################
|
73
|
-
############################## Activities Log Methods ##############################
|
74
|
-
#######################################################################################
|
75
|
-
|
76
|
-
|
77
|
-
# @param current_user [User] The current logged user
|
78
|
-
# @param cloud_id [Integer] Id of the *cloud_object* to which this activities belongs to
|
79
|
-
# @param query [Query] that contains the search and pagination information
|
80
|
-
# @return [Array] Array of activities. Each activities contains a *responses* element,
|
81
|
-
# which is an array that has all its responses ordered by date
|
82
|
-
# @description Retrieves and returns all activities from a *cloud_object*
|
83
|
-
# @example
|
84
|
-
# @activities = activity_model.index(
|
85
|
-
# current_user,
|
86
|
-
# profile_id,
|
87
|
-
# @query
|
88
|
-
# )
|
89
|
-
def self.index(current_user, cloud_id, query)
|
90
|
-
cloud_object_model = self.cloud_object_model
|
91
|
-
account_model = cloud_object_model.reflect_on_association(:account).klass
|
92
|
-
translations_module = self.name.split("::")[0].gsub("Cloud", "").underscore
|
93
|
-
|
94
|
-
# get search string from query params
|
95
|
-
search_string = query[:search].downcase.gsub(" ","%") unless query[:search].blank?
|
96
|
-
|
97
|
-
activities = self
|
98
|
-
.where("#{cloud_object_model.table_name}_id".to_sym => cloud_id)
|
99
|
-
.order(id: :desc)
|
100
|
-
.joins("inner join users u on #{self.table_name}.users_id = u.id")
|
101
|
-
.joins("inner join user_details ud on ud.users_id = u.id")
|
102
|
-
|
103
|
-
|
104
|
-
# Filter results by search string
|
105
|
-
unless search_string.blank?
|
106
|
-
# (LOWER(ud.last_name) SIMILAR TO '%#{search_string}%') OR
|
107
|
-
activities = activities.where("
|
108
|
-
(LOWER(#{self.table_name}.field_name) SIMILAR TO '%#{search_string}%') OR
|
109
|
-
(LOWER(#{self.table_name}.value_from) SIMILAR TO '%#{search_string}%') OR
|
110
|
-
(LOWER(#{self.table_name}.value_to) SIMILAR TO '%#{search_string}%') OR
|
111
|
-
(LOWER(ud.first_name) SIMILAR TO '%#{search_string}%')
|
112
|
-
")
|
113
|
-
end
|
114
|
-
|
115
|
-
activities = activities.map do |activity|
|
116
|
-
# We translate the category, first, we search in the core
|
117
|
-
category = I18n.t("core.shared.activities_enum_category_#{activity[:category]}", default: nil)
|
118
|
-
|
119
|
-
# Then we search in the engine
|
120
|
-
category = I18n.t("#{translations_module}.shared.activities_enum_category_#{activity[:category]}", default: nil) unless category
|
121
|
-
|
122
|
-
#Then we default to the real field
|
123
|
-
category = activity[:category] unless category
|
124
|
-
|
125
|
-
activity_attributes = activity.attributes
|
126
|
-
activity_attributes["category"] = category
|
127
|
-
activity_attributes["created_at_raw"] = activity[:created_at]
|
128
|
-
activity_attributes["created_at"] = LC::Date.to_string_datetime(activity[:created_at])
|
129
|
-
activity_attributes["updated_at"] = LC::Date.to_string_datetime(activity[:updated_at])
|
130
|
-
|
131
|
-
user = activity.user_creator
|
132
|
-
activity_attributes[:user_name] = user.full_name
|
133
|
-
|
134
|
-
activity_attributes
|
135
|
-
end
|
136
|
-
|
137
|
-
Kaminari.paginate_array(activities).page(query[:pagination][:page]).per(query[:pagination][:perPage])
|
138
|
-
end
|
139
|
-
|
140
|
-
# @return [void]
|
141
|
-
# @param current_user [::User] The user that created the cloud_object
|
142
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that was created
|
143
|
-
# @description Creates an activity for this cloud_object indicating who created it.
|
144
|
-
# Example
|
145
|
-
# params = {...}
|
146
|
-
# ticket = CloudHelp::Ticket.create(params)
|
147
|
-
# CloudHelp::Ticket.log_create(User.first, ticket)
|
148
|
-
def self.log_create(current_user, cloud_object)
|
149
|
-
cloud_object.activities.create(
|
150
|
-
user_creator: current_user,
|
151
|
-
category: "action_create"
|
152
|
-
)
|
153
|
-
|
154
|
-
# If cloud_object has workflow
|
155
|
-
if defined?(cloud_object.status)
|
156
|
-
module_name = cloud_object.class.lesli_classname().split("::")[0].underscore
|
157
|
-
cloud_object.activities.create(
|
158
|
-
user_creator: current_user,
|
159
|
-
category: "action_status",
|
160
|
-
description: cloud_object.status&.name,
|
161
|
-
field_name: "#{module_name}_workflow_statuses_id",
|
162
|
-
value_to: cloud_object.status&.name
|
163
|
-
)
|
164
|
-
end
|
165
|
-
|
166
|
-
yield if block_given?
|
167
|
-
end
|
168
|
-
|
169
|
-
# @return [void]
|
170
|
-
# @param current_user [::User] The user that created the cloud_object
|
171
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that was shown
|
172
|
-
# @description Creates an activity for this cloud_object indicating who view it.
|
173
|
-
# Example
|
174
|
-
# params = {...}
|
175
|
-
# ticket = CloudHelp::Ticket.create(params)
|
176
|
-
# CloudHelp::Ticket.log_show(User.first, ticket)
|
177
|
-
def self.log_show(current_user, cloud_object)
|
178
|
-
cloud_object.activities.create(
|
179
|
-
user_creator: current_user,
|
180
|
-
category: "action_show"
|
181
|
-
)
|
182
|
-
|
183
|
-
yield if block_given?
|
184
|
-
end
|
185
|
-
|
186
|
-
# @return [void]
|
187
|
-
# @param current_user [::User] The user that edited the cloud_object
|
188
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that was edited
|
189
|
-
# @param old_attributes[Hash] The data of the record before update
|
190
|
-
# @param new_attributes[Hash] The data of the record after update
|
191
|
-
# @description Creates an activity for this cloud_object if someone changed any of this values
|
192
|
-
# Example
|
193
|
-
# ticket = CloudHelp::Ticket.find(1)
|
194
|
-
# old_attributes = ticket.attributes
|
195
|
-
# ticket.update(user_main: User.find(33))
|
196
|
-
# new_attributes = ticket.attributes
|
197
|
-
# CloudHelp::TicketLogger.log_update(User.find(1), ticket, old_attributes, new_attributes)
|
198
|
-
def self.log_update(current_user, cloud_object, old_attributes, new_attributes, category: "action_update")
|
199
|
-
|
200
|
-
# We remove values that are not tracked in the activities
|
201
|
-
old_attributes.except!("id", "created_at", "updated_at", "deleted_at")
|
202
|
-
old_attributes.each do |key, value|
|
203
|
-
next if value == new_attributes[key]
|
204
|
-
if key.include?("id")
|
205
|
-
if key == "user_main_id" || key == "users_id" || key == "user_branch_office_id"
|
206
|
-
update_user_field(cloud_object, current_user, key, old_attributes[key], new_attributes[key], category)
|
207
|
-
elsif key.include?("workflow_statuses_id")
|
208
|
-
update_workflow_status_field(cloud_object, current_user, key, old_attributes[key], new_attributes[key])
|
209
|
-
else
|
210
|
-
update_field(cloud_object, current_user, key, old_attributes[key], new_attributes[key], category)
|
211
|
-
end
|
212
|
-
else
|
213
|
-
update_field(cloud_object, current_user, key, old_attributes[key], new_attributes[key], category)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
yield if block_given?
|
218
|
-
end
|
219
|
-
|
220
|
-
# @return [void]
|
221
|
-
# @param current_user [::User] The user that deleted the cloud_object
|
222
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that was destroyed
|
223
|
-
# @description Creates an activity for this cloud_object indicating that someone deleted it
|
224
|
-
# Example
|
225
|
-
# ticket = CloudHelp::Ticket.find(1)
|
226
|
-
# CloudHelp::TicketLogger.log_destroy(User.first, ticket)
|
227
|
-
# ticket.destroy
|
228
|
-
def self.log_destroy(current_user, cloud_object)
|
229
|
-
cloud_object.activities.create(
|
230
|
-
user_creator: current_user,
|
231
|
-
category: "action_destroy"
|
232
|
-
)
|
233
|
-
|
234
|
-
yield if block_given?
|
235
|
-
end
|
236
|
-
|
237
|
-
protected
|
238
|
-
|
239
|
-
# @return [void]
|
240
|
-
# @param current_user [User] The user that deleted the cloud_object
|
241
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that updated
|
242
|
-
# @param key [String] The user field to be logged
|
243
|
-
# @param old_user_id [Integer] The id of the user prior to the update
|
244
|
-
# @param new_user_id [Integer] The id of the user after the update
|
245
|
-
# @description Logs an "action_update" activity. But instead of using the raw id of the user, it logs their name
|
246
|
-
# @example
|
247
|
-
# project = CloudHouse::Project.first
|
248
|
-
# CloudHouse::ProjectLogger.log_update(User.first, project, "users_id", 1, 2)
|
249
|
-
# # This will log a change from user with id 1 to user with id 2 using their names
|
250
|
-
def self.update_user_field(cloud_object, current_user, key, old_user_id, new_user_id, category)
|
251
|
-
cloud_object.activities.create(
|
252
|
-
user_creator: current_user,
|
253
|
-
category: category,
|
254
|
-
field_name: key,
|
255
|
-
value_from: old_user_id ? User.with_deleted.find(old_user_id).full_name : nil,
|
256
|
-
value_to: new_user_id ? User.with_deleted.find(new_user_id).full_name : nil
|
257
|
-
)
|
258
|
-
end
|
259
|
-
|
260
|
-
# @return [void]
|
261
|
-
# @param current_user [User] The user that deleted the cloud_object
|
262
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that updated
|
263
|
-
# @param key [String] The user field to be logged
|
264
|
-
# @param old_workflow_status_id [Integer] The id of the workflow status prior to the update
|
265
|
-
# @param new_workflow_status_id [Integer] The id of the workflow status after the update
|
266
|
-
# @description Logs an "action_update" activity. But instead of using the raw id of the workflow status, it logs its name
|
267
|
-
# @example
|
268
|
-
# project = CloudHouse::Project.first
|
269
|
-
# CloudHouse::ProjectLogger.log_update(User.first, project, "cloud_house_workflow_statuses_id, 1, 2)
|
270
|
-
# # This will log a change from workflow status with id 1 to workflow status with id 2 using their names
|
271
|
-
def self.update_workflow_status_field(cloud_object, current_user, key, old_workflow_status_id, new_workflow_status_id)
|
272
|
-
module_name = cloud_object.class.lesli_classname().split("::")[0]
|
273
|
-
old_status = eval("#{module_name}::Workflow::Status").with_deleted.find(old_workflow_status_id).name
|
274
|
-
new_status = eval("#{module_name}::Workflow::Status").with_deleted.find(new_workflow_status_id).name
|
275
|
-
|
276
|
-
cloud_object.activities.create(
|
277
|
-
user_creator: current_user,
|
278
|
-
description: new_status,
|
279
|
-
category: "action_status",
|
280
|
-
field_name: key,
|
281
|
-
value_from: old_status,
|
282
|
-
value_to: new_status
|
283
|
-
)
|
284
|
-
end
|
285
|
-
|
286
|
-
# @return [void]
|
287
|
-
# @param current_user [User] The user that deleted the cloud_object
|
288
|
-
# @param cloud_object [CloudModule::Model] The cloud_object that updated
|
289
|
-
# @param key [String] The user field to be logged
|
290
|
-
# @param old_field [Integer] The value of the field prior to the update
|
291
|
-
# @param new_field [Integer] The value of the field after the update
|
292
|
-
# @description Logs an "action_update" activity. If the value that changed is a date, it uses LC::Date to turn it into a string
|
293
|
-
# otherwise, it logs it as is
|
294
|
-
# @example
|
295
|
-
# ticket = CloudHelp::Ticket.first
|
296
|
-
# CloudHelp::TicketLogger.log_update(User.first, ticket, "deadline": Time.now - 1.days, Time.now)
|
297
|
-
# # This will log a change from workflow on the deadline, and it will use the format specified by the lesli instance
|
298
|
-
def self.update_field(cloud_object, current_user, key, old_field, new_field, category)
|
299
|
-
old_field = LC::Date.to_string_datetime(old_field) if old_field.is_a?(Time) || old_field.is_a?(Date)
|
300
|
-
new_field = LC::Date.to_string_datetime(new_field) if new_field.is_a?(Time) || new_field.is_a?(Date)
|
301
|
-
|
302
|
-
cloud_object.activities.create(
|
303
|
-
user_creator: current_user,
|
304
|
-
category: category,
|
305
|
-
field_name: key,
|
306
|
-
value_from: old_field,
|
307
|
-
value_to: new_field
|
308
|
-
)
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
@@ -1,158 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
|
-
Lesli
|
4
|
-
|
5
|
-
Copyright (c) 2023, Lesli Technologies, S. A.
|
6
|
-
|
7
|
-
This program is free software: you can redistribute it and/or modify
|
8
|
-
it under the terms of the GNU General Public License as published by
|
9
|
-
the Free Software Foundation, either version 3 of the License, or
|
10
|
-
(at your option) any later version.
|
11
|
-
|
12
|
-
This program is distributed in the hope that it will be useful,
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
GNU General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU General Public License
|
18
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
19
|
-
|
20
|
-
Lesli · Your Smart Business Assistant.
|
21
|
-
|
22
|
-
Made with ♥ by https://www.lesli.tech
|
23
|
-
Building a better future, one line of code at a time.
|
24
|
-
|
25
|
-
@contact hello@lesli.tech
|
26
|
-
@website https://lesli.tech
|
27
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
28
|
-
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
30
|
-
// ·
|
31
|
-
|
32
|
-
=end
|
33
|
-
module Lesli
|
34
|
-
class CloudObject::CustomField < ApplicationLesliRecord
|
35
|
-
self.abstract_class = true
|
36
|
-
belongs_to :user_creator, class_name: "::User", foreign_key: "users_id"
|
37
|
-
|
38
|
-
# @return [User] This method will always return nil
|
39
|
-
# @description At the current time, this is a dummy method that returns nil, so the function is_editable_by? in
|
40
|
-
# ApplicationLesliRecord will work without issues
|
41
|
-
def user_main
|
42
|
-
return nil
|
43
|
-
end
|
44
|
-
|
45
|
-
=begin
|
46
|
-
# @param cloud_object [ApplicationRecord] Cloud object to which an user can subscribe to
|
47
|
-
# @param user [User] The user that is subscribing to the *cloud_ubject*
|
48
|
-
# @param event [Symbol] A valid event from this class's *event* enum to wich the *user* will be subscribed
|
49
|
-
# @param notification_type [Symbol] A valid notification_type from this class's *notification_type* enum
|
50
|
-
# @return [void]
|
51
|
-
# @description Subscribes a *user* to one or all *events* of the *cloud_object*. If no *event* is provided, the *user*
|
52
|
-
# is subscribed to all the *events*
|
53
|
-
# @example
|
54
|
-
# first_ticket = CloudHelp::Ticket.find( 1 )
|
55
|
-
# second_ticket = CloudHelp::Ticket.find( 2 )
|
56
|
-
# user = current_user
|
57
|
-
# CloudHelp::Ticket::Subscriber.add_subscriber( first_ticket, current_user )
|
58
|
-
# CloudHelp::Ticket::Subscriber.add_subscriber( second_ticket, current_user, :http_post, :email )
|
59
|
-
def self.add_subscriber(cloud_object, user, event=nil, notification_type= :web)
|
60
|
-
model = dynamic_info[:model]
|
61
|
-
|
62
|
-
if event
|
63
|
-
return cloud_object.subscribers.create(
|
64
|
-
user: user,
|
65
|
-
event: event,
|
66
|
-
notification_type: model.notification_types[notification_type]
|
67
|
-
)
|
68
|
-
end
|
69
|
-
|
70
|
-
model.events.values.each do |event|
|
71
|
-
cloud_object.subscribers.create(
|
72
|
-
user: user,
|
73
|
-
event: event,
|
74
|
-
notification_type: model.notification_types[notification_type]
|
75
|
-
)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# @param cloud_object [ApplicationRecord] Cloud object to which an user can subscribe to
|
80
|
-
# @param subject [String] The subject that will be shown in the notification
|
81
|
-
# @param event [Symbol] A valid event from this class's *event* enum
|
82
|
-
# @return [void]
|
83
|
-
# @description Notifies all the users subscribed to the *cloud_object*'s *event* using the *Courier* engine
|
84
|
-
# @example
|
85
|
-
# ticket = CloudHelp::Ticket.find( 1 )
|
86
|
-
# ClodHelp::Ticket::Subscriber.notify_subscribers(
|
87
|
-
# ticket,
|
88
|
-
# "A new comment has been added to ticket #{ticket.id}",
|
89
|
-
# :comment_created
|
90
|
-
# )
|
91
|
-
def self.notify_subscribers(cloud_object, subject, event)
|
92
|
-
module_name = dynamic_info[:module_name]
|
93
|
-
object_name = dynamic_info[:object_name]
|
94
|
-
|
95
|
-
cloud_object.subscribers.where(event: event).each do |subscriber|
|
96
|
-
Courier::Bell::Notifications.send(
|
97
|
-
user: subscriber.user,
|
98
|
-
subject: subject,
|
99
|
-
href: "#{module_name}/#{object_name}/#{cloud_object.id}",
|
100
|
-
type: subscriber.notification_type,
|
101
|
-
cloud_object_type: "#{module_name}/#{object_name}"
|
102
|
-
)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# @param cloud_object [ApplicationRecord] Cloud object to which an user can subscribe to
|
107
|
-
# @param user [User] The user that is subscribing to the *cloud_object*
|
108
|
-
# @return [Array] Array of subscriptions. There is one subscription per *event*.
|
109
|
-
# @description Generates an array of subscription, Each element contains a subscription *event*,
|
110
|
-
# information about wheter the *user* is subscribed or not and, if the user is subscribed,
|
111
|
-
# the notification type of the subscription
|
112
|
-
# @example
|
113
|
-
# ticket = CloudHelp::Ticket.find( 1 )
|
114
|
-
# subscription_events = CloudHelp::Ticket::Subscriber.subscription_events(
|
115
|
-
# ticket,
|
116
|
-
# current_user
|
117
|
-
# )
|
118
|
-
def self.subscription_events(cloud_object, user)
|
119
|
-
model = dynamic_info[:model]
|
120
|
-
|
121
|
-
data = { }
|
122
|
-
events = model.events.keys
|
123
|
-
events.each do |event|
|
124
|
-
data[event] = {
|
125
|
-
event: event,
|
126
|
-
subscribed: false,
|
127
|
-
notification_type: :web
|
128
|
-
}
|
129
|
-
end
|
130
|
-
cloud_object.subscribers.where(users_id: user.id).each do |subscriber|
|
131
|
-
data[subscriber.event][:id] = subscriber.id
|
132
|
-
data[subscriber.event][:subscribed] = true
|
133
|
-
data[subscriber.event][:notification_type] = subscriber.notification_type
|
134
|
-
end
|
135
|
-
data.values
|
136
|
-
end
|
137
|
-
|
138
|
-
private
|
139
|
-
|
140
|
-
# @return [Hash] Hash that contains information about the class
|
141
|
-
# @description Returns dynamic information based on the current implementation of this abstract class
|
142
|
-
# @example
|
143
|
-
# dynamic_info = CloudHelp::Ticket::Subscriber.dynamic_info
|
144
|
-
# puts dynamic_info[:module_name] # will print 'help'
|
145
|
-
# puts dynamic_info[:object_name] # will print 'ticket'
|
146
|
-
# dynamic_info.model.new # will return an instance of CloudHelp::Ticket::Subscriber
|
147
|
-
def self.dynamic_info
|
148
|
-
module_info = self.name.split("::")
|
149
|
-
{
|
150
|
-
module_name: module_info[0].sub("Cloud", "").downcase,
|
151
|
-
object_name: module_info[1].downcase,
|
152
|
-
model: "#{module_info[0]}::#{module_info[1]}::Subscriber".constantize
|
153
|
-
}
|
154
|
-
end
|
155
|
-
=end
|
156
|
-
|
157
|
-
end
|
158
|
-
end
|
@@ -1,219 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
|
-
Lesli
|
4
|
-
|
5
|
-
Copyright (c) 2023, Lesli Technologies, S. A.
|
6
|
-
|
7
|
-
This program is free software: you can redistribute it and/or modify
|
8
|
-
it under the terms of the GNU General Public License as published by
|
9
|
-
the Free Software Foundation, either version 3 of the License, or
|
10
|
-
(at your option) any later version.
|
11
|
-
|
12
|
-
This program is distributed in the hope that it will be useful,
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
GNU General Public License for more details.
|
16
|
-
|
17
|
-
You should have received a copy of the GNU General Public License
|
18
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
19
|
-
|
20
|
-
Lesli · Ruby on Rails SaaS Development Framework.
|
21
|
-
|
22
|
-
Made with ♥ by LesliTech
|
23
|
-
Building a better future, one line of code at a time.
|
24
|
-
|
25
|
-
@contact hello@lesli.tech
|
26
|
-
@website https://www.lesli.tech
|
27
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
28
|
-
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
30
|
-
// ·
|
31
|
-
=end
|
32
|
-
module Lesli
|
33
|
-
class CloudObject::Discussion < ApplicationLesliRecord
|
34
|
-
self.abstract_class = true
|
35
|
-
belongs_to :user_creator, class_name: "::User", foreign_key: "users_id"
|
36
|
-
|
37
|
-
# @return [User] This method will always return nil
|
38
|
-
# @description At the current time, this is a dummy method that returns nil, so the function is_editable_by? in
|
39
|
-
# ApplicationLesliRecord will work without issues
|
40
|
-
def user_main
|
41
|
-
return nil
|
42
|
-
end
|
43
|
-
|
44
|
-
# @param account [Account] Account from current user
|
45
|
-
# @param cloud_id [Integer] Id of the *cloud_object* to which this discussion belongs to
|
46
|
-
# @param query [Query] that contains the search and pagination information
|
47
|
-
# @return [Array] Array of discussions. Each discussion contains a *responses* element,
|
48
|
-
# which is an array that has all its responses ordered by date
|
49
|
-
# @description Retrieves and returns all discussions from a *cloud_object*,
|
50
|
-
# including information of the user that published the comment
|
51
|
-
# @example
|
52
|
-
# current_user = the user making this request
|
53
|
-
# employee_id = params[:employee_id]
|
54
|
-
# discussions = CloudTeam::Employee::Discussion.index( account, employee_id, @query )
|
55
|
-
def self.index(current_user, cloud_id, query)
|
56
|
-
cloud_object_model = self.cloud_object_model
|
57
|
-
account_model = cloud_object_model.reflect_on_association(:account).klass
|
58
|
-
|
59
|
-
# get search string from query params
|
60
|
-
#search_string = query[:search].downcase.gsub(" ","%") unless query[:search].blank?
|
61
|
-
|
62
|
-
discussions = self.joins(:cloud_object)
|
63
|
-
.joins("inner join lesli_users u on #{self.table_name}.user_id = u.id")
|
64
|
-
.where("#{cloud_object_model.table_name}.id = #{cloud_id}")
|
65
|
-
.where("#{cloud_object_model.table_name}.account_id = #{current_user.account.id}")
|
66
|
-
.select(
|
67
|
-
"#{self.table_name}.id",
|
68
|
-
"#{self.table_name}.user_id",
|
69
|
-
"#{self.table_name}.content",
|
70
|
-
Date2.new.date_time.db_timestamps("#{self.table_name}"),
|
71
|
-
"u.email",
|
72
|
-
"CONCAT_WS(' ', u.first_name, u.last_name) as user_name"
|
73
|
-
)
|
74
|
-
|
75
|
-
# Filter results by search string
|
76
|
-
# unless search_string.blank?
|
77
|
-
# discussions = discussions.where("
|
78
|
-
# (LOWER(ud.first_name) SIMILAR TO '%#{search_string}%') OR
|
79
|
-
# (LOWER(ud.last_name) SIMILAR TO '%#{search_string}%') OR
|
80
|
-
# (LOWER(#{self.table_name}.content) SIMILAR TO '%#{search_string}%')
|
81
|
-
# ")
|
82
|
-
# end
|
83
|
-
|
84
|
-
discussions = self.format_discussions(discussions)
|
85
|
-
|
86
|
-
Kaminari.paginate_array(discussions).page(query[:pagination][:page]).per(query[:pagination][:perPage])
|
87
|
-
end
|
88
|
-
|
89
|
-
# @return [Hash] Information about the discussion
|
90
|
-
# @description Retrieves and returns a specific discussion, along with information about the user
|
91
|
-
# that created it
|
92
|
-
# @example
|
93
|
-
# discussion = CloudHelp::Ticket::Discussion.first
|
94
|
-
# puts discussion.show #This will display extra information about the discussion, like the user's name
|
95
|
-
def show(current_user = nil)
|
96
|
-
discussion_attributes = attributes.merge({
|
97
|
-
editable: is_editable_by?(current_user),
|
98
|
-
email: user_creator.email,
|
99
|
-
user_name: user_creator.full_name
|
100
|
-
})
|
101
|
-
discussion_attributes["created_at"] = LC::Date.to_string_datetime(discussion_attributes["created_at"])
|
102
|
-
|
103
|
-
discussion_attributes
|
104
|
-
end
|
105
|
-
|
106
|
-
# @return [Class] The class of the association 'belongs_to'
|
107
|
-
# @description All discussions belong to a *cloud_object*. This method returns the specific class of
|
108
|
-
# that cloud_object.
|
109
|
-
# @example
|
110
|
-
# puts DeutscheLeibrenten::Project::Discussion.cloud_object_model.new # This will display an instance of DeutscheLeibrenten::Project
|
111
|
-
def self.cloud_object_model
|
112
|
-
self.reflect_on_association(:cloud_object).klass
|
113
|
-
end
|
114
|
-
|
115
|
-
private
|
116
|
-
|
117
|
-
# @param discussions [Arrray] An array of discussions that were previously filtered
|
118
|
-
# @return [Array] A new array of discussions, nesting the responses within the parent discussions
|
119
|
-
# @description Geretes a new array of discussions, nesting the responses inside the parent discussions and order them by date
|
120
|
-
# This method uses the *nest_responses* method to support the nesting action recursively
|
121
|
-
# @example
|
122
|
-
# # Imagine that discussions has 2 discussions, the first one is a normal discussion, and the second one is a response to the first one
|
123
|
-
# puts discussions # will display something like
|
124
|
-
# # [
|
125
|
-
# # {
|
126
|
-
# # id: 1,
|
127
|
-
# # users_id: 2,
|
128
|
-
# # created_at: Date(),
|
129
|
-
# # content: 'This is a root discussion',
|
130
|
-
# # user_name: 'System',
|
131
|
-
# # discussions_id: null
|
132
|
-
# # }, {
|
133
|
-
# # id: 2,
|
134
|
-
# # users_id: 2,
|
135
|
-
# # created_at: Date(),
|
136
|
-
# # content: 'This is a response',
|
137
|
-
# # user_name: 'Test',
|
138
|
-
# # discussions_id: 1
|
139
|
-
# # }
|
140
|
-
# # ]
|
141
|
-
# puts Discussion.format_discussions(discussions) # Will display something like
|
142
|
-
# # [
|
143
|
-
# # {
|
144
|
-
# # id: 1,
|
145
|
-
# # users_id: 2,
|
146
|
-
# # created_at: Date(),
|
147
|
-
# # content: 'This is a root discussion',
|
148
|
-
# # user_name: 'System',
|
149
|
-
# # discussions_id: null,
|
150
|
-
# # responses: [{
|
151
|
-
# # id: 2,
|
152
|
-
# # users_id: 2,
|
153
|
-
# # created_at: Date(),
|
154
|
-
# # content: 'This is a response',
|
155
|
-
# # response_to: 'System'
|
156
|
-
# # user_name: 'Test',
|
157
|
-
# # discussions_id: 1
|
158
|
-
# # }]
|
159
|
-
# # }
|
160
|
-
# # ]
|
161
|
-
def self.format_discussions(discussions)
|
162
|
-
data = {}
|
163
|
-
root_discussions = []
|
164
|
-
|
165
|
-
# Add all responses to that discussion
|
166
|
-
discussions.each do |discussion|
|
167
|
-
discussion_data = {
|
168
|
-
data: discussion,
|
169
|
-
responses: []
|
170
|
-
}
|
171
|
-
data[discussion["id"]] = discussion_data
|
172
|
-
|
173
|
-
if discussion["#{self.table_name}_id"].present?
|
174
|
-
parent_discussion = data[discussion["#{self.table_name}_id"]]
|
175
|
-
next unless parent_discussion
|
176
|
-
|
177
|
-
if parent_discussion[:data]["#{self.table_name}_id"].present?
|
178
|
-
discussion["response_to"] = parent_discussion[:data]["user_name"]
|
179
|
-
end
|
180
|
-
parent_discussion[:responses].push(discussion["id"])
|
181
|
-
else
|
182
|
-
root_discussions.push(discussion_data)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
# Nest the responses to root discussions. A root discussion is any comment that is not a response to another comment
|
187
|
-
root_discussions.each do |discussion|
|
188
|
-
responses = []
|
189
|
-
self.nest_responses(data, discussion, responses)
|
190
|
-
discussion[:responses] = responses
|
191
|
-
end
|
192
|
-
|
193
|
-
# revert the root discussions so the most recent comments appear in the top
|
194
|
-
root_discussions.reverse
|
195
|
-
end
|
196
|
-
|
197
|
-
# @param data [Hash] Hash that contains all the discussions, the key is the id of the discussion
|
198
|
-
# @param discussion [Hash] Hash that contains the information
|
199
|
-
# @param responses [Array] Array of discussions, that are the responses to the *discussion* param.
|
200
|
-
# It should start as an empty array
|
201
|
-
# @return [void]
|
202
|
-
# @description Recursive function that checks all discussions that are actually responses of other
|
203
|
-
# discussions and adds them to their *responses* param. It adds direct responses, responses of responses, etc.
|
204
|
-
# This is a void function that modifies the *discussion* param directly
|
205
|
-
# @example
|
206
|
-
# data = {}
|
207
|
-
# CloudHelp::Ticket::Discussion.all.each do |discussion|
|
208
|
-
# data[discussion.id] = discussion
|
209
|
-
# end
|
210
|
-
# CloudHelp::Ticket::Discussion.nest_responses(data, CloudHelp::Ticket::Discussion.first, [])
|
211
|
-
def self.nest_responses(data, discussion, responses)
|
212
|
-
discussion[:responses].each do |response_id|
|
213
|
-
response = data[response_id]
|
214
|
-
responses.push(response[:data])
|
215
|
-
self.nest_responses(data, response, responses)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|