Quellcode durchsuchen

merge main into add-activity-log-doc

chenxin0723 vor 1 Jahr
Ursprung
Commit
fcef9524a6
52 geänderte Dateien mit 908 neuen und 46 gelöschten Zeilen
  1. 5 1
      docs/activity-log.html
  2. 4 0
      docs/advanced-functions/the-go-html-builder.html
  3. 17 1
      docs/appendix/all-demo-examples.html
  4. 4 0
      docs/basics/brand.html
  5. 5 1
      docs/basics/confirm-dialog.html
  6. 4 0
      docs/basics/event-handling.html
  7. 4 0
      docs/basics/filter.html
  8. 4 0
      docs/basics/form-handling.html
  9. 4 0
      docs/basics/layout-function-and-page-injector.html
  10. 4 0
      docs/basics/listing.html
  11. 4 0
      docs/basics/manipulate-page-url-in-event-func.html
  12. 4 0
      docs/basics/menu.html
  13. 4 0
      docs/basics/notification-center.html
  14. 4 0
      docs/basics/page-func-and-event-func.html
  15. 4 0
      docs/basics/partial-refresh-with-portal.html
  16. 4 0
      docs/basics/reload-page-with-a-flash.html
  17. 4 0
      docs/basics/scope-component.html
  18. 4 0
      docs/basics/shortcut.html
  19. 4 0
      docs/basics/summary-of-event-response.html
  20. 4 0
      docs/basics/switch-pages-with-push-state.html
  21. 223 0
      docs/basics/worker.html
  22. 4 0
      docs/components-guide/composite-new-component-with-go.html
  23. 4 0
      docs/components-guide/integrate-a-heavy-vue-component.html
  24. 4 0
      docs/getting-started/one-minute-quick-start.html
  25. 5 1
      docs/index.html
  26. 0 0
      docs/index.js
  27. 4 0
      docs/presets-guide/detail-page-for-complex-object.html
  28. 4 0
      docs/presets-guide/editing-customizations.html
  29. 4 0
      docs/presets-guide/its-the-whole-house.html
  30. 4 0
      docs/presets-guide/permissions.html
  31. 4 0
      docs/presets-guide/role.html
  32. 0 0
      docs/search_indexes.json
  33. 4 0
      docs/seo.html
  34. 4 0
      docs/slug.html
  35. 4 0
      docs/vuetify-components/a-taste-of-using-vuetify-in-go.html
  36. 4 0
      docs/vuetify-components/auto-complete.html
  37. 4 0
      docs/vuetify-components/basic-inputs.html
  38. 4 0
      docs/vuetify-components/lazy-portals.html
  39. 4 0
      docs/vuetify-components/linkage-select.html
  40. 48 0
      docsrc/content/basics/worker.go
  41. 1 1
      docsrc/content/getting-started/what-is-goplaid.go
  42. 1 1
      docsrc/content/home.go
  43. 1 0
      docsrc/doc_tree.go
  44. 162 0
      docsrc/examples/example_basics/action_worker.go
  45. 26 0
      docsrc/examples/example_basics/action_worker_mock_que.go
  46. 1 1
      docsrc/examples/example_basics/confirm-dialog.go
  47. 98 0
      docsrc/examples/example_basics/worker.go
  48. 122 0
      docsrc/examples/example_basics/worker_mock_que.go
  49. 0 0
      docsrc/generated/examples-generated.go
  50. 14 0
      docsrc/mux.go
  51. 11 7
      go.mod
  52. 40 32
      go.sum

+ 5 - 1
docs/activity-log.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-blue-500'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>
@@ -237,7 +241,7 @@ Record the activity log manually</h2>
 
 <p>If you register a preset model into the activity, the activity will record the activity log automatically for the CRUD operation of the model. But if you want to record the activity log manually for some other operations or you want to register a model that is not a preset model, you can use the following sample to record the activity log manually.</p>
 
