flowbase-cli 0.1.11__tar.gz → 0.1.13__tar.gz
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.
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/PKG-INFO +1 -1
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/pyproject.toml +1 -1
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli/__init__.py +1 -1
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli/endpoints.py +87 -3
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli/guide.py +2 -2
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli/main.py +65 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli.egg-info/PKG-INFO +1 -1
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/tests/test_autonomy.py +16 -1
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/tests/test_cli.py +1 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/README.md +0 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/setup.cfg +0 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli.egg-info/SOURCES.txt +0 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli.egg-info/dependency_links.txt +0 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli.egg-info/entry_points.txt +0 -0
- {flowbase_cli-0.1.11 → flowbase_cli-0.1.13}/src/flowbase_cli.egg-info/top_level.txt +0 -0
|
@@ -287,6 +287,7 @@ ENDPOINTS = (
|
|
|
287
287
|
'{"baseRevision":3,"label":"Contract approval","enabled":true,'
|
|
288
288
|
'"trigger":{"manual":true,"create":false,"update":false,"match":"all","conditions":[]},'
|
|
289
289
|
'"displayFieldIds":["fld_xxx"],"lockRecord":true,"allowWithdraw":true,'
|
|
290
|
+
'"resubmit":{"enabled":true,"results":["rejected","withdrawn"],"limit":3},'
|
|
290
291
|
'"nodes":['
|
|
291
292
|
'{"id":"apn_trigger","type":"trigger"},'
|
|
292
293
|
'{"id":"apn_review","type":"approval","label":"Manager review",'
|
|
@@ -304,6 +305,7 @@ ENDPOINTS = (
|
|
|
304
305
|
'{"baseRevision":4,"label":"Contract approval","enabled":true,'
|
|
305
306
|
'"trigger":{"manual":true,"create":false,"update":false,"match":"all","conditions":[]},'
|
|
306
307
|
'"displayFieldIds":["fld_xxx"],"lockRecord":true,"allowWithdraw":true,'
|
|
308
|
+
'"resubmit":{"enabled":true,"results":["rejected","withdrawn"],"limit":3},'
|
|
307
309
|
'"nodes":['
|
|
308
310
|
'{"id":"apn_trigger","type":"trigger"},'
|
|
309
311
|
'{"id":"apn_review","type":"approval","label":"Manager review",'
|
|
@@ -322,6 +324,29 @@ ENDPOINTS = (
|
|
|
322
324
|
request_body='{"baseRevision":4,"enabled":true}'),
|
|
323
325
|
Endpoint("approvals.delete", "flowbase_approvals_delete", "POST", "/objects/{object_id}/approvals/{approval_id}/delete", "metadata:write", "Logically delete an approval flow.", "flowbase approvals delete obj_xxx apr_xxx --base-revision 4 --yes", True,
|
|
324
326
|
request_body='{"baseRevision":4}'),
|
|
327
|
+
Endpoint("print-templates.list", "flowbase_print_templates_list", "GET", "/objects/{object_id}/print-templates", "metadata:read", "List object print templates. draftRevision is on the envelope.", "flowbase print-templates list obj_xxx"),
|
|
328
|
+
Endpoint("print-templates.get", "flowbase_print_templates_get", "GET", "/objects/{object_id}/print-templates/{template_id}", "metadata:read", "Get a print template with HTML and data code. Returns source, not rendered HTML.", "flowbase print-templates get obj_xxx ptp_xxx"),
|
|
329
|
+
Endpoint("print-templates.create", "flowbase_print_templates_create", "POST", "/objects/{object_id}/print-templates", "metadata:write", "Create a print template draft. Read docs catalogs print-templates first.", "flowbase print-templates create obj_xxx --json-file template.json",
|
|
330
|
+
request_body=(
|
|
331
|
+
'{"baseRevision":3,"name":"Sales order","key":"sales_order","description":"",'
|
|
332
|
+
'"paper":{"size":"A4","width":null,"height":null,"orientation":"portrait",'
|
|
333
|
+
'"margins":{"top":15,"right":15,"bottom":15,"left":15}},'
|
|
334
|
+
'"header":{"left":"","center":"","right":""},'
|
|
335
|
+
'"footer":{"left":"","center":"第 {page} 页 / 共 {pages} 页","right":""},'
|
|
336
|
+
'"html":"<h1>{{ record.summary }}</h1>\\n<p>{{ record.name }}</p>\\n<p>{{ data.total | money(\\"CNY\\") }}</p>",'
|
|
337
|
+
'"code":"import flowbase\\n\\ndef run():\\n amount = flowbase.record.values.get(\\"amount\\") or 0\\n return {\\"total\\": amount}"}'
|
|
338
|
+
)),
|
|
339
|
+
Endpoint("print-templates.update", "flowbase_print_templates_update", "PUT", "/objects/{object_id}/print-templates/{template_id}", "metadata:write", "Partial update. Send changed fields plus baseRevision and baseUpdatedAt. Do not resend id, key, enabled, updatedAt, or draftRevision.", "flowbase print-templates update obj_xxx ptp_xxx --json-file template.json",
|
|
340
|
+
request_body=(
|
|
341
|
+
'{"baseRevision":4,"baseUpdatedAt":"2026-10-13T08:00:00+00:00",'
|
|
342
|
+
'"html":"<h1>{{ record.summary }}</h1>"}'
|
|
343
|
+
)),
|
|
344
|
+
Endpoint("print-templates.reorder", "flowbase_print_templates_reorder", "PUT", "/objects/{object_id}/print-templates/order", "metadata:write", "Reorder object print templates.", "flowbase print-templates reorder obj_xxx --json '{\"baseRevision\":4,\"templateIds\":[\"ptp_a\",\"ptp_b\"]}'",
|
|
345
|
+
request_body='{"baseRevision":4,"templateIds":["ptp_a","ptp_b"]}'),
|
|
346
|
+
Endpoint("print-templates.set-enabled", "flowbase_print_templates_set_enabled", "POST", "/objects/{object_id}/print-templates/{template_id}/enabled", "metadata:write", "Enable or disable a print template.", "flowbase print-templates set-enabled obj_xxx ptp_xxx --base-revision 4 --enabled --yes", True,
|
|
347
|
+
request_body='{"baseRevision":4,"enabled":true}'),
|
|
348
|
+
Endpoint("print-templates.delete", "flowbase_print_templates_delete", "POST", "/objects/{object_id}/print-templates/{template_id}/delete", "metadata:write", "Logically delete a print template.", "flowbase print-templates delete obj_xxx ptp_xxx --base-revision 4 --yes", True,
|
|
349
|
+
request_body='{"baseRevision":4}'),
|
|
325
350
|
Endpoint("pages.list", "flowbase_pages_list", "GET", "/pages", "metadata:read", "List custom Page metadata.", "flowbase pages list --object-id obj_xxx"),
|
|
326
351
|
Endpoint("pages.options", "flowbase_pages_options", "GET", "/pages/options", "metadata:read", "Get custom Page design options.", "flowbase pages options"),
|
|
327
352
|
Endpoint("pages.get", "flowbase_pages_get", "GET", "/pages/{page_id}", "metadata:read", "Get a custom Page.", "flowbase pages get pag_xxx"),
|
|
@@ -785,19 +810,23 @@ AUTHORING = {
|
|
|
785
810
|
"views.create": ["baseRevision", "name", "defaultFieldIds"],
|
|
786
811
|
"pages.create": ["baseRevision", "page"],
|
|
787
812
|
"records.create": ["values"],
|
|
813
|
+
"print-templates.create": ["name", "html"],
|
|
788
814
|
},
|
|
789
815
|
"draftRevision": {
|
|
790
816
|
"notReturnedBy": ["objects.get", "objects.list", "apps.get", "apps.list"],
|
|
791
817
|
"returnedBy": [
|
|
792
818
|
"views.list", "pages.list", "pages.get",
|
|
819
|
+
"print-templates.list", "print-templates.get",
|
|
793
820
|
"every metadata write response (draftRevision)",
|
|
794
821
|
],
|
|
795
|
-
"note": "Capture draftRevision from the last write or from views.list/pages.list before
|
|
822
|
+
"note": "Capture draftRevision from the last write or from views.list/pages.list/print-templates.list before writes.",
|
|
796
823
|
},
|
|
797
824
|
"readThenWrite": (
|
|
798
825
|
"For update of views/pages/dashboards/fields with constraints: get the snapshot, "
|
|
799
826
|
"edit it, set baseRevision from draftRevision. fields.update.constraints is a full replace; "
|
|
800
|
-
"sending {} wipes options."
|
|
827
|
+
"sending {} wipes options. print-templates.update is partial: send only changed fields, "
|
|
828
|
+
"baseRevision, and baseUpdatedAt copied from updatedAt. Resending id, key, enabled, "
|
|
829
|
+
"updatedAt, or draftRevision is rejected."
|
|
801
830
|
),
|
|
802
831
|
"recordsNeedReleasedMetadata": (
|
|
803
832
|
"On production, records.create/list/get use the released runtime, not the current draft. "
|
|
@@ -813,6 +842,7 @@ AUTHORING = {
|
|
|
813
842
|
"dashboards.create": "{dashboardId,draftRevision}",
|
|
814
843
|
"workflows.create": "{workflowId,draftRevision}",
|
|
815
844
|
"approvals.create": "{approvalId,draftRevision}",
|
|
845
|
+
"print-templates.create": "{templateId,draftRevision}",
|
|
816
846
|
"pages.list": "Page documents are in items. The pages field is the pagination page count.",
|
|
817
847
|
"pages.create": "Returns {page:{id,key,...}, draftRevision}. There is no top-level pageId.",
|
|
818
848
|
"objects.create": "Returns {objectId, draftRevision}.",
|
|
@@ -902,6 +932,18 @@ AUTHORING = {
|
|
|
902
932
|
"wrong": "dashboard date_range filter with no default",
|
|
903
933
|
"right": "Unset date_range defaults to last_30_days at runtime; set default.preset or omit the filter.",
|
|
904
934
|
},
|
|
935
|
+
{
|
|
936
|
+
"wrong": "print HTML {name} or {{ name }} or {{ record.客户名称 }}",
|
|
937
|
+
"right": "Use {{ record.<field key> }} with the key from objects get. See docs catalogs print-templates.",
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
"wrong": "print footer {{ page }} / {{ pages }}",
|
|
941
|
+
"right": "Page numbers are the literal tokens {page} and {pages}, only in header and footer.",
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
"wrong": "print-templates.update with the whole get document",
|
|
945
|
+
"right": "Partial update. Omit id, key, enabled, updatedAt, and draftRevision. Copy updatedAt to baseUpdatedAt.",
|
|
946
|
+
},
|
|
905
947
|
],
|
|
906
948
|
}
|
|
907
949
|
|
|
@@ -1243,6 +1285,7 @@ RESOURCE_ID_PREFIXES = {
|
|
|
1243
1285
|
"reg_": "page region", "cmp_": "page component",
|
|
1244
1286
|
"dsh_": "dashboard", "dcm_": "dashboard component", "rol_": "role",
|
|
1245
1287
|
"rec_": "record", "att_": "attachment", "emp_": "employee", "dep_": "department",
|
|
1288
|
+
"ptp_": "print template",
|
|
1246
1289
|
}
|
|
1247
1290
|
|
|
1248
1291
|
WORKFLOW_BRANCHES = {
|
|
@@ -1263,7 +1306,8 @@ APPROVAL_RULES = {
|
|
|
1263
1306
|
"selfPolicy": ["allow", "skip"],
|
|
1264
1307
|
"unavailablePolicy": ["autoApprove", "autoReject", "fallback"],
|
|
1265
1308
|
"constraints": "employees needs nonempty employeeIds; recordField needs an active lookup.employee; supervisor level is 1..10; fallback needs fallbackEmployeeId from employee discovery.",
|
|
1266
|
-
"
|
|
1309
|
+
"resubmit": "{enabled,results,limit}: results subset of rejected/withdrawn/approved (nonempty when enabled); limit null (unlimited) or integer 2..99 counting every non-failed instance per record. Omitted means enabled, all results, unlimited.",
|
|
1310
|
+
"updateEnvelope": ["baseRevision", "label", "enabled", "trigger", "displayFieldIds", "lockRecord", "allowWithdraw", "resubmit", "nodes", "edges"],
|
|
1267
1311
|
"note": "Use docs example approvals.create for a complete graph. Start disabled while authoring. Employee submit/decide is not a management CLI operation.",
|
|
1268
1312
|
}
|
|
1269
1313
|
|
|
@@ -1296,11 +1340,51 @@ DASHBOARD_RUNTIME = {
|
|
|
1296
1340
|
"example": "import flowbase\n\ndef run():\n return {\"type\": \"metric\", \"value\": 1}\n",
|
|
1297
1341
|
}
|
|
1298
1342
|
|
|
1343
|
+
PRINT_TEMPLATES = {
|
|
1344
|
+
"command": "flowbase docs catalogs print-templates",
|
|
1345
|
+
"readFirst": "objects get supplies field keys. print-templates list supplies draftRevision. print-templates get supplies html, code, header, footer, and updatedAt.",
|
|
1346
|
+
"placeholders": {
|
|
1347
|
+
"html": "Jinja2: {{ }} output, {% for %} loops, {% if %} conditions. An unknown name renders blank and still saves.",
|
|
1348
|
+
"record": "{{ record.<fieldKey> }} is display text. {{ record.values.<fieldKey> }} is the raw value. {{ record.summary }} is the record summary. Built-in id, summary, and values win over a field with the same key.",
|
|
1349
|
+
"keys": "fieldKey is the field key from objects get, never the label and never a fld_ id. Replace name and amount in the create example with keys from that object.",
|
|
1350
|
+
"data": "data is only the dict returned by run(). With no code, data is {}. {{ data.total }} stays blank unless run() returns total.",
|
|
1351
|
+
"other": "employee.name, employee.email, now (ISO string; format with the date filter), template.name, template.key.",
|
|
1352
|
+
"pageTokens": "{page} and {pages} are not Jinja. They work only in header and footer, as literal single-brace text. {{ page }} is erased before page numbers are applied. In the HTML body, {page} stays as the text {page}.",
|
|
1353
|
+
},
|
|
1354
|
+
"filters": {
|
|
1355
|
+
"money": "{{ record.values.amount | money(\"CNY\") }} thousands, 2 decimals, currency symbol. Use the raw value.",
|
|
1356
|
+
"money_upper": "{{ data.total | money_upper }} RMB amount in Chinese capitals.",
|
|
1357
|
+
"date": "{{ record.values.signed_on | date(\"YYYY-MM-DD HH:mm\") }} or {{ now | date(\"YYYY-MM-DD\") }}.",
|
|
1358
|
+
"rich": "{{ record.values.remark | rich }} sanitized HTML for a rich-text field.",
|
|
1359
|
+
"image": "{{ record.values.photo | image(width=\"40mm\") }} inlines a visible image attachment.",
|
|
1360
|
+
"qrcode": "{{ record.values.order_no | qrcode(size=\"25mm\") }}",
|
|
1361
|
+
"barcode": "{{ record.values.order_no | barcode(\"code128\", height=\"12mm\") }} code128 or ean13.",
|
|
1362
|
+
"nl2br": "{{ record.notes | nl2br }} turns newlines into <br>.",
|
|
1363
|
+
"removed": "safe, urlize, and xmlattr are unavailable. Output is HTML-escaped unless a filter above returns HTML.",
|
|
1364
|
+
},
|
|
1365
|
+
"code": {
|
|
1366
|
+
"shape": "Optional. import flowbase only. Define run() with no arguments and return a JSON object, max 2 MB.",
|
|
1367
|
+
"record": "flowbase.record.values[key] is raw; flowbase.record.display[key] is display text; flowbase.record.summary is the summary.",
|
|
1368
|
+
"related": "flowbase.records.related(relation, fields=None, order_by=None, limit=200, record=None). relation is a lookup field key, forward or reverse. Return line.display dicts so the template can use {{ line.<fieldKey> }}.",
|
|
1369
|
+
"get": "flowbase.records.get(object, record_id, fields=None) returns the same shape or None. object is an object key.",
|
|
1370
|
+
"query": "flowbase.query.records.count/group_by/timeseries/list match dashboard-runtime but have no inherit_filters argument. scope is own or omitted.",
|
|
1371
|
+
"approvals": "flowbase.approvals.history(record=None) returns up to 50 instances.",
|
|
1372
|
+
"example": "import flowbase\n\ndef run():\n record = flowbase.record\n lines = flowbase.records.related(\"lines\", fields=[\"product\", \"amount\"])\n return {\n \"total\": record.values.get(\"amount\") or 0,\n \"lines\": [line.display for line in lines],\n }\n",
|
|
1373
|
+
},
|
|
1374
|
+
"write": {
|
|
1375
|
+
"create": "Requires name and html. Other settings have defaults. New templates are enabled. key cannot be changed later. enabled is not a create/update field; use set-enabled.",
|
|
1376
|
+
"update": "Partial. Omitted fields stay. Copy updatedAt to baseUpdatedAt and draftRevision to baseRevision. Do not send id, key, enabled, updatedAt, or draftRevision.",
|
|
1377
|
+
"limits": "At most 20 templates per object. HTML 200 KB, code 100 KB, each header/footer slot 200 characters. A non-empty header needs top margin >= 10; a non-empty footer needs bottom margin >= 10.",
|
|
1378
|
+
},
|
|
1379
|
+
"verify": "The management CLI cannot render a template. get returns the source. A saved {{ }} that names the wrong key prints blank. There is no print-templates run command.",
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1299
1382
|
CATALOGS = {
|
|
1300
1383
|
"workflow-branches": WORKFLOW_BRANCHES,
|
|
1301
1384
|
"approval-rules": APPROVAL_RULES,
|
|
1302
1385
|
"page-buttons": PAGE_BUTTONS,
|
|
1303
1386
|
"dashboard-runtime": DASHBOARD_RUNTIME,
|
|
1387
|
+
"print-templates": PRINT_TEMPLATES,
|
|
1304
1388
|
"field-types": FIELD_TYPES,
|
|
1305
1389
|
"view-filters": VIEW_FILTERS,
|
|
1306
1390
|
"record-values": RECORD_VALUES,
|
|
@@ -8,7 +8,7 @@ GUIDE = {
|
|
|
8
8
|
"flowbase apps list;flowbase objects list:发现已有应用和对象,优先复用,不猜测 ID。",
|
|
9
9
|
"flowbase objects get <object_id>:读取字段 key、类型、约束和真实选项 ID;关联字段继续读取目标对象。",
|
|
10
10
|
"flowbase docs catalogs authoring;flowbase docs list;flowbase docs show <endpoint_key>:查请求和更新方式。",
|
|
11
|
-
"配置页面前读取 pages options、page-components、page-rules、page-buttons;配置流程前读取 workflow-nodes、workflow-branches 或 approval-rules。",
|
|
11
|
+
"配置页面前读取 pages options、page-components、page-rules、page-buttons;配置流程前读取 workflow-nodes、workflow-branches 或 approval-rules;配置打印模板前读取 print-templates。",
|
|
12
12
|
"先 get 再修改,保留未修改的配置。按目录转换更新 envelope;从最近读取或写入返回值获取 draftRevision,作为 baseRevision。",
|
|
13
13
|
"写后回读验证。records create 返回 recordId,再 records get;values 使用字段 key,选择和关联使用真实 ID。",
|
|
14
14
|
"遍历列表的所有分页。records list --view-id <view_id> 验证特定视图,records get 获取完整记录。",
|
|
@@ -29,7 +29,7 @@ GUIDE = {
|
|
|
29
29
|
],
|
|
30
30
|
"limits": [
|
|
31
31
|
"docs/guide 离线可读;业务调用需要权限和已启用环境。",
|
|
32
|
-
"
|
|
32
|
+
"页面规则求值不是浏览器渲染;仪表盘输出验证不是图表视觉验证。打印模板 get 返回源码,管理 CLI 不能生成打印内容;写错的 {{ }} 会保存成功并打印成空白。",
|
|
33
33
|
"组织候选只读;不能通过管理 CLI 替员工做审批决定。",
|
|
34
34
|
"删除对象/字段/页面是逻辑删除;没有物理 purge,审计与回收站会保留。",
|
|
35
35
|
],
|
|
@@ -710,6 +710,37 @@ def handle_approvals(args: argparse.Namespace) -> int:
|
|
|
710
710
|
)
|
|
711
711
|
|
|
712
712
|
|
|
713
|
+
def handle_print_templates(args: argparse.Namespace) -> int:
|
|
714
|
+
action = args.print_templates_action
|
|
715
|
+
path = {"object_id": args.object_id}
|
|
716
|
+
if hasattr(args, "template_id"):
|
|
717
|
+
path["template_id"] = args.template_id
|
|
718
|
+
if action in ("list", "get"):
|
|
719
|
+
return run_request(args, f"print-templates.{action}", path_params=path)
|
|
720
|
+
if action == "create":
|
|
721
|
+
body = load_json_payload(args.json, args.json_file)
|
|
722
|
+
require_fields(body, "name", "html")
|
|
723
|
+
return run_request(args, "print-templates.create", path_params=path, body=body)
|
|
724
|
+
if action == "update":
|
|
725
|
+
body = load_json_payload(args.json, args.json_file)
|
|
726
|
+
return run_request(args, "print-templates.update", path_params=path, body=body)
|
|
727
|
+
if action == "reorder":
|
|
728
|
+
body = load_json_payload(args.json, args.json_file)
|
|
729
|
+
require_fields(body, "baseRevision", "templateIds")
|
|
730
|
+
if not isinstance(body["templateIds"], list):
|
|
731
|
+
raise CliError("Request field 'templateIds' must be an array.")
|
|
732
|
+
return run_request(args, "print-templates.reorder", path_params=path, body=body)
|
|
733
|
+
if action == "set-enabled":
|
|
734
|
+
return run_request(
|
|
735
|
+
args, "print-templates.set-enabled", path_params=path,
|
|
736
|
+
body={"baseRevision": args.base_revision, "enabled": args.enabled},
|
|
737
|
+
)
|
|
738
|
+
return run_request(
|
|
739
|
+
args, "print-templates.delete", path_params=path,
|
|
740
|
+
body={"baseRevision": args.base_revision},
|
|
741
|
+
)
|
|
742
|
+
|
|
743
|
+
|
|
713
744
|
def handle_pages(args: argparse.Namespace) -> int:
|
|
714
745
|
action = args.pages_action
|
|
715
746
|
if action == "evaluate":
|
|
@@ -1272,6 +1303,40 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1272
1303
|
add_yes(approval_delete)
|
|
1273
1304
|
approvals.set_defaults(handler=handle_approvals)
|
|
1274
1305
|
|
|
1306
|
+
print_templates = groups.add_parser(
|
|
1307
|
+
"print-templates", help="Manage object print template metadata (HTML + data code).",
|
|
1308
|
+
)
|
|
1309
|
+
print_template_actions = print_templates.add_subparsers(
|
|
1310
|
+
dest="print_templates_action", required=True,
|
|
1311
|
+
)
|
|
1312
|
+
print_template_list = print_template_actions.add_parser("list")
|
|
1313
|
+
print_template_list.add_argument("object_id")
|
|
1314
|
+
print_template_get = print_template_actions.add_parser("get")
|
|
1315
|
+
print_template_get.add_argument("object_id")
|
|
1316
|
+
print_template_get.add_argument("template_id")
|
|
1317
|
+
for action in ("create", "reorder"):
|
|
1318
|
+
item = print_template_actions.add_parser(action)
|
|
1319
|
+
item.add_argument("object_id")
|
|
1320
|
+
add_json_args(item, endpoint_key=f"print-templates.{action}")
|
|
1321
|
+
print_template_update = print_template_actions.add_parser("update")
|
|
1322
|
+
print_template_update.add_argument("object_id")
|
|
1323
|
+
print_template_update.add_argument("template_id")
|
|
1324
|
+
add_json_args(print_template_update, endpoint_key="print-templates.update")
|
|
1325
|
+
print_template_enabled = print_template_actions.add_parser("set-enabled")
|
|
1326
|
+
print_template_enabled.add_argument("object_id")
|
|
1327
|
+
print_template_enabled.add_argument("template_id")
|
|
1328
|
+
print_template_enabled.add_argument("--base-revision", required=True, type=int)
|
|
1329
|
+
print_template_enabled.add_argument(
|
|
1330
|
+
"--enabled", action=argparse.BooleanOptionalAction, required=True,
|
|
1331
|
+
)
|
|
1332
|
+
add_yes(print_template_enabled)
|
|
1333
|
+
print_template_delete = print_template_actions.add_parser("delete")
|
|
1334
|
+
print_template_delete.add_argument("object_id")
|
|
1335
|
+
print_template_delete.add_argument("template_id")
|
|
1336
|
+
print_template_delete.add_argument("--base-revision", required=True, type=int)
|
|
1337
|
+
add_yes(print_template_delete)
|
|
1338
|
+
print_templates.set_defaults(handler=handle_print_templates)
|
|
1339
|
+
|
|
1275
1340
|
pages = groups.add_parser("pages", help="Manage custom Page metadata.")
|
|
1276
1341
|
page_actions = pages.add_subparsers(dest="pages_action", required=True)
|
|
1277
1342
|
page_evaluate = page_actions.add_parser("evaluate", help="Evaluate sample rule effects, not visual rendering or record validation.")
|
|
@@ -23,10 +23,25 @@ class AutonomyTest(unittest.TestCase):
|
|
|
23
23
|
self.assertIn('低代码平台', guide['product'])
|
|
24
24
|
self.assertTrue(any('objects get' in item for item in guide['workflow']))
|
|
25
25
|
self.assertEqual(code, 0)
|
|
26
|
+
self.assertTrue(any('print-templates' in item for item in guide['workflow']))
|
|
26
27
|
code, out, _ = self.invoke(['docs', 'catalogs'])
|
|
27
|
-
self.assertTrue({'page-buttons', 'workflow-branches', 'approval-rules', 'dashboard-runtime'}.issubset(json.loads(out)))
|
|
28
|
+
self.assertTrue({'page-buttons', 'workflow-branches', 'approval-rules', 'dashboard-runtime', 'print-templates'}.issubset(json.loads(out)))
|
|
28
29
|
request.assert_not_called()
|
|
29
30
|
|
|
31
|
+
def test_print_template_catalog_separates_field_and_page_placeholders(self):
|
|
32
|
+
code, out, err = self.invoke(['docs', 'catalogs', 'print-templates'])
|
|
33
|
+
self.assertEqual(code, 0, err)
|
|
34
|
+
catalog = json.loads(out)
|
|
35
|
+
placeholders = catalog['placeholders']
|
|
36
|
+
self.assertIn('{{ record.<fieldKey> }}', placeholders['record'])
|
|
37
|
+
self.assertIn('objects get', placeholders['keys'])
|
|
38
|
+
self.assertIn('{page}', placeholders['pageTokens'])
|
|
39
|
+
self.assertIn('{{ page }}', placeholders['pageTokens'])
|
|
40
|
+
self.assertIn('header and footer', placeholders['pageTokens'])
|
|
41
|
+
self.assertIn('no inherit_filters', catalog['code']['query'])
|
|
42
|
+
self.assertIn('baseUpdatedAt', catalog['write']['update'])
|
|
43
|
+
self.assertIn('cannot render', catalog['verify'])
|
|
44
|
+
|
|
30
45
|
def test_write_disconnect_is_not_retried_or_reported_as_definite_failure(self):
|
|
31
46
|
for error in (RemoteDisconnected('connection closed'), TimeoutError('timed out'), URLError('fbk_secret rejected')):
|
|
32
47
|
with self.subTest(error=error), patch('flowbase_cli.main.urlopen', side_effect=error) as request:
|
|
@@ -334,6 +334,7 @@ class FlowBaseCliTest(unittest.TestCase):
|
|
|
334
334
|
prefixes = json.loads(stdout.getvalue())
|
|
335
335
|
self.assertEqual(prefixes["reg_"], "page region")
|
|
336
336
|
self.assertEqual(prefixes["cmp_"], "page component")
|
|
337
|
+
self.assertEqual(prefixes["ptp_"], "print template")
|
|
337
338
|
|
|
338
339
|
def test_docs_list_marks_body_and_confirmation(self):
|
|
339
340
|
stdout = io.StringIO()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|