zrb 0.0.51__py3-none-any.whl → 0.0.53__py3-none-any.whl

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.
Files changed (90) hide show
  1. zrb/builtin/generator/fastapp/add.py +3 -2
  2. zrb/builtin/generator/fastapp/template/_automate/snake_app_name/cmd/start.sh +1 -1
  3. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/.gitignore +1 -0
  4. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/config.py +14 -5
  5. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/.env.local +4 -0
  6. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/.gitignore +1 -1
  7. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/README.md +0 -0
  8. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/package-lock.json +22 -0
  9. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/package.json +3 -0
  10. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/playwright.config.ts +0 -0
  11. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/postcss.config.js +0 -0
  12. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/app.css +0 -0
  13. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/app.d.ts +0 -0
  14. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/app.html +0 -0
  15. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/index.test.ts +0 -0
  16. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/helper.ts +146 -0
  17. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/store.ts +4 -0
  18. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/type.ts +10 -0
  19. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/Menu.svelte +19 -17
  20. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/Navigation.svelte +64 -7
  21. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/helper.ts +18 -0
  22. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/type.ts +0 -0
  23. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/app.ts +9 -0
  24. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/navData.ts +6 -17
  25. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/error/helper.ts +12 -0
  26. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+error.svelte +8 -0
  27. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+layout.js +0 -0
  28. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+layout.svelte +6 -5
  29. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+page.svelte +2 -8
  30. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/static/favicon.png +0 -0
  31. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/static/logo.png +0 -0
  32. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/svelte.config.js +0 -0
  33. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/tailwind.config.js +0 -0
  34. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/tests/test.ts +0 -0
  35. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/tsconfig.json +0 -0
  36. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/vite.config.ts +0 -0
  37. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/__init__.py +8 -4
  38. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/access_token_scheme.py +14 -0
  39. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/access_token_util.py +17 -0
  40. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/bearer_token_scheme.py +5 -0
  41. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/model/user_model.py +9 -4
  42. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/refresh_token_util.py +17 -0
  43. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/__init__.py +14 -9
  44. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/{token_scheme/oauth2_bearer_token_scheme.py → access_token/scheme.py} +11 -11
  45. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/access_token/util.py +69 -0
  46. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/authorizer/rpc_authorizer.py +4 -2
  47. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/{token_util/jwt_token_util.py → refresh_token/util.py} +18 -6
  48. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/group/api.py +9 -7
  49. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/group/rpc.py +4 -4
  50. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/permission/api.py +9 -7
  51. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/permission/rpc.py +4 -4
  52. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/api.py +27 -16
  53. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/model.py +44 -19
  54. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/rpc.py +19 -11
  55. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/schema/request.py +10 -0
  56. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/schema/token.py +7 -1
  57. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/requirements.txt +1 -0
  58. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/template.env +7 -3
  59. zrb/builtin/generator/fastapp_crud/add.py +7 -21
  60. zrb/builtin/generator/fastapp_crud/add_navigation.py +32 -0
  61. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/+page.svelte +121 -0
  62. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/delete/[id]/+page.svelte +75 -0
  63. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/delete/[id]/+page.ts +5 -0
  64. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/detail/[id]/+page.svelte +54 -0
  65. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/detail/[id]/+page.ts +5 -0
  66. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/new/+page.svelte +52 -0
  67. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/update/[id]/+page.svelte +78 -0
  68. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/frontend/src/routes/kebab-module-name/kebab-entity-name/update/[id]/+page.ts +5 -0
  69. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/module/snake_module_name/entity/snake_entity_name/api.py +9 -7
  70. zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/src/module/snake_module_name/entity/snake_entity_name/rpc.py +4 -4
  71. zrb/builtin/generator/fastapp_field/add.py +203 -4
  72. zrb/helper/util.py +4 -0
  73. zrb/task/resource_maker.py +2 -1
  74. {zrb-0.0.51.dist-info → zrb-0.0.53.dist-info}/METADATA +6 -5
  75. {zrb-0.0.51.dist-info → zrb-0.0.53.dist-info}/RECORD +66 -52
  76. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/config.ts +0 -4
  77. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/about/+page.svelte +0 -2
  78. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/greetings/[slug]/+page.js +0 -6
  79. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/greetings/[slug]/+page.svelte +0 -5
  80. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/sample/+page.svelte +0 -37
  81. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/sample/delete/[id]/+page.svelte +0 -1
  82. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/token_scheme.py +0 -11
  83. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/token_util.py +0 -17
  84. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/token_scheme/token_sheme.py +0 -5
  85. zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/token_util/token_util.py +0 -13
  86. /zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/{token_scheme/__init__.py → access_token/_init_.py} +0 -0
  87. /zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/{token_util/__init__.py → refresh_token/_init_.py} +0 -0
  88. {zrb-0.0.51.dist-info → zrb-0.0.53.dist-info}/LICENSE +0 -0
  89. {zrb-0.0.51.dist-info → zrb-0.0.53.dist-info}/WHEEL +0 -0
  90. {zrb-0.0.51.dist-info → zrb-0.0.53.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,78 @@
1
+ <script lang="ts">
2
+ import axios from 'axios';
3
+ import { onMount } from 'svelte';
4
+ import { goto } from '$app/navigation';
5
+ import { ensureAccessToken } from '$lib/auth/helper';
6
+ import { getErrorMessage } from '$lib/error/helper';
7
+
8
+ export let data: {id?: string} = {};
9
+
10
+ let row: any = {}
11
+ let isAlertVisible: boolean = false;
12
+ let isSaving: boolean = false;
13
+ let errorMessage: string = '';
14
+
15
+ onMount(async() => {
16
+ await loadRow();
17
+ });
18
+
19
+ async function loadRow() {
20
+ const accessToken = await ensureAccessToken();
21
+ try {
22
+ const response = await axios.get(
23
+ `/api/v1/kebab-module-name/kebab-plural-entity-name/${data.id}`,
24
+ {headers: {Authorization: `Bearer ${accessToken}`}}
25
+ );
26
+ if (response?.status == 200 && response?.data) {
27
+ row = response.data;
28
+ return;
29
+ }
30
+ errorMessage = 'Unknown error';
31
+ } catch(error) {
32
+ console.error(error);
33
+ errorMessage = getErrorMessage(error);
34
+ }
35
+ isAlertVisible = true;
36
+ }
37
+
38
+ async function onSaveClick() {
39
+ isSaving = true
40
+ const accessToken = await ensureAccessToken();
41
+ try {
42
+ const response = await axios.put(
43
+ `/api/v1/kebab-module-name/kebab-plural-entity-name/${data.id}`, row, {headers: {Authorization: `Bearer ${accessToken}`}}
44
+ );
45
+ if (response?.status == 200) {
46
+ await goto('../../');
47
+ return;
48
+ }
49
+ errorMessage = 'Unknown error';
50
+ } catch(error) {
51
+ console.error(error);
52
+ errorMessage = getErrorMessage(error);
53
+ }
54
+ isAlertVisible = true;
55
+ isSaving = false;
56
+ }
57
+ </script>
58
+
59
+ <h1 class="text-3xl">Book</h1>
60
+
61
+ <form class="max-w-md mx-auto bg-gray-100 p-6 rounded-md mt-5 mb-5">
62
+ <h2 class="text-xl font-bold mb-4">Update Book</h2>
63
+ <div class="mb-4">
64
+ <label class="block text-gray-700 font-bold mb-2" for="kebab-column-name">Human readable column name</label>
65
+ <input type="text" class="input w-full" id="kebab-column-name" placeholder="Human readable column name" bind:value={row.snake_column_name}>
66
+ </div>
67
+ <!-- DON'T DELETE: insert new field here-->
68
+ <a href="#top" class="btn btn-primary {isSaving ? 'btn-disabled': '' }" on:click={onSaveClick}>Save</a>
69
+ <a href="../../" class="btn">Cancel</a>
70
+
71
+ <div class="alert alert-error shadow-lg mt-5 {isAlertVisible? 'visible': 'hidden'}">
72
+ <div>
73
+ <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
74
+ <span>{errorMessage}</span>
75
+ </div>
76
+ </div>
77
+
78
+ </form>
@@ -0,0 +1,5 @@
1
+ export async function load({ params }) {
2
+ return {
3
+ id: params?.id
4
+ };
5
+ }
@@ -7,8 +7,8 @@ from module.auth.core import Authorizer
7
7
  from module.snake_module_name.schema.snake_entity_name import (
8
8
  PascalEntityName, PascalEntityNameData, PascalEntityNameResult
9
9
  )
10
- from module.auth.schema.token import TokenData
11
- from module.auth.component import token_scheme
10
+ from module.auth.schema.token import AccessTokenData
11
+ from module.auth.component import access_token_scheme
12
12
 
13
13
 
14
14
  def register_api(
@@ -25,7 +25,7 @@ def register_api(
25
25
  )
26
26
  async def get_snake_entity_names(
27
27
  keyword: str = '', limit: int = 100, offset: int = 0,
28
- user_token_data: TokenData = Depends(token_scheme)
28
+ user_token_data: AccessTokenData = Depends(access_token_scheme)
29
29
  ):
30
30
  if not await authorizer.is_having_permission(
31
31
  user_token_data.user_id, 'snake_module_name:snake_entity_name:get'
@@ -48,7 +48,8 @@ def register_api(
48
48
  '/api/v1/kebab-module-name/kebab-plural-entity-name/{id}', response_model=PascalEntityName
49
49
  )
50
50
  async def get_snake_entity_name_by_id(
51
- id: str, user_token_data: TokenData = Depends(token_scheme)
51
+ id: str,
52
+ user_token_data: AccessTokenData = Depends(access_token_scheme)
52
53
  ):
53
54
  if not await authorizer.is_having_permission(
54
55
  user_token_data.user_id, 'snake_module_name:snake_entity_name:get_by_id'
@@ -68,7 +69,7 @@ def register_api(
68
69
  )
69
70
  async def insert_snake_entity_name(
70
71
  data: PascalEntityNameData,
71
- user_token_data: TokenData = Depends(token_scheme)
72
+ user_token_data: AccessTokenData = Depends(access_token_scheme)
72
73
  ):
73
74
  if not await authorizer.is_having_permission(
74
75
  user_token_data.user_id, 'snake_module_name:snake_entity_name:insert'
@@ -88,7 +89,7 @@ def register_api(
88
89
  )
89
90
  async def update_snake_entity_name(
90
91
  id: str, data: PascalEntityNameData,
91
- user_token_data: TokenData = Depends(token_scheme)
92
+ user_token_data: AccessTokenData = Depends(access_token_scheme)
92
93
  ):
93
94
  if not await authorizer.is_having_permission(
94
95
  user_token_data.user_id, 'snake_module_name:snake_entity_name:update'
@@ -107,7 +108,8 @@ def register_api(
107
108
  '/api/v1/kebab-module-name/kebab-plural-entity-name/{id}', response_model=PascalEntityName
108
109
  )
109
110
  async def delete_snake_entity_name(
110
- id: str, user_token_data: TokenData = Depends(token_scheme)
111
+ id: str,
112
+ user_token_data: AccessTokenData = Depends(access_token_scheme)
111
113
  ):
112
114
  if not await authorizer.is_having_permission(
113
115
  user_token_data.user_id, 'snake_module_name:snake_entity_name:delete'
@@ -7,7 +7,7 @@ from module.snake_module_name.component.model.snake_entity_name_model import (
7
7
  snake_entity_name_model
8
8
  )
9
9
  from module.snake_module_name.schema.snake_entity_name import PascalEntityNameData
10
- from module.auth.schema.token import TokenData
10
+ from module.auth.schema.token import AccessTokenData
11
11
 
12
12
 
13
13
  def register_rpc(
@@ -48,7 +48,7 @@ def register_rpc(
48
48
  data: Mapping[str, Any],
49
49
  user_token_data: Mapping[str, Any]
50
50
  ) -> Mapping[str, Any]:
51
- user_token_data = TokenData(**user_token_data)
51
+ user_token_data = AccessTokenData(**user_token_data)
52
52
  data['created_by'] = user_token_data.user_id
53
53
  data['updated_by'] = user_token_data.user_id
54
54
  row = await snake_entity_name_model.insert(
@@ -62,7 +62,7 @@ def register_rpc(
62
62
  data: Mapping[str, Any],
63
63
  user_token_data: Mapping[str, Any]
64
64
  ) -> Mapping[str, Any]:
65
- user_token_data = TokenData(**user_token_data)
65
+ user_token_data = AccessTokenData(**user_token_data)
66
66
  data['updated_by'] = user_token_data.user_id
67
67
  row = await snake_entity_name_model.update(
68
68
  id=id, data=PascalEntityNameData(**data)
@@ -74,6 +74,6 @@ def register_rpc(
74
74
  id: str,
75
75
  user_token_data: Mapping[str, Any]
76
76
  ) -> Mapping[str, Any]:
77
- user_token_data = TokenData(**user_token_data)
77
+ user_token_data = AccessTokenData(**user_token_data)
78
78
  row = await snake_entity_name_model.delete(id=id)
79
79
  return row.dict()
@@ -1,13 +1,13 @@
1
1
  from typing import Any
2
- from ..._group import project_add_group
3
- from ....task.task import Task
4
- from ....task.decorator import python_task
5
- from ....runner import runner
6
2
  from .._common.input import (
7
3
  project_dir_input, app_name_input, module_name_input, entity_name_input,
8
4
  column_name_input, column_type_input
9
5
  )
10
6
  from .._common.helper import validate_project_dir
7
+ from ..._group import project_add_group
8
+ from ....task.task import Task
9
+ from ....task.decorator import python_task
10
+ from ....runner import runner
11
11
  from ....helper import util
12
12
  from ....helper.codemod.add_property_to_class import add_property_to_class
13
13
  from ....helper.codemod.add_key_value_to_dict import add_key_value_to_dict
@@ -15,6 +15,7 @@ from ....helper.file.text import read_text_file_async, write_text_file_async
15
15
 
16
16
  import asyncio
17
17
  import os
18
+ import re
18
19
 
19
20
  current_dir = os.path.dirname(__file__)
20
21
 
@@ -78,10 +79,16 @@ async def add_fastapp_field(*args: Any, **kwargs: Any):
78
79
  column_name = kwargs.get('column_name')
79
80
  column_type = kwargs.get('column_name')
80
81
  kebab_app_name = util.to_kebab_case(app_name)
82
+ kebab_module_name = util.to_kebab_case(module_name)
81
83
  snake_module_name = util.to_snake_case(module_name)
84
+ kebab_entity_name = util.to_kebab_case(entity_name)
82
85
  snake_entity_name = util.to_snake_case(entity_name)
83
86
  pascal_entity_name = util.to_pascal_case(entity_name)
84
87
  snake_column_name = util.to_snake_case(column_name)
88
+ kebab_column_name = util.to_kebab_case(column_name)
89
+ capitalized_human_readable_column_name = util.to_capitalized_human_readable( # noqa
90
+ column_name
91
+ )
85
92
  await asyncio.gather(
86
93
  asyncio.create_task(add_column_to_test(
87
94
  task, project_dir, kebab_app_name, snake_module_name,
@@ -97,10 +104,202 @@ async def add_fastapp_field(*args: Any, **kwargs: Any):
97
104
  snake_entity_name, pascal_entity_name, snake_column_name,
98
105
  column_type
99
106
  )),
107
+ asyncio.create_task(add_column_to_list_page(
108
+ task, project_dir, kebab_app_name, kebab_module_name,
109
+ kebab_entity_name, snake_column_name,
110
+ capitalized_human_readable_column_name
111
+ )),
112
+ asyncio.create_task(add_column_to_detail_page(
113
+ task, project_dir, kebab_app_name, kebab_module_name,
114
+ kebab_entity_name, kebab_column_name, snake_column_name,
115
+ capitalized_human_readable_column_name
116
+ )),
117
+ asyncio.create_task(add_column_to_delete_page(
118
+ task, project_dir, kebab_app_name, kebab_module_name,
119
+ kebab_entity_name, kebab_column_name, snake_column_name,
120
+ capitalized_human_readable_column_name
121
+ )),
122
+ asyncio.create_task(add_column_to_update_page(
123
+ task, project_dir, kebab_app_name, kebab_module_name,
124
+ kebab_entity_name, kebab_column_name, snake_column_name,
125
+ capitalized_human_readable_column_name
126
+ )),
127
+ asyncio.create_task(add_column_to_insert_page(
128
+ task, project_dir, kebab_app_name, kebab_module_name,
129
+ kebab_entity_name, kebab_column_name, snake_column_name,
130
+ capitalized_human_readable_column_name
131
+ )),
100
132
  )
101
133
  task.print_out('Success')
102
134
 
103
135
 
136
+ async def add_column_to_insert_page(
137
+ task: Task,
138
+ project_dir: str,
139
+ kebab_app_name: str,
140
+ kebab_module_name: str,
141
+ kebab_entity_name: str,
142
+ kebab_column_name: str,
143
+ snake_column_name: str,
144
+ capitalized_human_readable_column_name: str
145
+ ):
146
+ list_page_file_path = os.path.join(
147
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
148
+ kebab_module_name, kebab_entity_name, 'new', '+page.svelte'
149
+ )
150
+ task.print_out(f'Read HTML from: {list_page_file_path}')
151
+ html_content = await read_text_file_async(list_page_file_path)
152
+ task.print_out('Add field to insert page')
153
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
154
+ subst = '\\n'.join([
155
+ '\\1<div class="mb-4">',
156
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
157
+ f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '}>', # noqa
158
+ '\\1</div>',
159
+ '\\1\\2'
160
+ ])
161
+ html_content = re.sub(
162
+ regex, subst, html_content, 0, re.MULTILINE
163
+ )
164
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
165
+ await write_text_file_async(list_page_file_path, html_content)
166
+
167
+
168
+ async def add_column_to_update_page(
169
+ task: Task,
170
+ project_dir: str,
171
+ kebab_app_name: str,
172
+ kebab_module_name: str,
173
+ kebab_entity_name: str,
174
+ kebab_column_name: str,
175
+ snake_column_name: str,
176
+ capitalized_human_readable_column_name: str
177
+ ):
178
+ list_page_file_path = os.path.join(
179
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
180
+ kebab_module_name, kebab_entity_name, 'update', '[id]', '+page.svelte'
181
+ )
182
+ task.print_out(f'Read HTML from: {list_page_file_path}')
183
+ html_content = await read_text_file_async(list_page_file_path)
184
+ task.print_out('Add field to update page')
185
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
186
+ subst = '\\n'.join([
187
+ '\\1<div class="mb-4">',
188
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
189
+ f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '}>', # noqa
190
+ '\\1</div>',
191
+ '\\1\\2'
192
+ ])
193
+ html_content = re.sub(
194
+ regex, subst, html_content, 0, re.MULTILINE
195
+ )
196
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
197
+ await write_text_file_async(list_page_file_path, html_content)
198
+
199
+
200
+ async def add_column_to_delete_page(
201
+ task: Task,
202
+ project_dir: str,
203
+ kebab_app_name: str,
204
+ kebab_module_name: str,
205
+ kebab_entity_name: str,
206
+ kebab_column_name: str,
207
+ snake_column_name: str,
208
+ capitalized_human_readable_column_name: str
209
+ ):
210
+ list_page_file_path = os.path.join(
211
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
212
+ kebab_module_name, kebab_entity_name, 'delete', '[id]', '+page.svelte'
213
+ )
214
+ task.print_out(f'Read HTML from: {list_page_file_path}')
215
+ html_content = await read_text_file_async(list_page_file_path)
216
+ task.print_out('Add field to delete page')
217
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
218
+ subst = '\\n'.join([
219
+ '\\1<div class="mb-4">',
220
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
221
+ f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
222
+ '\\1</div>',
223
+ '\\1\\2'
224
+ ])
225
+ html_content = re.sub(
226
+ regex, subst, html_content, 0, re.MULTILINE
227
+ )
228
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
229
+ await write_text_file_async(list_page_file_path, html_content)
230
+
231
+
232
+ async def add_column_to_detail_page(
233
+ task: Task,
234
+ project_dir: str,
235
+ kebab_app_name: str,
236
+ kebab_module_name: str,
237
+ kebab_entity_name: str,
238
+ kebab_column_name: str,
239
+ snake_column_name: str,
240
+ capitalized_human_readable_column_name: str
241
+ ):
242
+ list_page_file_path = os.path.join(
243
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
244
+ kebab_module_name, kebab_entity_name, 'detail', '[id]', '+page.svelte'
245
+ )
246
+ task.print_out(f'Read HTML from: {list_page_file_path}')
247
+ html_content = await read_text_file_async(list_page_file_path)
248
+ task.print_out('Add field to detail page')
249
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
250
+ subst = '\\n'.join([
251
+ '\\1<div class="mb-4">',
252
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
253
+ f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
254
+ '\\1</div>',
255
+ '\\1\\2'
256
+ ])
257
+ html_content = re.sub(
258
+ regex, subst, html_content, 0, re.MULTILINE
259
+ )
260
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
261
+ await write_text_file_async(list_page_file_path, html_content)
262
+
263
+
264
+ async def add_column_to_list_page(
265
+ task: Task,
266
+ project_dir: str,
267
+ kebab_app_name: str,
268
+ kebab_module_name: str,
269
+ kebab_entity_name: str,
270
+ snake_column_name: str,
271
+ capitalized_human_readable_column_name: str
272
+ ):
273
+ list_page_file_path = os.path.join(
274
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
275
+ kebab_module_name, kebab_entity_name, '+page.svelte'
276
+ )
277
+ task.print_out(f'Read HTML from: {list_page_file_path}')
278
+ html_content = await read_text_file_async(list_page_file_path)
279
+ # process header
280
+ task.print_out('Add column header to table')
281
+ header_regex = r"(.*)(<!-- DON'T DELETE: insert new column header here-->)"
282
+ header_subst = '\\n'.join([
283
+ f'\\1<th>{capitalized_human_readable_column_name}</th>',
284
+ '\\1\\2'
285
+ ])
286
+ html_content = re.sub(
287
+ header_regex, header_subst, html_content, 0, re.MULTILINE
288
+ )
289
+ # process column
290
+ task.print_out('Add column to table')
291
+ column_regex = r"(.*)(<!-- DON'T DELETE: insert new column here-->)"
292
+ column_subst = '\\n'.join([
293
+ '\\1<td>{row.' + snake_column_name + '}</td>',
294
+ '\\1\\2'
295
+ ])
296
+ html_content = re.sub(
297
+ column_regex, column_subst, html_content, 0, re.MULTILINE
298
+ )
299
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
300
+ await write_text_file_async(list_page_file_path, html_content)
301
+
302
+
104
303
  async def add_column_to_test(
105
304
  task: Task,
106
305
  project_dir: str,
zrb/helper/util.py CHANGED
@@ -73,6 +73,10 @@ def to_human_readable(text: Optional[str]) -> str:
73
73
  ])
74
74
 
75
75
 
76
+ def to_capitalized_human_readable(text: Optional[str]) -> str:
77
+ return to_human_readable(text).capitalize()
78
+
79
+
76
80
  def _to_space_separated(text: Optional[str]) -> str:
77
81
  text = str(text) if not _is_undefined(text) else ''
78
82
  text = text.replace('-', ' ').replace('_', ' ')
@@ -7,7 +7,7 @@ from ..task_input.base_input import BaseInput
7
7
  from ..helper.file.copy_tree import copy_tree
8
8
  from ..helper.util import (
9
9
  to_camel_case, to_pascal_case, to_kebab_case, to_snake_case,
10
- to_human_readable
10
+ to_human_readable, to_capitalized_human_readable
11
11
  )
12
12
 
13
13
  import os
@@ -129,6 +129,7 @@ class ResourceMaker(BaseTask):
129
129
  'camel': to_camel_case,
130
130
  'snake': to_snake_case,
131
131
  'human readable': to_human_readable,
132
+ 'Human readable': to_capitalized_human_readable,
132
133
  }
133
134
  keys = list(rendered_replacements.keys())
134
135
  for key in keys:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 0.0.51
3
+ Version: 0.0.53
4
4
  Summary: Your faithful companion
5
5
  Author-email: Go Frendi Gunawan <gofrendiasgard@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -24,15 +24,16 @@ Requires-Dist: pytest==7.2.1 ; extra == "test"
24
24
  Requires-Dist: pytest-cov==4.0.0 ; extra == "test"
25
25
  Requires-Dist: pytest-xdist==3.2.0 ; extra == "test"
26
26
  Requires-Dist: pytest-asyncio==0.21.0 ; extra == "test"
27
- Project-URL: Bug Tracker, https://github.com/state-alchemists/zaruba/issues
28
- Project-URL: Homepage, https://github.com/state-alchemists/zaruba
27
+ Project-URL: Bug Tracker, https://github.com/state-alchemists/zrb/issues
28
+ Project-URL: Homepage, https://github.com/state-alchemists/zrb
29
29
  Provides-Extra: dev
30
30
  Provides-Extra: test
31
31
 
32
- # Zrb (WIP)
32
+ # Zrb (WIP): Your Faithful Companion
33
33
 
34
- Your faithful companion.
34
+ ![](images/zrb/android-chrome-192x192.png)
35
35
 
36
+ Zrb is a task runner to help you automate day-to-day tasks.
36
37
  # Installation
37
38
 
38
39
  ```bash