-<highlightjs :language='"go"' :code='"presetsBuilder := presets.New()\ndb, err := gorm.Open(sqlite.Open(\"/tmp/activity.db\"), \u0026gorm.Config{})\nif err != nil {\n\tpanic(err)\n}\n\ntype Product struct {\n\tTitle string\n\tCode  string\n\tPrice float64\n}\n\nactivityBuilder := activity.New(presetsBuilder, db)\nactivityBuilder.RegisterModel(\u0026Product{})\n\n// if you can fetch the user infromation from the current context, you can use the following code to record the user\ncurrentCtx := context.WithValue(context.Background(), activity.CreatorContextKey, \"user1\")\nactivityBuilder.AddRecords(\"Publish\", currentCtx, \u0026Product{Title: \"Product 1\", Code: \"P1\", Price: 100}) // custmize the action name\nactivityBuilder.AddRecords(\"Update Price\", currentCtx, \u0026Product{Title: \"Product 1\", Code: \"P1\", Price: 200})\n"'></highlightjs>
+<highlightjs :language='"go"' :code='"presetsBuilder := presets.New()\ndb, err := gorm.Open(sqlite.Open(\"/tmp/activity.db\"), \u0026gorm.Config{})\nif err != nil {\n\tpanic(err)\n}\n\ntype Product struct {\n\tTitle string\n\tCode  string\n\tPrice float64\n}\n\nactivityBuilder := activity.New(presetsBuilder, db)\nactivityBuilder.RegisterModel(\u0026Product{})\ncurrentCtx := context.WithValue(context.Background(), activity.CreatorContextKey, \"user1\")\nactivityBuilder.AddRecords(\"Publish\", currentCtx, \u0026Product{Title: \"Product 1\", Code: \"P1\", Price: 100}) // custmize the action name\nactivityBuilder.AddRecords(\"Update Price\", currentCtx, \u0026Product{Title: \"Product 1\", Code: \"P1\", Price: 200})\n"'></highlightjs>
 </div>
 </div>
 </div>

+ 4 - 0
docs/advanced-functions/the-go-html-builder.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 17 - 1
docs/appendix/all-demo-examples.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>
@@ -422,7 +426,7 @@
 </li>
 
 <li>
-<a href='/samples/confirm-dialog' target='_blank'>Confirm Dialog</a>
+<a href='/samples/confirm_dialog/confirm-dialog' target='_blank'>Confirm Dialog</a>
  | 
 <a href='https://github.com/qor5/docs/tree/main/docsrc/examples/example_basics/confirm-dialog.go' target='_blank'>Source</a>
 </li>
@@ -535,6 +539,18 @@
 <a href='https://github.com/qor5/docs/tree/main/docsrc/examples/e22_vuetify_variant_sub_form/page.go' target='_blank'>Source</a>
 </li>
 
+<li>
+<a href='/samples/worker/workers' target='_blank'>Worker</a>
+ | 
+<a href='https://github.com/qor5/docs/tree/main/docsrc/examples/example_basics/worker.go' target='_blank'>Source</a>
+</li>
+
+<li>
+<a href='/samples/action_worker/example-resources' target='_blank'>Action Worker</a>
+ | 
+<a href='https://github.com/qor5/docs/tree/main/docsrc/examples/example_basics/action_worker.go' target='_blank'>Source</a>
+</li>
+
 <li>
 <a href='/samples/composite-component-sample1' target='_blank'>Composite New Component With Go</a>
  | 

+ 4 - 0
docs/basics/brand.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 5 - 1
docs/basics/confirm-dialog.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>
@@ -219,7 +223,7 @@ To use a custom portal for dialog.</p>
 
 <div>
 <div class='demo'>
-<a href='/samples/confirm-dialog' target='_blank'>Check the demo</a>
+<a href='/samples/confirm_dialog/confirm-dialog' target='_blank'>Check the demo</a>
  | 
 <a href='https://github.com/qor5/docs/tree/main/docsrc/examples/example_basics/confirm-dialog.go' target='_blank'>Source on GitHub</a>
 </div>

+ 4 - 0
docs/basics/event-handling.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/filter.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/form-handling.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/layout-function-and-page-injector.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/listing.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/manipulate-page-url-in-event-func.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/menu.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/notification-center.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/page-func-and-event-func.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/partial-refresh-with-portal.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/reload-page-with-a-flash.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/scope-component.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/shortcut.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/summary-of-event-response.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/basics/switch-pages-with-push-state.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

Datei-Diff unterdrückt, da er zu groß ist
+ 223 - 0
docs/basics/worker.html


+ 4 - 0
docs/components-guide/composite-new-component-with-go.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/components-guide/integrate-a-heavy-vue-component.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/getting-started/one-minute-quick-start.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 5 - 1
docs/index.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>
@@ -197,7 +201,7 @@
 <div id='docMainBox' class='px-16 pb-12 pt-4 overflow-auto'>
 <h1 class='mb-8'>Introduction</h1>
 
-<div class='border-t'><p>QOR5 is yet another Go library to build web applications. We aim to accelerate the development speed and make the website highly customizable.</p>
+<div class='border-t'><p>QOR5 is a Go library to build web applications. We aim to accelerate the development speed and make the website highly customizable.</p>
 
 <ul>
 <li>It prefers writing HTML in <a href="/advanced-functions/the-go-html-builder.html" rel="nofollow">static typing Go language</a>, rather than a certain type of template language, Not even go template.</li>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
docs/index.js


+ 4 - 0
docs/presets-guide/detail-page-for-complex-object.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/presets-guide/editing-customizations.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/presets-guide/its-the-whole-house.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/presets-guide/permissions.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/presets-guide/role.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
docs/search_indexes.json


