pgkiln 0.44.0 → 0.46.0
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.
- package/db/migrations/102_app_computations.sql +345 -0
- package/db/migrations/103_shortcuts.sql +341 -0
- package/db/migrations/104_report_queries.sql +413 -0
- package/db/migrations/105_component_settings_groups.sql +367 -0
- package/db/migrations/106_form_designer.sql +102 -0
- package/db/migrations/107_app_version.sql +9 -0
- package/docs/apex-feature-parity.md +15 -12
- package/docs/guide/02-concepts.md +24 -0
- package/docs/guide/03-builder.md +69 -13
- package/docs/guide/04-pages-and-regions.md +84 -3
- package/docs/guide/05-items.md +14 -2
- package/docs/guide/06-processing.md +22 -0
- package/docs/guide/09-reference.md +14 -1
- package/docs/guide/11-from-apex.md +2 -1
- package/docs/guide/12-development.md +8 -2
- package/docs/guide/16-files.md +23 -0
- package/docs/guide/18-cli.md +4 -0
- package/examples/hr/hr_61_form_designer.sql +80 -0
- package/package.json +1 -1
- package/public/app.css +79 -2
- package/public/app.js +307 -35
- package/public/builder.css +21 -1
- package/public/builder.js +67 -0
- package/public/sw.js +2 -1
- package/src/app.ts +9 -1
- package/src/appfiles.ts +18 -2
- package/src/builder/advisor.ts +7 -2
- package/src/builder/appwizard.ts +22 -6
- package/src/builder/arrange.ts +33 -12
- package/src/builder/code-editor.ts +7 -2
- package/src/builder/components.ts +86 -4
- package/src/builder/designer.ts +44 -17
- package/src/builder/errors.ts +65 -0
- package/src/builder/form-designer.ts +229 -0
- package/src/builder/forms.ts +1 -1
- package/src/builder/locks.ts +6 -0
- package/src/builder/newapp.ts +2 -1
- package/src/builder/object-browser.ts +81 -18
- package/src/builder/region-help.ts +2 -0
- package/src/builder/region-settings.ts +2 -0
- package/src/builder/reporter.ts +1 -1
- package/src/builder/routes.ts +7 -5
- package/src/builder/search.ts +3 -3
- package/src/builder/shared.ts +41 -8
- package/src/builder/subscriptions.ts +30 -4
- package/src/builder/ui.ts +2 -0
- package/src/cli/replace.ts +16 -2
- package/src/i18n/ar.ts +62 -0
- package/src/i18n/cs.ts +62 -0
- package/src/i18n/da.ts +62 -0
- package/src/i18n/de.ts +62 -0
- package/src/i18n/el.ts +62 -0
- package/src/i18n/es.ts +62 -0
- package/src/i18n/fi.ts +62 -0
- package/src/i18n/fr.ts +62 -0
- package/src/i18n/he.ts +62 -0
- package/src/i18n/it.ts +62 -0
- package/src/i18n/ja.ts +62 -0
- package/src/i18n/ko.ts +62 -0
- package/src/i18n/nb.ts +62 -0
- package/src/i18n/pl.ts +62 -0
- package/src/i18n/pt.ts +62 -0
- package/src/i18n/ru.ts +62 -0
- package/src/i18n/sv.ts +62 -0
- package/src/i18n/tr.ts +62 -0
- package/src/i18n/uk.ts +62 -0
- package/src/i18n/zh.ts +62 -0
- package/src/i18n.ts +124 -0
- package/src/metadata.ts +18 -3
- package/src/runtime/component-settings.ts +42 -0
- package/src/runtime/context.ts +4 -0
- package/src/runtime/devbar.ts +1 -1
- package/src/runtime/documents.ts +29 -3
- package/src/runtime/engine.ts +2 -2
- package/src/runtime/facet-state.ts +10 -5
- package/src/runtime/facets.ts +29 -5
- package/src/runtime/form-designer.ts +676 -0
- package/src/runtime/grid.ts +36 -11
- package/src/runtime/items.ts +47 -32
- package/src/runtime/lists.ts +1 -1
- package/src/runtime/logic.ts +12 -7
- package/src/runtime/pdf.ts +2 -1
- package/src/runtime/regions.ts +8 -3
- package/src/runtime/render.ts +8 -3
- package/src/runtime/report.ts +4 -3
- package/src/runtime/routes.ts +7 -3
- package/src/runtime/shortcuts.ts +43 -0
- package/src/runtime/smart-filters.ts +2 -1
- package/src/runtime/tasks.ts +6 -3
- package/src/security.ts +2 -1
- package/src/subscriptions.ts +67 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
-- =====================================================================
|
|
2
|
+
-- 103: shortcuts (APEX: Shared Components → Shortcuts)
|
|
3
|
+
--
|
|
4
|
+
-- meta.shortcut: a named piece of text an application reuses. "NAME" (the
|
|
5
|
+
-- name in double quotes) in a static region's content, an item's help
|
|
6
|
+
-- text and a button's or menu entry's confirm message is replaced by the
|
|
7
|
+
-- shortcut, before &ITEM. substitutions (src/runtime/shortcuts.ts). Only
|
|
8
|
+
-- the names of the application's shortcuts are replaced. Types:
|
|
9
|
+
-- text the value, escaped where it goes into HTML
|
|
10
|
+
-- html the value as HTML
|
|
11
|
+
-- function_body a PL/pgSQL function body that returns the text (HTML),
|
|
12
|
+
-- run as the application's role once per request
|
|
13
|
+
-- export_app / import_app are redefined from 102 to carry shortcuts.
|
|
14
|
+
-- =====================================================================
|
|
15
|
+
create table meta.shortcut (
|
|
16
|
+
id serial primary key,
|
|
17
|
+
app_id int not null references meta.app on delete cascade,
|
|
18
|
+
name text not null check (name ~ '^[A-Z][A-Z0-9_]{0,59}$'),
|
|
19
|
+
type text not null default 'text' check (type in ('text', 'html', 'function_body')),
|
|
20
|
+
value text not null default '',
|
|
21
|
+
comments text,
|
|
22
|
+
unique (app_id, name),
|
|
23
|
+
check (type <> 'function_body' or trim(value) <> '')
|
|
24
|
+
);
|
|
25
|
+
revoke all on meta.shortcut from public;
|
|
26
|
+
grant select on meta.shortcut to pgkiln_runtime;
|
|
27
|
+
comment on table meta.shortcut is 'Shortcuts (103): named texts; "NAME" in static content, help texts and confirm messages is replaced by them';
|
|
28
|
+
|
|
29
|
+
-- (090) an isolated workspace's logins see their own applications' rows only
|
|
30
|
+
alter table meta.shortcut enable row level security;
|
|
31
|
+
create policy workspace on meta.shortcut
|
|
32
|
+
using ((select meta.isolation_off()) or app_id in (select meta.visible_apps()))
|
|
33
|
+
with check ((select meta.isolation_off()) or app_id in (select meta.visible_apps()));
|
|
34
|
+
|
|
35
|
+
create or replace function meta.export_app(p_alias text) returns jsonb
|
|
36
|
+
language sql stable set search_path = meta, pg_catalog as $$
|
|
37
|
+
select jsonb_build_object(
|
|
38
|
+
'format', 'pgkiln/2',
|
|
39
|
+
-- (083) availability and build status belong to the installation
|
|
40
|
+
'app', to_jsonb(a) - 'id' - 'created_at' - 'updated_at' - 'availability' - 'availability_message' - 'availability_users' - 'build_status',
|
|
41
|
+
'authz_schemes', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.authz_scheme x where x.app_id = a.id), '[]'),
|
|
42
|
+
'app_items', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.app_item x where x.app_id = a.id), '[]'),
|
|
43
|
+
'app_processes', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.seq, x.id) from meta.app_process x where x.app_id = a.id), '[]'),
|
|
44
|
+
'lovs', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.lov x where x.app_id = a.id), '[]'),
|
|
45
|
+
'group_roles', coalesce((select jsonb_agg(to_jsonb(x) - 'app_id' order by x.group_name, x.role) from meta.app_group_role x where x.app_id = a.id), '[]'),
|
|
46
|
+
'text_messages', coalesce((select jsonb_agg(to_jsonb(x) - 'app_id' order by x.name, x.language) from meta.text_message x where x.app_id = a.id), '[]'),
|
|
47
|
+
'translations', coalesce((select jsonb_agg(to_jsonb(x) - 'app_id' order by x.language, x.source) from meta.translation x where x.app_id = a.id), '[]'),
|
|
48
|
+
'report_layouts', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' - 'logo' || jsonb_build_object('logo', encode(x.logo, 'base64')) order by x.name)
|
|
49
|
+
from meta.report_layout x where x.app_id = a.id), '[]'),
|
|
50
|
+
'automations', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' - 'next_run_at' - 'last_run_at' - 'last_status' - 'code' order by x.name)
|
|
51
|
+
from meta.automation x where x.app_id = a.id), '[]'),
|
|
52
|
+
-- (044) the actions of the automations, by automation name
|
|
53
|
+
'automation_actions', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.automation_name collate "C", x.seq, x.name collate "C")
|
|
54
|
+
from meta.automation_action x where x.app_id = a.id), '[]'),
|
|
55
|
+
'document_templates', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.document_template x where x.app_id = a.id), '[]'),
|
|
56
|
+
'task_definitions', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.task_definition x where x.app_id = a.id), '[]'),
|
|
57
|
+
'workflow_definitions', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.workflow_definition x where x.app_id = a.id), '[]'),
|
|
58
|
+
'rest_modules', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.rest_module x where x.app_id = a.id), '[]'),
|
|
59
|
+
'template_components', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.static_id) from meta.template_component x where x.app_id = a.id), '[]'),
|
|
60
|
+
'build_options', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.build_option x where x.app_id = a.id), '[]'),
|
|
61
|
+
-- (030) secrets never leave the installation: they are entered again after an import
|
|
62
|
+
-- (050) nor do the password and refresh token of the OAuth2 flows, or the token state
|
|
63
|
+
'web_credentials', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' - 'secret_enc' - 'password_enc' - 'refresh_token_enc' - 'token_refreshed_at' order by x.name)
|
|
64
|
+
from meta.web_credential x where x.app_id = a.id), '[]'),
|
|
65
|
+
-- (050) the synchronisation's state (next and last run) belongs to the installation
|
|
66
|
+
'rest_sources', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' - 'sync_next_at' - 'sync_last_at' - 'sync_last_status' order by x.name)
|
|
67
|
+
from meta.rest_source x where x.app_id = a.id), '[]'),
|
|
68
|
+
-- (041) data load definitions
|
|
69
|
+
'data_load_definitions', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.data_load_def x where x.app_id = a.id), '[]'),
|
|
70
|
+
-- (042) lists; entries keep their ids so parents can be remapped on import
|
|
71
|
+
'lists', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.list x where x.app_id = a.id), '[]'),
|
|
72
|
+
'list_entries', coalesce((select jsonb_agg(to_jsonb(x) - 'app_id' order by x.list_name, x.parent_id nulls first, x.seq, x.id) from meta.list_entry x where x.app_id = a.id), '[]'),
|
|
73
|
+
-- (042) supporting objects: install, upgrade and deinstall scripts (never run on import)
|
|
74
|
+
'supporting_scripts', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.supporting_script x where x.app_id = a.id), '[]'),
|
|
75
|
+
-- (069) plug-ins (their files are static files, their templates template components)
|
|
76
|
+
'plugins', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.plugin x where x.app_id = a.id), '[]'),
|
|
77
|
+
-- (080) search configurations
|
|
78
|
+
'search_configs', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.search_config x where x.app_id = a.id), '[]'),
|
|
79
|
+
-- (081) e-mail templates
|
|
80
|
+
'email_templates', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.email_template x where x.app_id = a.id), '[]'),
|
|
81
|
+
-- (086) application settings (with their values) and dynamic translations
|
|
82
|
+
'app_settings', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.app_setting x where x.app_id = a.id), '[]'),
|
|
83
|
+
'page_groups', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.page_group x where x.app_id = a.id), '[]'),
|
|
84
|
+
-- (103) shortcuts
|
|
85
|
+
'shortcuts', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.name) from meta.shortcut x where x.app_id = a.id), '[]'),
|
|
86
|
+
-- (102) application computations
|
|
87
|
+
'app_computations', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.seq, x.id) from meta.app_computation x where x.app_id = a.id), '[]'),
|
|
88
|
+
'dynamic_translations', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' order by x.language, x.source collate "C") from meta.dynamic_translation x where x.app_id = a.id), '[]'),
|
|
89
|
+
-- (068) static application files (JavaScript, CSS, images, fonts) as base64
|
|
90
|
+
'static_files', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'app_id' - 'content' - 'updated_at' || jsonb_build_object('content', translate(encode(x.content, 'base64'), E'\n', '')) order by x.name)
|
|
91
|
+
from meta.static_file x where x.app_id = a.id), '[]'),
|
|
92
|
+
-- nav entries and regions keep their ids, so parents and references can be remapped on import
|
|
93
|
+
'nav', coalesce((select jsonb_agg(to_jsonb(x) - 'app_id' order by x.parent_id nulls first, x.seq, x.id) from meta.nav_entry x where x.app_id = a.id), '[]'),
|
|
94
|
+
'pages', coalesce((
|
|
95
|
+
select jsonb_agg(to_jsonb(p) - 'id' - 'app_id' || jsonb_build_object(
|
|
96
|
+
'regions', coalesce((select jsonb_agg(to_jsonb(r) - 'page_id' order by r.seq, r.id) from meta.region r where r.page_id = p.id), '[]'),
|
|
97
|
+
'items', coalesce((select jsonb_agg(to_jsonb(i) - 'id' - 'page_id' order by i.seq, i.id) from meta.item i where i.page_id = p.id), '[]'),
|
|
98
|
+
'buttons', coalesce((select jsonb_agg(to_jsonb(b) - 'id' - 'page_id' order by b.seq, b.id) from meta.button b where b.page_id = p.id), '[]'),
|
|
99
|
+
'dynamic_actions', coalesce((select jsonb_agg(to_jsonb(d) - 'id' - 'page_id' order by d.seq, d.id) from meta.dynamic_action d where d.page_id = p.id), '[]'),
|
|
100
|
+
'validations', coalesce((select jsonb_agg(to_jsonb(v) - 'id' - 'page_id' order by v.seq, v.id) from meta.validation v where v.page_id = p.id), '[]'),
|
|
101
|
+
'processes', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'page_id' order by x.seq, x.id) from meta.process x where x.page_id = p.id), '[]'),
|
|
102
|
+
'computations', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'page_id' order by x.seq, x.id) from meta.computation x where x.page_id = p.id), '[]'),
|
|
103
|
+
'branches', coalesce((select jsonb_agg(to_jsonb(x) - 'id' - 'page_id' order by x.seq, x.id) from meta.branch x where x.page_id = p.id), '[]')
|
|
104
|
+
) order by p.page_no)
|
|
105
|
+
from meta.page p where p.app_id = a.id), '[]'))
|
|
106
|
+
from meta.app a
|
|
107
|
+
where a.alias = p_alias
|
|
108
|
+
$$;
|
|
109
|
+
|
|
110
|
+
-- ---------------------------------------------------------------- import
|
|
111
|
+
-- Same as 081, plus app_settings and dynamic_translations.
|
|
112
|
+
|
|
113
|
+
create or replace function meta.import_app(p_doc jsonb, p_alias text default null) returns int
|
|
114
|
+
language plpgsql set search_path = meta, pg_catalog as $$
|
|
115
|
+
declare
|
|
116
|
+
v_app_id int;
|
|
117
|
+
v_page_id int;
|
|
118
|
+
v_page jsonb;
|
|
119
|
+
v_e jsonb;
|
|
120
|
+
v_rmap jsonb;
|
|
121
|
+
v_nmap jsonb := '{}';
|
|
122
|
+
v_lmap jsonb := '{}';
|
|
123
|
+
v_new_id int;
|
|
124
|
+
begin
|
|
125
|
+
if p_doc->>'format' is distinct from 'pgkiln/2' then
|
|
126
|
+
raise exception 'unsupported export format %', coalesce(p_doc->>'format', '(none)');
|
|
127
|
+
end if;
|
|
128
|
+
|
|
129
|
+
insert into meta.app
|
|
130
|
+
select (jsonb_populate_record(null::meta.app, p_doc->'app' || jsonb_build_object(
|
|
131
|
+
'id', nextval('meta.app_id_seq'),
|
|
132
|
+
'alias', coalesce(p_alias, p_doc->'app'->>'alias'),
|
|
133
|
+
'created_at', now(), 'updated_at', now()))).*
|
|
134
|
+
returning id into v_app_id;
|
|
135
|
+
|
|
136
|
+
insert into meta.authz_scheme
|
|
137
|
+
select (jsonb_populate_record(null::meta.authz_scheme, e || jsonb_build_object('id', nextval('meta.authz_scheme_id_seq'), 'app_id', v_app_id))).*
|
|
138
|
+
from jsonb_array_elements(coalesce(p_doc->'authz_schemes', '[]')) e;
|
|
139
|
+
insert into meta.app_item
|
|
140
|
+
select (jsonb_populate_record(null::meta.app_item, e || jsonb_build_object('id', nextval('meta.app_item_id_seq'), 'app_id', v_app_id))).*
|
|
141
|
+
from jsonb_array_elements(coalesce(p_doc->'app_items', '[]')) e;
|
|
142
|
+
insert into meta.app_process
|
|
143
|
+
select (jsonb_populate_record(null::meta.app_process, e || jsonb_build_object('id', nextval('meta.app_process_id_seq'), 'app_id', v_app_id))).*
|
|
144
|
+
from jsonb_array_elements(coalesce(p_doc->'app_processes', '[]')) e;
|
|
145
|
+
insert into meta.lov
|
|
146
|
+
select (jsonb_populate_record(null::meta.lov, e || jsonb_build_object('id', nextval('meta.lov_id_seq'), 'app_id', v_app_id))).*
|
|
147
|
+
from jsonb_array_elements(coalesce(p_doc->'lovs', '[]')) e;
|
|
148
|
+
insert into meta.app_group_role
|
|
149
|
+
select (jsonb_populate_record(null::meta.app_group_role, e || jsonb_build_object('app_id', v_app_id))).*
|
|
150
|
+
from jsonb_array_elements(coalesce(p_doc->'group_roles', '[]')) e;
|
|
151
|
+
insert into meta.text_message
|
|
152
|
+
select (jsonb_populate_record(null::meta.text_message, e || jsonb_build_object('app_id', v_app_id))).*
|
|
153
|
+
from jsonb_array_elements(coalesce(p_doc->'text_messages', '[]')) e;
|
|
154
|
+
insert into meta.translation
|
|
155
|
+
select (jsonb_populate_record(null::meta.translation, e || jsonb_build_object('app_id', v_app_id))).*
|
|
156
|
+
from jsonb_array_elements(coalesce(p_doc->'translations', '[]')) e;
|
|
157
|
+
insert into meta.report_layout
|
|
158
|
+
select (jsonb_populate_record(null::meta.report_layout, (e - 'logo') || jsonb_build_object(
|
|
159
|
+
'id', nextval('meta.report_layout_id_seq'), 'app_id', v_app_id,
|
|
160
|
+
'logo', null))).*
|
|
161
|
+
from jsonb_array_elements(coalesce(p_doc->'report_layouts', '[]')) e;
|
|
162
|
+
update meta.report_layout l
|
|
163
|
+
set logo = decode(e->>'logo', 'base64')
|
|
164
|
+
from jsonb_array_elements(coalesce(p_doc->'report_layouts', '[]')) e
|
|
165
|
+
where l.app_id = v_app_id and l.name = e->>'name' and e->>'logo' is not null;
|
|
166
|
+
-- imported automations start switched off: the copy must not run the original's jobs unasked.
|
|
167
|
+
-- (044) a file with actions: the automations' code is ignored; an older file: code becomes the single action
|
|
168
|
+
insert into meta.automation
|
|
169
|
+
select (jsonb_populate_record(null::meta.automation, '{"error_handling": "stop"}'::jsonb
|
|
170
|
+
|| jsonb_strip_nulls(case when p_doc ? 'automation_actions' then e - 'code' else e end)
|
|
171
|
+
|| jsonb_build_object('id', nextval('meta.automation_id_seq'), 'app_id', v_app_id, 'enabled', false))).*
|
|
172
|
+
from jsonb_array_elements(coalesce(p_doc->'automations', '[]')) e;
|
|
173
|
+
insert into meta.automation_action
|
|
174
|
+
select (jsonb_populate_record(null::meta.automation_action, '{"seq": 10}'::jsonb || jsonb_strip_nulls(e)
|
|
175
|
+
|| jsonb_build_object('id', nextval('meta.automation_action_id_seq'), 'app_id', v_app_id))).*
|
|
176
|
+
from jsonb_array_elements(coalesce(p_doc->'automation_actions', '[]')) e;
|
|
177
|
+
insert into meta.document_template
|
|
178
|
+
select (jsonb_populate_record(null::meta.document_template, e || jsonb_build_object('id', nextval('meta.document_template_id_seq'), 'app_id', v_app_id))).*
|
|
179
|
+
from jsonb_array_elements(coalesce(p_doc->'document_templates', '[]')) e;
|
|
180
|
+
insert into meta.task_definition
|
|
181
|
+
select (jsonb_populate_record(null::meta.task_definition, e || jsonb_build_object('id', nextval('meta.task_definition_id_seq'), 'app_id', v_app_id))).*
|
|
182
|
+
from jsonb_array_elements(coalesce(p_doc->'task_definitions', '[]')) e;
|
|
183
|
+
insert into meta.workflow_definition
|
|
184
|
+
select (jsonb_populate_record(null::meta.workflow_definition, e || jsonb_build_object('id', nextval('meta.workflow_definition_id_seq'), 'app_id', v_app_id))).*
|
|
185
|
+
from jsonb_array_elements(coalesce(p_doc->'workflow_definitions', '[]')) e;
|
|
186
|
+
insert into meta.rest_module
|
|
187
|
+
select (jsonb_populate_record(null::meta.rest_module, e || jsonb_build_object('id', nextval('meta.rest_module_id_seq'), 'app_id', v_app_id))).*
|
|
188
|
+
from jsonb_array_elements(coalesce(p_doc->'rest_modules', '[]')) e;
|
|
189
|
+
-- (028) template components: regions and report columns refer to them by static id
|
|
190
|
+
insert into meta.template_component
|
|
191
|
+
select (jsonb_populate_record(null::meta.template_component, e || jsonb_build_object('id', nextval('meta.template_component_id_seq'), 'app_id', v_app_id))).*
|
|
192
|
+
from jsonb_array_elements(coalesce(p_doc->'template_components', '[]')) e;
|
|
193
|
+
-- (029) build options (components name them by name)
|
|
194
|
+
insert into meta.build_option
|
|
195
|
+
select (jsonb_populate_record(null::meta.build_option, e || jsonb_build_object('id', nextval('meta.build_option_id_seq'), 'app_id', v_app_id))).*
|
|
196
|
+
from jsonb_array_elements(coalesce(p_doc->'build_options', '[]')) e;
|
|
197
|
+
-- (030) web credentials arrive without a secret, whatever the document holds
|
|
198
|
+
-- (050) nor a password or refresh token
|
|
199
|
+
insert into meta.web_credential
|
|
200
|
+
select (jsonb_populate_record(null::meta.web_credential, '{"type": "basic", "valid_for": [], "grant_type": "client_credentials"}'::jsonb
|
|
201
|
+
|| jsonb_strip_nulls(e - 'secret_enc' - 'password_enc' - 'refresh_token_enc' - 'token_refreshed_at')
|
|
202
|
+
|| jsonb_build_object('id', nextval('meta.web_credential_id_seq'), 'app_id', v_app_id))).*
|
|
203
|
+
from jsonb_array_elements(coalesce(p_doc->'web_credentials', '[]')) e;
|
|
204
|
+
-- (050) write-back operations and synchronisation; an imported synchronisation starts switched off
|
|
205
|
+
insert into meta.rest_source
|
|
206
|
+
select (jsonb_populate_record(null::meta.rest_source, '{"method": "GET", "headers": {}, "params": [], "columns": [], "cache_seconds": 0, "timeout_s": 10, "max_rows": 1000,
|
|
207
|
+
"operations": {}, "key_columns": [], "sync_mode": "merge", "sync_delete": false, "sync_time_zone": "UTC"}'::jsonb
|
|
208
|
+
|| jsonb_strip_nulls(e - 'sync_next_at' - 'sync_last_at' - 'sync_last_status')
|
|
209
|
+
|| jsonb_build_object('id', nextval('meta.rest_source_id_seq'), 'app_id', v_app_id, 'sync_enabled', false))).*
|
|
210
|
+
from jsonb_array_elements(coalesce(p_doc->'rest_sources', '[]')) e;
|
|
211
|
+
|
|
212
|
+
-- (041) data load definitions (the data_load process names them)
|
|
213
|
+
insert into meta.data_load_def
|
|
214
|
+
select (jsonb_populate_record(null::meta.data_load_def, '{"format": "auto", "headers": true, "mode": "append", "skip_errors": false, "columns": []}'::jsonb
|
|
215
|
+
|| jsonb_strip_nulls(e) || jsonb_build_object('id', nextval('meta.data_load_def_id_seq'), 'app_id', v_app_id))).*
|
|
216
|
+
from jsonb_array_elements(coalesce(p_doc->'data_load_definitions', '[]')) e;
|
|
217
|
+
|
|
218
|
+
-- (042) lists and their entries, supporting scripts. Entries are inserted
|
|
219
|
+
-- without a parent first and the parents set afterwards, so the order of
|
|
220
|
+
-- the entries in the document doesn't matter (a moved entry may have a
|
|
221
|
+
-- higher id than its children).
|
|
222
|
+
insert into meta.list
|
|
223
|
+
select (jsonb_populate_record(null::meta.list, '{"type": "static"}'::jsonb || jsonb_strip_nulls(e) || jsonb_build_object('id', nextval('meta.list_id_seq'), 'app_id', v_app_id))).*
|
|
224
|
+
from jsonb_array_elements(coalesce(p_doc->'lists', '[]')) e;
|
|
225
|
+
for v_e in select * from jsonb_array_elements(coalesce(p_doc->'list_entries', '[]')) loop
|
|
226
|
+
insert into meta.list_entry
|
|
227
|
+
select (jsonb_populate_record(null::meta.list_entry, '{"target_items": {}}'::jsonb || jsonb_strip_nulls(v_e) || jsonb_build_object(
|
|
228
|
+
'id', nextval('meta.list_entry_id_seq'), 'app_id', v_app_id, 'parent_id', null))).*
|
|
229
|
+
returning id into v_new_id;
|
|
230
|
+
if v_e->>'id' is not null then
|
|
231
|
+
v_lmap := v_lmap || jsonb_build_object(v_e->>'id', v_new_id);
|
|
232
|
+
end if;
|
|
233
|
+
end loop;
|
|
234
|
+
update meta.list_entry x
|
|
235
|
+
set parent_id = (v_lmap->>(e->>'parent_id'))::int
|
|
236
|
+
from jsonb_array_elements(coalesce(p_doc->'list_entries', '[]')) e
|
|
237
|
+
where e->>'parent_id' is not null and v_lmap ? (e->>'parent_id') and v_lmap ? (e->>'id')
|
|
238
|
+
and x.id = (v_lmap->>(e->>'id'))::int;
|
|
239
|
+
insert into meta.supporting_script
|
|
240
|
+
select (jsonb_populate_record(null::meta.supporting_script, '{"kind": "install", "seq": 10, "script": ""}'::jsonb || jsonb_strip_nulls(e)
|
|
241
|
+
|| jsonb_build_object('id', nextval('meta.supporting_script_id_seq'), 'app_id', v_app_id))).*
|
|
242
|
+
from jsonb_array_elements(coalesce(p_doc->'supporting_scripts', '[]')) e;
|
|
243
|
+
|
|
244
|
+
-- (069) plug-ins
|
|
245
|
+
insert into meta.plugin
|
|
246
|
+
select (jsonb_populate_record(null::meta.plugin, e || jsonb_build_object('id', nextval('meta.plugin_id_seq'), 'app_id', v_app_id))).*
|
|
247
|
+
from jsonb_array_elements(coalesce(p_doc->'plugins', '[]')) e;
|
|
248
|
+
|
|
249
|
+
-- (080) search configurations (search regions name them)
|
|
250
|
+
insert into meta.search_config
|
|
251
|
+
select (jsonb_populate_record(null::meta.search_config, '{"seq": 10, "source_type": "table", "searchable_columns": [], "max_results": 10}'::jsonb
|
|
252
|
+
|| jsonb_strip_nulls(e) || jsonb_build_object('id', nextval('meta.search_config_id_seq'), 'app_id', v_app_id))).*
|
|
253
|
+
from jsonb_array_elements(coalesce(p_doc->'search_configs', '[]')) e;
|
|
254
|
+
|
|
255
|
+
-- (081) e-mail templates (meta.send_mail_template and the send_email process name them)
|
|
256
|
+
insert into meta.email_template
|
|
257
|
+
select (jsonb_populate_record(null::meta.email_template, e || jsonb_build_object('id', nextval('meta.email_template_id_seq'), 'app_id', v_app_id))).*
|
|
258
|
+
from jsonb_array_elements(coalesce(p_doc->'email_templates', '[]')) e;
|
|
259
|
+
|
|
260
|
+
-- (103) shortcuts
|
|
261
|
+
insert into meta.shortcut
|
|
262
|
+
select (jsonb_populate_record(null::meta.shortcut, '{"type": "text"}'::jsonb || jsonb_strip_nulls(e)
|
|
263
|
+
|| jsonb_build_object('id', nextval('meta.shortcut_id_seq'), 'app_id', v_app_id))).*
|
|
264
|
+
from jsonb_array_elements(coalesce(p_doc->'shortcuts', '[]')) e;
|
|
265
|
+
|
|
266
|
+
-- (102) application computations
|
|
267
|
+
insert into meta.app_computation
|
|
268
|
+
select (jsonb_populate_record(null::meta.app_computation, '{"seq": 10, "point": "before_header", "type": "static"}'::jsonb || jsonb_strip_nulls(e)
|
|
269
|
+
|| jsonb_build_object('id', nextval('meta.app_computation_id_seq'), 'app_id', v_app_id))).*
|
|
270
|
+
from jsonb_array_elements(coalesce(p_doc->'app_computations', '[]')) e;
|
|
271
|
+
|
|
272
|
+
-- (089) page groups
|
|
273
|
+
insert into meta.page_group
|
|
274
|
+
select (jsonb_populate_record(null::meta.page_group, e || jsonb_build_object('id', nextval('meta.page_group_id_seq'), 'app_id', v_app_id))).*
|
|
275
|
+
from jsonb_array_elements(coalesce(p_doc->'page_groups', '[]')) e;
|
|
276
|
+
|
|
277
|
+
-- (086) application settings and dynamic translations
|
|
278
|
+
insert into meta.app_setting
|
|
279
|
+
select (jsonb_populate_record(null::meta.app_setting, e || jsonb_build_object('id', nextval('meta.app_setting_id_seq'), 'app_id', v_app_id))).*
|
|
280
|
+
from jsonb_array_elements(coalesce(p_doc->'app_settings', '[]')) e;
|
|
281
|
+
insert into meta.dynamic_translation
|
|
282
|
+
select (jsonb_populate_record(null::meta.dynamic_translation, e || jsonb_build_object('id', nextval('meta.dynamic_translation_id_seq'), 'app_id', v_app_id))).*
|
|
283
|
+
from jsonb_array_elements(coalesce(p_doc->'dynamic_translations', '[]')) e;
|
|
284
|
+
|
|
285
|
+
-- (068) static application files
|
|
286
|
+
insert into meta.static_file (app_id, name, mime, content, updated_at)
|
|
287
|
+
select v_app_id, e->>'name', e->>'mime', decode(coalesce(e->>'content', ''), 'base64'), now()
|
|
288
|
+
from jsonb_array_elements(coalesce(p_doc->'static_files', '[]')) e;
|
|
289
|
+
|
|
290
|
+
for v_e in select * from jsonb_array_elements(coalesce(p_doc->'nav', '[]')) loop
|
|
291
|
+
insert into meta.nav_entry
|
|
292
|
+
select (jsonb_populate_record(null::meta.nav_entry, v_e || jsonb_build_object(
|
|
293
|
+
'id', nextval('meta.nav_entry_id_seq'), 'app_id', v_app_id,
|
|
294
|
+
'parent_id', v_nmap->>(v_e->>'parent_id')))).*
|
|
295
|
+
returning id into v_new_id;
|
|
296
|
+
v_nmap := v_nmap || jsonb_build_object(v_e->>'id', v_new_id);
|
|
297
|
+
end loop;
|
|
298
|
+
|
|
299
|
+
for v_page in select * from jsonb_array_elements(coalesce(p_doc->'pages', '[]')) loop
|
|
300
|
+
insert into meta.page
|
|
301
|
+
select (jsonb_populate_record(null::meta.page, v_page || jsonb_build_object('id', nextval('meta.page_id_seq'), 'app_id', v_app_id))).*
|
|
302
|
+
returning id into v_page_id;
|
|
303
|
+
|
|
304
|
+
v_rmap := '{}';
|
|
305
|
+
for v_e in select * from jsonb_array_elements(coalesce(v_page->'regions', '[]')) loop
|
|
306
|
+
insert into meta.region
|
|
307
|
+
select (jsonb_populate_record(null::meta.region, v_e || jsonb_build_object('id', nextval('meta.region_id_seq'), 'page_id', v_page_id))).*
|
|
308
|
+
returning id into v_new_id;
|
|
309
|
+
v_rmap := v_rmap || jsonb_build_object(v_e->>'id', v_new_id);
|
|
310
|
+
end loop;
|
|
311
|
+
-- facet and map regions point at their report region by id
|
|
312
|
+
update meta.region r
|
|
313
|
+
set config = jsonb_set(r.config, '{report}', to_jsonb((v_rmap->>(r.config->>'report'))::int))
|
|
314
|
+
where r.page_id = v_page_id and r.type in ('facets', 'smart_filters', 'map') and v_rmap ? (r.config->>'report');
|
|
315
|
+
|
|
316
|
+
insert into meta.item
|
|
317
|
+
select (jsonb_populate_record(null::meta.item, e || jsonb_build_object('id', nextval('meta.item_id_seq'), 'page_id', v_page_id, 'region_id', v_rmap->>(e->>'region_id')))).*
|
|
318
|
+
from jsonb_array_elements(coalesce(v_page->'items', '[]')) e;
|
|
319
|
+
insert into meta.button
|
|
320
|
+
select (jsonb_populate_record(null::meta.button, e || jsonb_build_object('id', nextval('meta.button_id_seq'), 'page_id', v_page_id, 'region_id', v_rmap->>(e->>'region_id')))).*
|
|
321
|
+
from jsonb_array_elements(coalesce(v_page->'buttons', '[]')) e;
|
|
322
|
+
insert into meta.dynamic_action
|
|
323
|
+
select (jsonb_populate_record(null::meta.dynamic_action, e || jsonb_build_object('id', nextval('meta.dynamic_action_id_seq'), 'page_id', v_page_id, 'affected_region_id', v_rmap->>(e->>'affected_region_id')))).*
|
|
324
|
+
from jsonb_array_elements(coalesce(v_page->'dynamic_actions', '[]')) e;
|
|
325
|
+
insert into meta.validation
|
|
326
|
+
select (jsonb_populate_record(null::meta.validation, e || jsonb_build_object('id', nextval('meta.validation_id_seq'), 'page_id', v_page_id))).*
|
|
327
|
+
from jsonb_array_elements(coalesce(v_page->'validations', '[]')) e;
|
|
328
|
+
insert into meta.process
|
|
329
|
+
select (jsonb_populate_record(null::meta.process, e || jsonb_build_object('id', nextval('meta.process_id_seq'), 'page_id', v_page_id, 'region_id', v_rmap->>(e->>'region_id')))).*
|
|
330
|
+
from jsonb_array_elements(coalesce(v_page->'processes', '[]')) e;
|
|
331
|
+
insert into meta.computation
|
|
332
|
+
select (jsonb_populate_record(null::meta.computation, e || jsonb_build_object('id', nextval('meta.computation_id_seq'), 'page_id', v_page_id))).*
|
|
333
|
+
from jsonb_array_elements(coalesce(v_page->'computations', '[]')) e;
|
|
334
|
+
insert into meta.branch
|
|
335
|
+
select (jsonb_populate_record(null::meta.branch, e || jsonb_build_object('id', nextval('meta.branch_id_seq'), 'page_id', v_page_id))).*
|
|
336
|
+
from jsonb_array_elements(coalesce(v_page->'branches', '[]')) e;
|
|
337
|
+
end loop;
|
|
338
|
+
|
|
339
|
+
return v_app_id;
|
|
340
|
+
end
|
|
341
|
+
$$;
|