pgkiln 0.44.0 → 0.45.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/docs/apex-feature-parity.md +10 -10
- package/docs/guide/02-concepts.md +24 -0
- package/docs/guide/03-builder.md +33 -1
- package/docs/guide/04-pages-and-regions.md +10 -1
- package/docs/guide/06-processing.md +22 -0
- package/docs/guide/09-reference.md +13 -0
- package/docs/guide/12-development.md +2 -1
- package/docs/guide/16-files.md +23 -0
- package/docs/guide/18-cli.md +4 -0
- package/package.json +1 -1
- package/public/app.css +17 -0
- package/public/app.js +63 -0
- package/src/appfiles.ts +18 -2
- package/src/builder/advisor.ts +7 -2
- package/src/builder/code-editor.ts +6 -1
- package/src/builder/components.ts +85 -3
- package/src/builder/forms.ts +1 -1
- package/src/builder/shared.ts +39 -6
- package/src/builder/subscriptions.ts +30 -4
- package/src/cli/replace.ts +6 -2
- package/src/metadata.ts +14 -1
- package/src/runtime/component-settings.ts +42 -0
- package/src/runtime/context.ts +4 -0
- package/src/runtime/documents.ts +29 -3
- package/src/runtime/engine.ts +2 -2
- package/src/runtime/grid.ts +22 -4
- package/src/runtime/items.ts +14 -11
- package/src/runtime/logic.ts +12 -7
- package/src/runtime/regions.ts +4 -3
- package/src/runtime/render.ts +1 -0
- package/src/runtime/report.ts +2 -1
- package/src/runtime/routes.ts +4 -2
- package/src/runtime/shortcuts.ts +43 -0
- package/src/security.ts +2 -1
- package/src/subscriptions.ts +67 -0
package/src/subscriptions.ts
CHANGED
|
@@ -219,3 +219,70 @@ export async function publish(masterId: number, kind: string, name: string, user
|
|
|
219
219
|
|
|
220
220
|
export const unsubscribe = async (appId: number, kind: string, name: string) =>
|
|
221
221
|
((await owner.query('delete from meta.subscription where app_id = $1 and kind = $2 and name = $3', [appId, kind, name])).rowCount ?? 0) > 0;
|
|
222
|
+
|
|
223
|
+
// ------------------------------------------------------------------ (105) component groups
|
|
224
|
+
// A component group names some of an application's subscribable components
|
|
225
|
+
// ("kind:name"); another application subscribes to all of them at once.
|
|
226
|
+
|
|
227
|
+
/** The kinds a component group can hold: every subscribable kind but the theme. */
|
|
228
|
+
export const GROUP_KINDS = (Object.keys(KINDS) as Kind[]).filter((k) => k !== 'theme');
|
|
229
|
+
|
|
230
|
+
/** Members as the application has them ("lov:JOBS"), and a message for each that it doesn't have. */
|
|
231
|
+
export async function checkGroupMembers(appId: number, members: string[]) {
|
|
232
|
+
const ok: string[] = [];
|
|
233
|
+
const problems: string[] = [];
|
|
234
|
+
for (const m of members.map((x) => x.trim()).filter(Boolean)) {
|
|
235
|
+
const at = m.indexOf(':');
|
|
236
|
+
const kind = m.slice(0, at).trim();
|
|
237
|
+
const name = m.slice(at + 1).trim();
|
|
238
|
+
if (at < 1 || !isKind(kind) || kind === 'theme') {
|
|
239
|
+
problems.push(`${m}: write kind:name, the kind one of ${GROUP_KINDS.join(', ')}.`);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const k = KINDS[kind];
|
|
243
|
+
const row = await owner.one<{ n: string }>(`select ${k.key} as n from ${k.table} where app_id = $1 and lower(${k.key}) = lower($2)`, [appId, name]);
|
|
244
|
+
if (!row) problems.push(`${m}: the application has no ${k.label.toLowerCase()} ${name}.`);
|
|
245
|
+
else if (!ok.includes(`${kind}:${row.n}`)) ok.push(`${kind}:${row.n}`);
|
|
246
|
+
}
|
|
247
|
+
return { members: ok, problems };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Component groups of the theme and library applications appId can subscribe to. */
|
|
251
|
+
export async function groupsOffered(appId: number) {
|
|
252
|
+
return (
|
|
253
|
+
await owner.query<{ master_id: number; master_name: string; name: string; description: string | null; members: string[] }>(
|
|
254
|
+
`select m.id as master_id, m.name as master_name, g.name, g.description, g.members
|
|
255
|
+
from meta.component_group g join meta.app m on m.id = g.app_id
|
|
256
|
+
where m.app_type in ('theme', 'library') and m.id <> $1 and meta.app_workspace(m.id) = meta.app_workspace($1)
|
|
257
|
+
order by lower(m.name), m.id, lower(g.name)`,
|
|
258
|
+
[appId],
|
|
259
|
+
)
|
|
260
|
+
).rows;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** Subscribe appId to every member of a master's component group; members the master no longer has are skipped. */
|
|
264
|
+
export async function subscribeGroup(appId: number, masterId: number, group: string, username: string) {
|
|
265
|
+
const g = await owner.one<{ members: string[] }>('select members from meta.component_group where app_id = $1 and name = $2', [masterId, group]);
|
|
266
|
+
if (!g) throw new SubscriptionError('Choose a component group.');
|
|
267
|
+
const done: string[] = [];
|
|
268
|
+
const skipped: string[] = [];
|
|
269
|
+
for (const m of g.members) {
|
|
270
|
+
const at = m.indexOf(':');
|
|
271
|
+
const kind = m.slice(0, at);
|
|
272
|
+
const name = m.slice(at + 1);
|
|
273
|
+
if (!isKind(kind) || kind === 'theme') continue;
|
|
274
|
+
const k = KINDS[kind];
|
|
275
|
+
if (!(await owner.one(`select 1 as ok from ${k.table} where app_id = $1 and ${k.key} = $2`, [masterId, name]))) {
|
|
276
|
+
skipped.push(m);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
await subscribe(appId, masterId, kind, name, username);
|
|
281
|
+
done.push(m);
|
|
282
|
+
} catch (e) {
|
|
283
|
+
if (!(e instanceof SubscriptionError)) throw e;
|
|
284
|
+
skipped.push(m);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return { done, skipped };
|
|
288
|
+
}
|