+ 4 - 0
docs/seo.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/slug.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/vuetify-components/a-taste-of-using-vuetify-in-go.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/vuetify-components/auto-complete.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/vuetify-components/basic-inputs.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/vuetify-components/lazy-portals.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 4 - 0
docs/vuetify-components/linkage-select.html

@@ -90,6 +90,10 @@
 <a href='activity-log.html' id='activity-log.html' onclick='window.storeMenuState("activity-log.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Activity Log</a>
 </li>
 
+<li class='m-0'>
+<a href='basics/worker.html' id='basics/worker.html' onclick='window.storeMenuState("basics/worker.html")' class='inline-block pl-10 pr-4 py-1 truncate break-words w-64 hover:text-blue-400 text-gray-700'>Worker</a>
+</li>
+
 <li class='cursor-default px-4 py-1 truncate break-words w-64 m-0'>Web Application</li>
 
 <li class='m-0'>

+ 48 - 0
docsrc/content/basics/worker.go

@@ -0,0 +1,48 @@
+package basics
+
+import (
+	"fmt"
+	"path"
+
+	"github.com/qor5/docs/docsrc/examples/example_basics"
+	"github.com/qor5/docs/docsrc/generated"
+	"github.com/qor5/docs/docsrc/utils"
+	. "github.com/theplant/docgo"
+	"github.com/theplant/docgo/ch"
+)
+
+var Worker = Doc(
+	Markdown(fmt.Sprintf(`
+Worker runs a single Job in the background, it can do so immediately or at a scheduled time.  
+Once registered with QOR Admin, Worker will provide a Workers section in the navigation tree, containing pages for listing and managing the following aspects of Workers:
+
+- All Jobs.
+- Running: Jobs that are currently running.
+- Scheduled: Jobs which have been scheduled to run at a time in the future.
+- Done: finished Jobs.
+- Errors: any errors output from any Workers that have been run.
+
+## Note
+- The default que GoQueQueue(https://github.com/tnclong/go-que) only supports postgres for now.
+- To make a job abortable, you need to check %s channel in job handler and stop the handler func.
+    `, "`ctx.Done()`")),
+	Markdown(`
+## Example
+`),
+	ch.Code(generated.WorkerExample).Language("go"),
+	utils.Demo(
+		"Worker",
+		path.Join(example_basics.WorkerExamplePath, "/workers"),
+		"example_basics/worker.go",
+	),
+	Markdown(`
+## Action Worker
+Action Worker is used to visualize the progress of long-running actions.
+    `),
+	ch.Code(generated.ActionWorkerExample).Language("go"),
+	utils.Demo(
+		"Action Worker",
+		path.Join(example_basics.ActionWorkerExamplePath, "/example-resources"),
+		"example_basics/action_worker.go",
+	),
+).Slug("basics/worker").Title("Worker")

+ 1 - 1
docsrc/content/getting-started/what-is-goplaid.go

@@ -11,7 +11,7 @@ import (
 
 var WhatIsQOR5 = Doc(
 	Markdown(`
-QOR5 is yet another Go library to build web applications.
+QOR5 is a Go library to build web applications.
 different from other MVC frameworks. the concepts in QOR5 is **Page**, **Event**, **Component**.
 and doesn't include Model.
 

+ 1 - 1
docsrc/content/home.go

@@ -8,7 +8,7 @@ import (
 
 var Home = Doc(
 	Markdown(`
-QOR5 is yet another Go library to build web applications. We aim to accelerate the development speed and make the website highly customizable.
+QOR5 is a Go library to build web applications. We aim to accelerate the development speed and make the website highly customizable.
 
 - It prefers writing HTML in [static typing Go language](/advanced-functions/the-go-html-builder.html), rather than a certain type of template language, Not even go template.
 - It try to minify the needs to write any JavaScript/Typescript for building interactive web applications

+ 1 - 0
docsrc/doc_tree.go

@@ -41,6 +41,7 @@ var DocTree = []interface{}{
 			basics.Slug,
 			basics.SEO,
 			basics.Activity,
+			basics.Worker,
 		},
 	},
 

+ 162 - 0
docsrc/examples/example_basics/action_worker.go

@@ -0,0 +1,162 @@
+package example_basics
+
+// @snippet_begin(ActionWorkerExample)
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"github.com/qor5/admin/presets"
+	"github.com/qor5/admin/worker"
+	"github.com/qor5/ui/vuetify"
+	"github.com/qor5/web"
+	h "github.com/theplant/htmlgo"
+	"gorm.io/gorm"
+)
+
+type ExampleResource struct {
+	gorm.Model
+	Name string
+}
+
+func MountActionWorker(b *presets.Builder) {
+	mb := b.Model(&ExampleResource{})
+	mb.Listing().ActionsAsMenu(true)
+
+	wb := worker.New(DB)
+	wb.Configure(b)
+	defer wb.Listen()
+
+	addActionJobs(mb, wb)
+}
+
+func addActionJobs(mb *presets.ModelBuilder, wb *worker.Builder) {
+	lb := mb.Listing()
+
+	noParametersJob := wb.ActionJob(
+		"No parameters",
+		mb,
+		func(ctx context.Context, job worker.QorJobInterface) error {
+			for i := 1; i <= 10; i++ {
+				select {
+				case <-ctx.Done():
+					job.AddLog("job aborted")
+					return nil
+				default:
+					job.SetProgress(uint(i * 10))
+					time.Sleep(time.Second)
+				}
+			}
+			job.SetProgressText(`<a href="https://qor5-test.s3.ap-northeast-1.amazonaws.com/system/media_libraries/37/file.@qor_preview.png">Please download this file</a>`)
+			return nil
+		},
+	).Description("This test demo is used to show that an no parameter job can be executed")
+
+	parametersBoxJob := wb.ActionJob(
+		"Parameter input box",
+		mb,
+		func(ctx context.Context, job worker.QorJobInterface) error {
+			for i := 1; i <= 10; i++ {
+				select {
+				case <-ctx.Done():
+					job.AddLog("job aborted")
+					return nil
+				default:
+					job.SetProgress(uint(i * 10))
+					time.Sleep(time.Second)
+				}
+			}
+			job.SetProgressText(`<a href="https://qor5-test.s3.ap-northeast-1.amazonaws.com/system/media_libraries/37/file.@qor_preview.png">Please download this file</a>`)
+			return nil
+		},
+	).Description("This test demo is used to show that an input box when there are parameters").
+		Params(&struct{ Name string }{})
+
+	displayLogJob := wb.ActionJob(
+		"Display log",
+		mb,
+		func(ctx context.Context, job worker.QorJobInterface) error {
+			for i := 1; i <= 10; i++ {
+				select {
+				case <-ctx.Done():
+					job.AddLog("job aborted")
+					return nil
+				default:
+					job.SetProgress(uint(i * 10))
+					job.AddLog(fmt.Sprintf("%v", i))
+					time.Sleep(time.Second)
+				}
+			}
+			job.SetProgressText(`<a href="https://qor5-test.s3.ap-northeast-1.amazonaws.com/system/media_libraries/37/file.@qor_preview.png">Please download this file</a>`)
+			return nil
+		},
+	).Description("This test demo is used to show the log section of this job").
+		Params(&struct{ Name string }{}).
+		DisplayLog(true).
+		ProgressingInterval(4000)
+
+	getArgsJob := wb.ActionJob(
+		"Get Args",
+		mb,
+		func(ctx context.Context, job worker.QorJobInterface) error {
+			jobInfo, err := job.GetJobInfo()
+			if err != nil {
+				return err
+			}
+
+			job.AddLog(fmt.Sprintf("Action Params Name is  %#+v", jobInfo.Argument.(*struct{ Name string }).Name))
+			job.AddLog(fmt.Sprintf("Origina Context AuthInfo is  %#+v", jobInfo.Context["AuthInfo"]))
+			job.AddLog(fmt.Sprintf("Origina Context URL is  %#+v", jobInfo.Context["URL"]))
+
+			for i := 1; i <= 10; i++ {
+				select {
+				case <-ctx.Done():
+					return nil
+				default:
+					job.SetProgress(uint(i * 10))
+					time.Sleep(time.Second)
+				}
+			}
+			job.SetProgressText(`<a href="https://qor5-test.s3.ap-northeast-1.amazonaws.com/system/media_libraries/37/file.@qor_preview.png">Please download this file</a>`)
+			return nil
+		},
+	).Description("This test demo is used to show how to get the action's arguments and original page context").
+		Params(&struct{ Name string }{}).
+		DisplayLog(true).
+		ContextHandler(func(ctx *web.EventContext) map[string]interface{} {
+			auth, err := ctx.R.Cookie("auth")
+			if err == nil {
+				return map[string]interface{}{"AuthInfo": auth.Value}
+			}
+			return nil
+		})
+
+	lb.Action("Action Job - No parameters").
+		ButtonCompFunc(
+			func(ctx *web.EventContext) h.HTMLComponent {
+				return vuetify.VBtn("Action Job - No parameters").Color("secondary").Depressed(true).Class("ml-2").
+					Attr("@click", noParametersJob.URL())
+			})
+
+	lb.Action("Action Job - Parameter input box").
+		ButtonCompFunc(
+			func(ctx *web.EventContext) h.HTMLComponent {
+				return vuetify.VBtn("Action Job - Parameter input box").Color("secondary").Depressed(true).Class("ml-2").
+					Attr("@click", parametersBoxJob.URL())
+			})
+	lb.Action("Action Job - Display log").
+		ButtonCompFunc(
+			func(ctx *web.EventContext) h.HTMLComponent {
+				return vuetify.VBtn("Action Job - Display log").Color("secondary").Depressed(true).Class("ml-2").
+					Attr("@click", displayLogJob.URL())
+			})
+
+	lb.Action("Action Job - Get Args").
+		ButtonCompFunc(
+			func(ctx *web.EventContext) h.HTMLComponent {
+				return vuetify.VBtn("Action Job - Get Args").Color("secondary").Depressed(true).Class("ml-2").
+					Attr("@click", getArgsJob.URL())
+			})
+}
+
+// @snippet_end

+ 26 - 0
docsrc/examples/example_basics/action_worker_mock_que.go

@@ -0,0 +1,26 @@
+package example_basics
+
+import (
+	"github.com/qor5/admin/presets"
+	"github.com/qor5/admin/presets/gorm2op"
+	"github.com/qor5/admin/worker"
+)
+
+func ActionWorkerExampleMock(b *presets.Builder) {
+	if err := DB.AutoMigrate(&ExampleResource{}); err != nil {
+		panic(err)
+	}
+
+	b.URIPrefix(ActionWorkerExamplePath).
+		DataOperator(gorm2op.DataOperator(DB))
+
+	mb := b.Model(&ExampleResource{})
+	mb.Listing().ActionsAsMenu(true)
+
+	wb := worker.NewWithQueue(DB, Que)
+	wb.Configure(b)
+	addActionJobs(mb, wb)
+	wb.Listen()
+}
+
+const ActionWorkerExamplePath = "/samples/action_worker"

+ 1 - 1
docsrc/examples/example_basics/confirm-dialog.go

@@ -51,4 +51,4 @@ func PresetsConfirmDialog(b *presets.Builder) {
 	})
 }
 
-const PresetsConfirmDialogPath = "/samples"
+const PresetsConfirmDialogPath = "/samples/confirm_dialog"

+ 98 - 0
docsrc/examples/example_basics/worker.go

@@ -0,0 +1,98 @@
+package example_basics
+
+// @snippet_begin(WorkerExample)
+import (
+	"context"
+	"errors"
+	"fmt"
+	"time"
+
+	"github.com/qor5/admin/presets"
+	"github.com/qor5/admin/worker"
+)
+
+func MountWorker(b *presets.Builder) {
+	wb := worker.New(DB)
+	wb.Configure(b)
+	defer wb.Listen()
+
+	addJobs(wb)
+}
+
+func addJobs(w *worker.Builder) {
+	w.NewJob("noArgJob").
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			job.AddLog("hoho1")
+			job.AddLog("hoho2")
+			job.AddLog("hoho3")
+			return nil
+		})
+
+	type ArgJobResource struct {
+		F1 string
+		F2 int
+		F3 bool
+	}
+	argJb := w.NewJob("argJob").
+		Resource(&ArgJobResource{}).
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			jobInfo, _ := job.GetJobInfo()
+			job.AddLog(fmt.Sprintf("Argument %#+v", jobInfo.Argument))
+			return nil
+		})
+	// you can to customize the resource Editing via GetResourceBuilder()
+	argJb.GetResourceBuilder().Editing()
+
+	w.NewJob("progressTextJob").
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			job.AddLog("hoho1")
+			job.AddLog("hoho2")
+			job.AddLog("hoho3")
+			job.SetProgressText(`<a href="https://www.google.com">Download users</a>`)
+			return nil
+		})
+
+	// check ctx.Done() to stop the handler
+	w.NewJob("longRunningJob").
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			for i := 1; i <= 5; i++ {
+				select {
+				case <-ctx.Done():
+					job.AddLog("job aborted")
+					return nil
+				default:
+					job.AddLog(fmt.Sprintf("%v", i))
+					job.SetProgress(uint(i * 20))
+					time.Sleep(time.Second)
+				}
+			}
+			return nil
+		})
+
+	// insert worker.Schedule to resource to make a job schedulable
+	type ScheduleJobResource struct {
+		F1 string
+		worker.Schedule
+	}
+	w.NewJob("scheduleJob").
+		Resource(&ScheduleJobResource{}).
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			jobInfo, _ := job.GetJobInfo()
+			job.AddLog(fmt.Sprintf("%#+v", jobInfo.Argument))
+			return nil
+		})
+
+	w.NewJob("errorJob").
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			job.AddLog("=====perform error job")
+			return errors.New("imError")
+		})
+
+	w.NewJob("panicJob").
+		Handler(func(ctx context.Context, job worker.QorJobInterface) error {
+			job.AddLog("=====perform panic job")
+			panic("letsPanic")
+		})
+}
+
+// @snippet_end

+ 122 - 0
docsrc/examples/example_basics/worker_mock_que.go

@@ -0,0 +1,122 @@
+package example_basics
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"runtime/debug"
+	"time"
+
+	"github.com/qor5/admin/presets"
+	"github.com/qor5/admin/presets/gorm2op"
+	"github.com/qor5/admin/worker"
+	"github.com/qor5/admin/worker/mock"
+)
+
+func WorkerExampleMock(b *presets.Builder) {
+	b.URIPrefix(WorkerExamplePath).
+		DataOperator(gorm2op.DataOperator(DB))
+
+	wb := worker.NewWithQueue(DB, Que)
+	wb.Configure(b)
+	addJobs(wb)
+	wb.Listen()
+}
+
+const WorkerExamplePath = "/samples/worker"
+
+var Que = &mock.QueueMock{
+	AddFunc: func(job worker.QueJobInterface) error {
+		jobInfo, err := job.GetJobInfo()
+
+		if err != nil {
+			return err
+		}
+		if scheduler, ok := jobInfo.Argument.(worker.Scheduler); ok && scheduler.GetScheduleTime() != nil {
+			job.SetStatus(worker.JobStatusScheduled)
+			go func() {
+				time.Sleep(scheduler.GetScheduleTime().Sub(time.Now()))
+				ConsumeQueItem(job)
+			}()
+		} else {
+			go func() {
+				ConsumeQueItem(job)
+			}()
+		}
+		return nil
+	},
+	KillFunc: func(job worker.QueJobInterface) error {
+		return job.SetStatus(worker.JobStatusKilled)
+	},
+	ListenFunc: func(jobDefs []*worker.QorJobDefinition, getJob func(qorJobID uint) (worker.QueJobInterface, error)) error {
+		return nil
+	},
+	RemoveFunc: func(job worker.QueJobInterface) error {
+		return job.SetStatus(worker.JobStatusCancelled)
+	},
+}
+
+func ConsumeQueItem(job worker.QueJobInterface) (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			job.AddLog(string(debug.Stack()))
+			job.SetProgressText(fmt.Sprint(r))
+			job.SetStatus(worker.JobStatusException)
+			job.StopRefresh()
+		}
+	}()
+
+	if job.GetStatus() == worker.JobStatusCancelled {
+		return
+	}
+	if job.GetStatus() != worker.JobStatusNew && job.GetStatus() != worker.JobStatusScheduled {
+		job.SetStatus(worker.JobStatusKilled)
+		return errors.New("invalid job status, current status: " + job.GetStatus())
+	}
+
+	err = job.SetStatus(worker.JobStatusRunning)
+	if err != nil {
+		return err
+	}
+	time.Sleep(100 * time.Millisecond)
+
+	hctx, cf := context.WithCancel(context.Background())
+	hDoneC := make(chan struct{})
+	isAborted := false
+	go func() {
+		timer := time.NewTicker(time.Second)
+		for {
+			select {
+			case <-hDoneC:
+				return
+			case <-timer.C:
+				status, _ := job.FetchAndSetStatus()
+				if status == worker.JobStatusKilled {
+					isAborted = true
+					cf()
+					return
+				}
+			}
+		}
+	}()
+	job.StartRefresh()
+	err = job.GetHandler()(hctx, job)
+	job.StopRefresh()
+	if !isAborted {
+		hDoneC <- struct{}{}
+	}
+	if err != nil {
+		job.SetProgressText(err.Error())
+		job.SetStatus(worker.JobStatusException)
+		return err
+	}
+	if isAborted {
+		return
+	}
+
+	err = job.SetStatus(worker.JobStatusDone)
+	if err != nil {
+		return err
+	}
+	return
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
docsrc/generated/examples-generated.go


+ 14 - 0
docsrc/mux.go

@@ -718,5 +718,19 @@ func SamplesHandler(prefix string) http.Handler {
 		c22,
 	)
 
+	c23 := presets.New().AssetFunc(addGA)
+	example_basics.WorkerExampleMock(c23)
+	mux.Handle(
+		example_basics.WorkerExamplePath+"/",
+		c23,
+	)
+
+	c24 := presets.New().AssetFunc(addGA)
+	example_basics.ActionWorkerExampleMock(c24)
+	mux.Handle(
+		example_basics.ActionWorkerExamplePath+"/",
+		c24,
+	)
+
 	return mux
 }

+ 11 - 7
go.mod

@@ -7,17 +7,18 @@ require (
 	github.com/fatih/color v1.13.0
 	github.com/go-chi/chi v1.5.4
 	github.com/manifoldco/promptui v0.9.0
+	github.com/ory/ladon v1.2.0
 	github.com/qor/oss v0.0.0-20210412121326-3c5583a62015
 	github.com/qor5/admin v0.0.0-20230309055501-c8d08dc6944b
 	github.com/qor5/ui v1.0.1-0.20221212071205-e794612c1e84
-	github.com/qor5/web v1.2.4-0.20221109035751-adf9bf246c1e
+	github.com/qor5/web v1.2.4
 	github.com/qor5/x v1.2.1-0.20230308023320-5dd0a2f09c49
 	github.com/shurcooL/sanitized_anchor_name v1.0.0
 	github.com/sunfmin/reflectutils v1.0.3
 	github.com/theplant/docgo v0.0.15
 	github.com/theplant/htmlgo v1.0.3
 	github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4
-	golang.org/x/text v0.6.0
+	golang.org/x/text v0.8.0
 	gorm.io/driver/postgres v1.4.5
 	gorm.io/driver/sqlite v1.4.3
 	gorm.io/gorm v1.24.2
@@ -60,8 +61,7 @@ require (
 	github.com/mattn/go-colorable v0.1.9 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/mattn/go-sqlite3 v1.14.16 // indirect
-	github.com/microcosm-cc/bluemonday v1.0.21 // indirect
-	github.com/ory/ladon v1.2.0 // indirect
+	github.com/microcosm-cc/bluemonday v1.0.23 // indirect
 	github.com/ory/pagination v0.0.1 // indirect
 	github.com/pborman/uuid v1.2.1 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -81,16 +81,20 @@ require (
 	github.com/stretchr/testify v1.8.1 // indirect
 	github.com/theplant/sliceutils v0.0.0-20200406042209-89153d988eb1 // indirect
 	github.com/thoas/go-funk v0.9.2 // indirect
+	github.com/tnclong/go-que v0.0.0-20201111043106-1fc5fa2b9761 // indirect
 	go.uber.org/atomic v1.10.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
 	goji.io v2.0.2+incompatible // indirect
 	golang.org/x/crypto v0.5.0 // indirect
-	golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 // indirect
-	golang.org/x/net v0.5.0 // indirect
+	golang.org/x/image v0.6.0 // indirect
+	golang.org/x/net v0.8.0 // indirect
 	golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
-	golang.org/x/sys v0.4.0 // indirect
+	golang.org/x/sys v0.6.0 // indirect
+	golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
 	google.golang.org/appengine v1.6.6 // indirect
 	google.golang.org/protobuf v1.26.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
+
+// replace github.com/qor5/web => ../web

+ 40 - 32
go.sum

@@ -253,14 +253,14 @@ github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
 github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
 github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
 github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
-github.com/markbates/goth v1.75.1 h1:x+0vP1GBBj+Si6ChLTMW1sF7FDn8myLVJYMoS+9+cHk=
-github.com/markbates/goth v1.75.1/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc=
+github.com/markbates/goth v1.76.0 h1:lXLpETvTJWYKnfbd9tHK/GfLFsc3ihVB8KGjfDTyIEQ=
 github.com/markbates/goth v1.76.0/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc=
 github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -274,8 +274,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
 github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
 github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
-github.com/microcosm-cc/bluemonday v1.0.21 h1:dNH3e4PSyE4vNX+KlRGHT5KrSvjeUkoNPwEORjffHJg=
-github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM=
+github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY=
+github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4=
 github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
 github.com/ory/ladon v1.2.0 h1:efIVtNkObNR/HL7nR5y17Lrw9c/wMwe56iKVDcRv3GY=
 github.com/ory/ladon v1.2.0/go.mod h1:25bNc/Glx/8xCH7MbItDxjvviAmFQ+aYxb1V1SE5wlg=
@@ -295,27 +295,17 @@ github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/qor/oss v0.0.0-20210412121326-3c5583a62015 h1:gmzorMEb+tKC8wkYBsIO9z+tpul0nWyIyKErqj9GG2o=
 github.com/qor/oss v0.0.0-20210412121326-3c5583a62015/go.mod h1:JhtPzUhP5KGtCB2yksmxuYAD4hEWw4qGQJpucjsm3U0=
-github.com/qor5/admin v0.0.0-20221128020357-adb551f97fa2 h1:075GoxMrB2/VY6pYRAPLTK1XAVuD/Vh9GLbd8bFBXto=
-github.com/qor5/admin v0.0.0-20221128020357-adb551f97fa2/go.mod h1:uymLUBdFzCae2QFwN+MW/4gnJDhKSqqhuID+fVkmkyY=
-github.com/qor5/admin v0.0.0-20230222060239-323b09795d83 h1:ys1C3onPFAZRZoL/l+TQTIwhT9VvQZoPIZp/duge85s=
-github.com/qor5/admin v0.0.0-20230222060239-323b09795d83/go.mod h1:UhmKyOUDo/2iNxVu2y9+8IGSgLj9HvxTfSsSC/VkgnM=
-github.com/qor5/admin v0.0.0-20230224100402-af6e5e15c108 h1:PwvBGGV6JXMvRhRKr2XcTZ+CweYzlQ79gzoAIzU3IPE=
-github.com/qor5/admin v0.0.0-20230224100402-af6e5e15c108/go.mod h1:UhmKyOUDo/2iNxVu2y9+8IGSgLj9HvxTfSsSC/VkgnM=
-github.com/qor5/admin v0.0.0-20230227013111-715f9fd3421a h1:nL6kJnmkmNc3Ryw3tPShuiVReN/B9XMGGHUjeqZKcGQ=
-github.com/qor5/admin v0.0.0-20230227013111-715f9fd3421a/go.mod h1:UhmKyOUDo/2iNxVu2y9+8IGSgLj9HvxTfSsSC/VkgnM=
 github.com/qor5/admin v0.0.0-20230309055501-c8d08dc6944b h1:j9wGiuweDoSAVxBH/+zAKS3wrkijmVWODnvpCIKnYJE=
 github.com/qor5/admin v0.0.0-20230309055501-c8d08dc6944b/go.mod h1:cTtdZJvUGLNTGFfe53xT1H5noFgawFbfHsBLJyKEZYs=
-github.com/qor5/ui v1.0.0 h1:9npS/FvnlR2j7Z8uGW69511oLbHad+LOLDNob7jJj2Y=
-github.com/qor5/ui v1.0.0/go.mod h1:bgBqjIytHRdfTsiZea8df/ltAcyQyuHiLbecgo8Iwgw=
+github.com/qor5/ui v1.0.1-0.20221212071205-e794612c1e84 h1:4Zueo+/c3cBDSE89CuPcHFRPPIo4UrWbCEc+amCGy84=
 github.com/qor5/ui v1.0.1-0.20221212071205-e794612c1e84/go.mod h1:bgBqjIytHRdfTsiZea8df/ltAcyQyuHiLbecgo8Iwgw=
-github.com/qor5/web v1.2.4-0.20221109035751-adf9bf246c1e h1:hBK89VZV9+Xtan053WjT2SHANQm6Y2OHYvRCG12YqYM=
-github.com/qor5/web v1.2.4-0.20221109035751-adf9bf246c1e/go.mod h1:gwAoUC1cQ9y5Vm3zZmWTq9t1iLOrQH+sIvJUpG6V61w=
-github.com/qor5/x v1.2.1-0.20221109065533-3e5f9b440cb3 h1:4W5ix5ep3JJQSJwBMjyXLskaOHUy2vfd1aPDt4xtVU0=
-github.com/qor5/x v1.2.1-0.20221109065533-3e5f9b440cb3/go.mod h1:pqE7TSENrUKHlwzDSdaww0pk3E9X1ffoqAfCHzoZrJk=
-github.com/qor5/x v1.2.1-0.20230215023713-a028537191cc/go.mod h1:pqE7TSENrUKHlwzDSdaww0pk3E9X1ffoqAfCHzoZrJk=
+github.com/qor5/web v1.2.4 h1:CsChErtiYgaMA7CkqkC7nP2YEAOjDZ7JNrrUJTYGNLc=
+github.com/qor5/web v1.2.4/go.mod h1:4VXydGmy5Uwz8rEeKjcmCetciJo8TpU0mnN7Ca5kMR0=
+github.com/qor5/x v1.2.1-0.20230308023320-5dd0a2f09c49 h1:IAh1ichaQ6X9jpds5qdxjPUZ/IcchPeidsuF58M/ycA=
 github.com/qor5/x v1.2.1-0.20230308023320-5dd0a2f09c49/go.mod h1:pqE7TSENrUKHlwzDSdaww0pk3E9X1ffoqAfCHzoZrJk=
 github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
 github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
+github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
@@ -379,12 +369,15 @@ github.com/theplant/sliceutils v0.0.0-20200406042209-89153d988eb1/go.mod h1:+y97
 github.com/theplant/testingutils v0.0.0-20220314083015-b74d1aa8ac8a h1:dF00sJtP57ZEVpkR5Wu0dtpz9Iw94xO6XBHUwTJr0hQ=
 github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk=
 github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
+github.com/tnclong/go-que v0.0.0-20201111043106-1fc5fa2b9761 h1:CsN/I4kTJIs/mx1MHt9H9I9ttYxILxMEgCYPkqaBWp8=
+github.com/tnclong/go-que v0.0.0-20201111043106-1fc5fa2b9761/go.mod h1:j+L/Ih47BU2nmiEW1m5zS2gjxB6xqGyxzHfdXLg/3Ho=
 github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts=
 github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@@ -422,10 +415,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
-golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
 golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -440,9 +433,10 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
-golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
 golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
+golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4=
+golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -461,6 +455,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -493,9 +489,10 @@ golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -511,6 +508,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -551,11 +550,15 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -564,12 +567,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
+golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -617,6 +622,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
 golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
 golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -716,6 +723,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

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