pgkiln 0.75.0 → 0.76.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/docs/apex-feature-parity.md +4 -3
- package/docs/guide/04-pages-and-regions.md +23 -2
- package/package.json +1 -1
- package/public/app.css +18 -0
- package/public/app.js +141 -0
- package/src/i18n/ar.ts +24 -0
- package/src/i18n/cs.ts +24 -0
- package/src/i18n/da.ts +24 -0
- package/src/i18n/de.ts +24 -0
- package/src/i18n/el.ts +24 -0
- package/src/i18n/es.ts +24 -0
- package/src/i18n/fi.ts +24 -0
- package/src/i18n/fr.ts +24 -0
- package/src/i18n/he.ts +24 -0
- package/src/i18n/it.ts +24 -0
- package/src/i18n/ja.ts +24 -0
- package/src/i18n/ko.ts +24 -0
- package/src/i18n/nb.ts +24 -0
- package/src/i18n/pl.ts +24 -0
- package/src/i18n/pt.ts +24 -0
- package/src/i18n/ru.ts +24 -0
- package/src/i18n/sv.ts +24 -0
- package/src/i18n/tr.ts +24 -0
- package/src/i18n/uk.ts +24 -0
- package/src/i18n/zh.ts +24 -0
- package/src/i18n.ts +48 -0
- package/src/runtime/ai-filter.ts +11 -6
- package/src/runtime/ir-plan.ts +3 -3
- package/src/runtime/pdf.ts +6 -6
- package/src/runtime/render.ts +1 -1
- package/src/runtime/report.ts +208 -25
package/src/i18n/he.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const he: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "אינו מכיל",
|
|
476
476
|
'op.null': "ריק",
|
|
477
477
|
'op.not_null': "אינו ריק",
|
|
478
|
+
'op.in': "הוא אחד מ",
|
|
479
|
+
'op.not_in': "אינו אף אחד מ",
|
|
480
|
+
'op.between': "בין",
|
|
481
|
+
'op.period': "בתוך",
|
|
482
|
+
'report.value_to': "עד",
|
|
483
|
+
'report.values': "ערכים",
|
|
484
|
+
'report.period': "תקופה",
|
|
485
|
+
'report.and': "ו",
|
|
486
|
+
'report.filter_help': "אחד מ: ערכים מופרדים בפסיקים או מסומנים ברשימה. בין: אחד הערכים יכול להישאר ריק. בתוך: תקופה של עמודת תאריך.",
|
|
487
|
+
'report.order_chip': "סדר עמודות משלך",
|
|
488
|
+
'report.order_reset': "חזרה לסדר העמודות של הדוח",
|
|
489
|
+
'report.order_help': "גרור עמודה או השתמש בחצים כדי לשנות את הסדר.",
|
|
490
|
+
'report.move_up': "הזז את {column} למעלה",
|
|
491
|
+
'report.move_down': "הזז את {column} למטה",
|
|
492
|
+
'report.moved': "{column}: מיקום {n} מתוך {total}",
|
|
493
|
+
'period.today': "היום",
|
|
494
|
+
'period.yesterday': "אתמול",
|
|
495
|
+
'period.last_7_days': "7 הימים האחרונים",
|
|
496
|
+
'period.last_30_days': "30 הימים האחרונים",
|
|
497
|
+
'period.next_7_days': "7 הימים הבאים",
|
|
498
|
+
'period.this_month': "החודש",
|
|
499
|
+
'period.last_month': "החודש שעבר",
|
|
500
|
+
'period.this_year': "השנה",
|
|
501
|
+
'period.last_year': "השנה שעברה",
|
|
478
502
|
'grid.delete_row': "מחיקת שורה {row}",
|
|
479
503
|
'grid.new': "חדשה",
|
|
480
504
|
'grid.row_changed': "שורה {row}: השורה שונתה מחוץ לטבלה; טענו מחדש את הדף.",
|
package/src/i18n/it.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const it: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "non contiene",
|
|
476
476
|
'op.null': "è vuoto",
|
|
477
477
|
'op.not_null': "non è vuoto",
|
|
478
|
+
'op.in': "è uno di",
|
|
479
|
+
'op.not_in': "non è nessuno di",
|
|
480
|
+
'op.between': "è tra",
|
|
481
|
+
'op.period': "è in",
|
|
482
|
+
'report.value_to': "A",
|
|
483
|
+
'report.values': "Valori",
|
|
484
|
+
'report.period': "Periodo",
|
|
485
|
+
'report.and': "e",
|
|
486
|
+
'report.filter_help': "È uno di: valori separati da virgole, o selezionati nell'elenco. È tra: uno dei due valori può restare vuoto. È in: un periodo di una colonna data.",
|
|
487
|
+
'report.order_chip': "Ordine delle colonne personale",
|
|
488
|
+
'report.order_reset': "Torna all'ordine delle colonne del report",
|
|
489
|
+
'report.order_help': "Trascina una colonna, o usa le frecce, per cambiare l'ordine.",
|
|
490
|
+
'report.move_up': "Sposta {column} in alto",
|
|
491
|
+
'report.move_down': "Sposta {column} in basso",
|
|
492
|
+
'report.moved': "{column}: posizione {n} di {total}",
|
|
493
|
+
'period.today': "oggi",
|
|
494
|
+
'period.yesterday': "ieri",
|
|
495
|
+
'period.last_7_days': "gli ultimi 7 giorni",
|
|
496
|
+
'period.last_30_days': "gli ultimi 30 giorni",
|
|
497
|
+
'period.next_7_days': "i prossimi 7 giorni",
|
|
498
|
+
'period.this_month': "questo mese",
|
|
499
|
+
'period.last_month': "il mese scorso",
|
|
500
|
+
'period.this_year': "quest'anno",
|
|
501
|
+
'period.last_year': "l'anno scorso",
|
|
478
502
|
'grid.delete_row': "Elimina la riga {row}",
|
|
479
503
|
'grid.new': "nuova",
|
|
480
504
|
'grid.row_changed': "Riga {row}: questa riga è stata modificata fuori dalla griglia; ricarica la pagina.",
|
package/src/i18n/ja.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const ja: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "を含まない",
|
|
476
476
|
'op.null': "が空",
|
|
477
477
|
'op.not_null': "が空でない",
|
|
478
|
+
'op.in': "次のいずれか",
|
|
479
|
+
'op.not_in': "次のいずれでもない",
|
|
480
|
+
'op.between': "次の範囲内",
|
|
481
|
+
'op.period': "次の期間内",
|
|
482
|
+
'report.value_to': "終了",
|
|
483
|
+
'report.values': "値",
|
|
484
|
+
'report.period': "期間",
|
|
485
|
+
'report.and': "から",
|
|
486
|
+
'report.filter_help': "次のいずれか: 値をカンマで区切るか、リストでチェックします。次の範囲内: どちらかの値は空でもかまいません。次の期間内: 日付列の期間です。",
|
|
487
|
+
'report.order_chip': "独自の列の順序",
|
|
488
|
+
'report.order_reset': "レポートの列の順序に戻す",
|
|
489
|
+
'report.order_help': "列をドラッグするか矢印を使って順序を変更します。",
|
|
490
|
+
'report.move_up': "{column}を上へ移動",
|
|
491
|
+
'report.move_down': "{column}を下へ移動",
|
|
492
|
+
'report.moved': "{column}: {total} 列中 {n} 番目",
|
|
493
|
+
'period.today': "今日",
|
|
494
|
+
'period.yesterday': "昨日",
|
|
495
|
+
'period.last_7_days': "過去7日間",
|
|
496
|
+
'period.last_30_days': "過去30日間",
|
|
497
|
+
'period.next_7_days': "今後7日間",
|
|
498
|
+
'period.this_month': "今月",
|
|
499
|
+
'period.last_month': "先月",
|
|
500
|
+
'period.this_year': "今年",
|
|
501
|
+
'period.last_year': "昨年",
|
|
478
502
|
'grid.delete_row': "行 {row} を削除",
|
|
479
503
|
'grid.new': "新規",
|
|
480
504
|
'grid.row_changed': "行 {row}: この行はグリッドの外で変更されました。ページを再読み込みしてください。",
|
package/src/i18n/ko.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const ko: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "포함하지 않음",
|
|
476
476
|
'op.null': "비어 있음",
|
|
477
477
|
'op.not_null': "비어 있지 않음",
|
|
478
|
+
'op.in': "다음 중 하나",
|
|
479
|
+
'op.not_in': "다음 중 어느 것도 아님",
|
|
480
|
+
'op.between': "다음 사이",
|
|
481
|
+
'op.period': "다음 기간",
|
|
482
|
+
'report.value_to': "끝",
|
|
483
|
+
'report.values': "값",
|
|
484
|
+
'report.period': "기간",
|
|
485
|
+
'report.and': "~",
|
|
486
|
+
'report.filter_help': "다음 중 하나: 쉼표로 구분한 값 또는 목록에서 선택한 값. 다음 사이: 두 값 중 하나는 비워 둘 수 있습니다. 다음 기간: 날짜 열의 기간입니다.",
|
|
487
|
+
'report.order_chip': "사용자 열 순서",
|
|
488
|
+
'report.order_reset': "보고서의 열 순서로 되돌리기",
|
|
489
|
+
'report.order_help': "열을 끌거나 화살표를 사용하여 순서를 바꿉니다.",
|
|
490
|
+
'report.move_up': "{column} 위로 이동",
|
|
491
|
+
'report.move_down': "{column} 아래로 이동",
|
|
492
|
+
'report.moved': "{column}: {total}개 중 {n}번째",
|
|
493
|
+
'period.today': "오늘",
|
|
494
|
+
'period.yesterday': "어제",
|
|
495
|
+
'period.last_7_days': "최근 7일",
|
|
496
|
+
'period.last_30_days': "최근 30일",
|
|
497
|
+
'period.next_7_days': "다음 7일",
|
|
498
|
+
'period.this_month': "이번 달",
|
|
499
|
+
'period.last_month': "지난달",
|
|
500
|
+
'period.this_year': "올해",
|
|
501
|
+
'period.last_year': "작년",
|
|
478
502
|
'grid.delete_row': "{row}행 삭제",
|
|
479
503
|
'grid.new': "새 행",
|
|
480
504
|
'grid.row_changed': "{row}행: 그리드 밖에서 변경된 행입니다. 페이지를 새로 고치세요.",
|
package/src/i18n/nb.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const nb: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "inneholder ikke",
|
|
476
476
|
'op.null': "er tom",
|
|
477
477
|
'op.not_null': "er ikke tom",
|
|
478
|
+
'op.in': "er en av",
|
|
479
|
+
'op.not_in': "er ingen av",
|
|
480
|
+
'op.between': "er mellom",
|
|
481
|
+
'op.period': "er i",
|
|
482
|
+
'report.value_to': "Til",
|
|
483
|
+
'report.values': "Verdier",
|
|
484
|
+
'report.period': "Periode",
|
|
485
|
+
'report.and': "og",
|
|
486
|
+
'report.filter_help': "Er en av: verdier skilt med komma, eller krysset av i listen. Er mellom: den ene verdien kan stå tom. Er i: en periode for en datokolonne.",
|
|
487
|
+
'report.order_chip': "Egen kolonnerekkefølge",
|
|
488
|
+
'report.order_reset': "Tilbake til rapportens kolonnerekkefølge",
|
|
489
|
+
'report.order_help': "Dra en kolonne, eller bruk pilene, for å endre rekkefølgen.",
|
|
490
|
+
'report.move_up': "Flytt {column} opp",
|
|
491
|
+
'report.move_down': "Flytt {column} ned",
|
|
492
|
+
'report.moved': "{column}: posisjon {n} av {total}",
|
|
493
|
+
'period.today': "i dag",
|
|
494
|
+
'period.yesterday': "i går",
|
|
495
|
+
'period.last_7_days': "de siste 7 dagene",
|
|
496
|
+
'period.last_30_days': "de siste 30 dagene",
|
|
497
|
+
'period.next_7_days': "de neste 7 dagene",
|
|
498
|
+
'period.this_month': "denne måneden",
|
|
499
|
+
'period.last_month': "forrige måned",
|
|
500
|
+
'period.this_year': "dette året",
|
|
501
|
+
'period.last_year': "i fjor",
|
|
478
502
|
'grid.delete_row': "Slett rad {row}",
|
|
479
503
|
'grid.new': "ny",
|
|
480
504
|
'grid.row_changed': "Rad {row}: raden er endret utenfor rutenettet; last inn siden på nytt.",
|
package/src/i18n/pl.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const pl: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "nie zawiera",
|
|
476
476
|
'op.null': "jest puste",
|
|
477
477
|
'op.not_null': "nie jest puste",
|
|
478
|
+
'op.in': "jest jednym z",
|
|
479
|
+
'op.not_in': "nie jest żadnym z",
|
|
480
|
+
'op.between': "jest między",
|
|
481
|
+
'op.period': "jest w",
|
|
482
|
+
'report.value_to': "Do",
|
|
483
|
+
'report.values': "Wartości",
|
|
484
|
+
'report.period': "Okres",
|
|
485
|
+
'report.and': "i",
|
|
486
|
+
'report.filter_help': "Jest jednym z: wartości oddzielone przecinkami lub zaznaczone na liście. Jest między: jedna z wartości może pozostać pusta. Jest w: okres kolumny z datą.",
|
|
487
|
+
'report.order_chip': "Własna kolejność kolumn",
|
|
488
|
+
'report.order_reset': "Powrót do kolejności kolumn raportu",
|
|
489
|
+
'report.order_help': "Przeciągnij kolumnę lub użyj strzałek, aby zmienić kolejność.",
|
|
490
|
+
'report.move_up': "Przesuń {column} w górę",
|
|
491
|
+
'report.move_down': "Przesuń {column} w dół",
|
|
492
|
+
'report.moved': "{column}: pozycja {n} z {total}",
|
|
493
|
+
'period.today': "dzisiaj",
|
|
494
|
+
'period.yesterday': "wczoraj",
|
|
495
|
+
'period.last_7_days': "ostatnich 7 dniach",
|
|
496
|
+
'period.last_30_days': "ostatnich 30 dniach",
|
|
497
|
+
'period.next_7_days': "następnych 7 dniach",
|
|
498
|
+
'period.this_month': "tym miesiącu",
|
|
499
|
+
'period.last_month': "zeszłym miesiącu",
|
|
500
|
+
'period.this_year': "tym roku",
|
|
501
|
+
'period.last_year': "zeszłym roku",
|
|
478
502
|
'grid.delete_row': "Usuń wiersz {row}",
|
|
479
503
|
'grid.new': "nowy",
|
|
480
504
|
'grid.row_changed': "Wiersz {row}: ten wiersz zmieniono poza siatką; odśwież stronę.",
|
package/src/i18n/pt.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const pt: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "não contém",
|
|
476
476
|
'op.null': "está vazio",
|
|
477
477
|
'op.not_null': "não está vazio",
|
|
478
|
+
'op.in': "é um de",
|
|
479
|
+
'op.not_in': "não é nenhum de",
|
|
480
|
+
'op.between': "está entre",
|
|
481
|
+
'op.period': "está em",
|
|
482
|
+
'report.value_to': "Até",
|
|
483
|
+
'report.values': "Valores",
|
|
484
|
+
'report.period': "Período",
|
|
485
|
+
'report.and': "e",
|
|
486
|
+
'report.filter_help': "É um de: valores separados por vírgulas, ou marcados na lista. Está entre: qualquer um dos valores pode ficar vazio. Está em: um período de uma coluna de data.",
|
|
487
|
+
'report.order_chip': "Ordem de colunas própria",
|
|
488
|
+
'report.order_reset': "Voltar à ordem de colunas do relatório",
|
|
489
|
+
'report.order_help': "Arraste uma coluna, ou use as setas, para mudar a ordem.",
|
|
490
|
+
'report.move_up': "Mover {column} para cima",
|
|
491
|
+
'report.move_down': "Mover {column} para baixo",
|
|
492
|
+
'report.moved': "{column}: posição {n} de {total}",
|
|
493
|
+
'period.today': "hoje",
|
|
494
|
+
'period.yesterday': "ontem",
|
|
495
|
+
'period.last_7_days': "os últimos 7 dias",
|
|
496
|
+
'period.last_30_days': "os últimos 30 dias",
|
|
497
|
+
'period.next_7_days': "os próximos 7 dias",
|
|
498
|
+
'period.this_month': "este mês",
|
|
499
|
+
'period.last_month': "o mês passado",
|
|
500
|
+
'period.this_year': "este ano",
|
|
501
|
+
'period.last_year': "o ano passado",
|
|
478
502
|
'grid.delete_row': "Eliminar a linha {row}",
|
|
479
503
|
'grid.new': "nova",
|
|
480
504
|
'grid.row_changed': "Linha {row}: esta linha foi alterada fora da grelha; recarregue a página.",
|
package/src/i18n/ru.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const ru: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "не содержит",
|
|
476
476
|
'op.null': "пусто",
|
|
477
477
|
'op.not_null': "не пусто",
|
|
478
|
+
'op.in': "одно из",
|
|
479
|
+
'op.not_in': "ни одно из",
|
|
480
|
+
'op.between': "между",
|
|
481
|
+
'op.period': "в периоде",
|
|
482
|
+
'report.value_to': "По",
|
|
483
|
+
'report.values': "Значения",
|
|
484
|
+
'report.period': "Период",
|
|
485
|
+
'report.and': "и",
|
|
486
|
+
'report.filter_help': "Одно из: значения через запятую или отмеченные в списке. Между: одно из значений может остаться пустым. В периоде: период столбца с датой.",
|
|
487
|
+
'report.order_chip': "Свой порядок столбцов",
|
|
488
|
+
'report.order_reset': "Вернуть порядок столбцов отчета",
|
|
489
|
+
'report.order_help': "Перетащите столбец или используйте стрелки, чтобы изменить порядок.",
|
|
490
|
+
'report.move_up': "Переместить {column} вверх",
|
|
491
|
+
'report.move_down': "Переместить {column} вниз",
|
|
492
|
+
'report.moved': "{column}: позиция {n} из {total}",
|
|
493
|
+
'period.today': "сегодня",
|
|
494
|
+
'period.yesterday': "вчера",
|
|
495
|
+
'period.last_7_days': "последние 7 дней",
|
|
496
|
+
'period.last_30_days': "последние 30 дней",
|
|
497
|
+
'period.next_7_days': "следующие 7 дней",
|
|
498
|
+
'period.this_month': "этот месяц",
|
|
499
|
+
'period.last_month': "прошлый месяц",
|
|
500
|
+
'period.this_year': "этот год",
|
|
501
|
+
'period.last_year': "прошлый год",
|
|
478
502
|
'grid.delete_row': "Удалить строку {row}",
|
|
479
503
|
'grid.new': "новая",
|
|
480
504
|
'grid.row_changed': "Строка {row}: строку изменили вне таблицы; обновите страницу.",
|
package/src/i18n/sv.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const sv: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "innehåller inte",
|
|
476
476
|
'op.null': "är tomt",
|
|
477
477
|
'op.not_null': "är inte tomt",
|
|
478
|
+
'op.in': "är en av",
|
|
479
|
+
'op.not_in': "är ingen av",
|
|
480
|
+
'op.between': "är mellan",
|
|
481
|
+
'op.period': "är i",
|
|
482
|
+
'report.value_to': "Till",
|
|
483
|
+
'report.values': "Värden",
|
|
484
|
+
'report.period': "Period",
|
|
485
|
+
'report.and': "och",
|
|
486
|
+
'report.filter_help': "Är en av: värden åtskilda med kommatecken, eller markerade i listan. Är mellan: ett av värdena får vara tomt. Är i: en period för en datumkolumn.",
|
|
487
|
+
'report.order_chip': "Egen kolumnordning",
|
|
488
|
+
'report.order_reset': "Tillbaka till rapportens kolumnordning",
|
|
489
|
+
'report.order_help': "Dra en kolumn, eller använd pilarna, för att ändra ordningen.",
|
|
490
|
+
'report.move_up': "Flytta upp {column}",
|
|
491
|
+
'report.move_down': "Flytta ned {column}",
|
|
492
|
+
'report.moved': "{column}: position {n} av {total}",
|
|
493
|
+
'period.today': "i dag",
|
|
494
|
+
'period.yesterday': "i går",
|
|
495
|
+
'period.last_7_days': "de senaste 7 dagarna",
|
|
496
|
+
'period.last_30_days': "de senaste 30 dagarna",
|
|
497
|
+
'period.next_7_days': "de kommande 7 dagarna",
|
|
498
|
+
'period.this_month': "denna månad",
|
|
499
|
+
'period.last_month': "förra månaden",
|
|
500
|
+
'period.this_year': "detta år",
|
|
501
|
+
'period.last_year': "förra året",
|
|
478
502
|
'grid.delete_row': "Ta bort rad {row}",
|
|
479
503
|
'grid.new': "ny",
|
|
480
504
|
'grid.row_changed': "Rad {row}: raden har ändrats utanför rutnätet; läs in sidan igen.",
|
package/src/i18n/tr.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const tr: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "içermez",
|
|
476
476
|
'op.null': "boş",
|
|
477
477
|
'op.not_null': "boş değil",
|
|
478
|
+
'op.in': "şunlardan biri",
|
|
479
|
+
'op.not_in': "şunların hiçbiri",
|
|
480
|
+
'op.between': "arasında",
|
|
481
|
+
'op.period': "şu dönemde",
|
|
482
|
+
'report.value_to': "Bitiş",
|
|
483
|
+
'report.values': "Değerler",
|
|
484
|
+
'report.period': "Dönem",
|
|
485
|
+
'report.and': "ve",
|
|
486
|
+
'report.filter_help': "Şunlardan biri: virgülle ayrılmış değerler veya listede işaretlenenler. Arasında: değerlerden biri boş kalabilir. Şu dönemde: bir tarih sütununun dönemi.",
|
|
487
|
+
'report.order_chip': "Kendi sütun sıralaması",
|
|
488
|
+
'report.order_reset': "Raporun sütun sıralamasına dön",
|
|
489
|
+
'report.order_help': "Sırayı değiştirmek için bir sütunu sürükleyin veya oklarını kullanın.",
|
|
490
|
+
'report.move_up': "{column} yukarı taşı",
|
|
491
|
+
'report.move_down': "{column} aşağı taşı",
|
|
492
|
+
'report.moved': "{column}: {total} içinde {n}. konum",
|
|
493
|
+
'period.today': "bugün",
|
|
494
|
+
'period.yesterday': "dün",
|
|
495
|
+
'period.last_7_days': "son 7 gün",
|
|
496
|
+
'period.last_30_days': "son 30 gün",
|
|
497
|
+
'period.next_7_days': "sonraki 7 gün",
|
|
498
|
+
'period.this_month': "bu ay",
|
|
499
|
+
'period.last_month': "geçen ay",
|
|
500
|
+
'period.this_year': "bu yıl",
|
|
501
|
+
'period.last_year': "geçen yıl",
|
|
478
502
|
'grid.delete_row': "{row}. satırı sil",
|
|
479
503
|
'grid.new': "yeni",
|
|
480
504
|
'grid.row_changed': "Satır {row}: bu satır tablonun dışında değiştirildi; sayfayı yeniden yükleyin.",
|
package/src/i18n/uk.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const uk: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "не містить",
|
|
476
476
|
'op.null': "порожньо",
|
|
477
477
|
'op.not_null': "не порожньо",
|
|
478
|
+
'op.in': "одне з",
|
|
479
|
+
'op.not_in': "жодне з",
|
|
480
|
+
'op.between': "між",
|
|
481
|
+
'op.period': "у періоді",
|
|
482
|
+
'report.value_to': "По",
|
|
483
|
+
'report.values': "Значення",
|
|
484
|
+
'report.period': "Період",
|
|
485
|
+
'report.and': "і",
|
|
486
|
+
'report.filter_help': "Одне з: значення через кому або позначені у списку. Між: одне зі значень може лишитися порожнім. У періоді: період стовпця з датою.",
|
|
487
|
+
'report.order_chip': "Власний порядок стовпців",
|
|
488
|
+
'report.order_reset': "Повернути порядок стовпців звіту",
|
|
489
|
+
'report.order_help': "Перетягніть стовпець або скористайтеся стрілками, щоб змінити порядок.",
|
|
490
|
+
'report.move_up': "Перемістити {column} вгору",
|
|
491
|
+
'report.move_down': "Перемістити {column} вниз",
|
|
492
|
+
'report.moved': "{column}: позиція {n} з {total}",
|
|
493
|
+
'period.today': "сьогодні",
|
|
494
|
+
'period.yesterday': "вчора",
|
|
495
|
+
'period.last_7_days': "останні 7 днів",
|
|
496
|
+
'period.last_30_days': "останні 30 днів",
|
|
497
|
+
'period.next_7_days': "наступні 7 днів",
|
|
498
|
+
'period.this_month': "цей місяць",
|
|
499
|
+
'period.last_month': "минулий місяць",
|
|
500
|
+
'period.this_year': "цей рік",
|
|
501
|
+
'period.last_year': "минулий рік",
|
|
478
502
|
'grid.delete_row': "Видалити рядок {row}",
|
|
479
503
|
'grid.new': "новий",
|
|
480
504
|
'grid.row_changed': "Рядок {row}: рядок змінено поза таблицею; оновіть сторінку.",
|
package/src/i18n/zh.ts
CHANGED
|
@@ -475,6 +475,30 @@ export const zh: Record<MessageKey, string> = {
|
|
|
475
475
|
'op.not_contains': "不包含",
|
|
476
476
|
'op.null': "为空",
|
|
477
477
|
'op.not_null': "不为空",
|
|
478
|
+
'op.in': "是以下之一",
|
|
479
|
+
'op.not_in': "不是以下任何一个",
|
|
480
|
+
'op.between': "介于",
|
|
481
|
+
'op.period': "属于",
|
|
482
|
+
'report.value_to': "至",
|
|
483
|
+
'report.values': "值",
|
|
484
|
+
'report.period': "期间",
|
|
485
|
+
'report.and': "和",
|
|
486
|
+
'report.filter_help': "是以下之一:用逗号分隔的值,或在列表中勾选。介于:任一值可以留空。属于:日期列的一个期间。",
|
|
487
|
+
'report.order_chip': "自定义列顺序",
|
|
488
|
+
'report.order_reset': "恢复报表的列顺序",
|
|
489
|
+
'report.order_help': "拖动列或使用箭头来更改顺序。",
|
|
490
|
+
'report.move_up': "上移 {column}",
|
|
491
|
+
'report.move_down': "下移 {column}",
|
|
492
|
+
'report.moved': "{column}:第 {n} 列,共 {total} 列",
|
|
493
|
+
'period.today': "今天",
|
|
494
|
+
'period.yesterday': "昨天",
|
|
495
|
+
'period.last_7_days': "过去 7 天",
|
|
496
|
+
'period.last_30_days': "过去 30 天",
|
|
497
|
+
'period.next_7_days': "未来 7 天",
|
|
498
|
+
'period.this_month': "本月",
|
|
499
|
+
'period.last_month': "上月",
|
|
500
|
+
'period.this_year': "今年",
|
|
501
|
+
'period.last_year': "去年",
|
|
478
502
|
'grid.delete_row': "删除第 {row} 行",
|
|
479
503
|
'grid.new': "新",
|
|
480
504
|
'grid.row_changed': "第 {row} 行:此行已在表格外被更改,请重新加载页面。",
|
package/src/i18n.ts
CHANGED
|
@@ -502,6 +502,30 @@ const en = {
|
|
|
502
502
|
'op.not_contains': 'does not contain',
|
|
503
503
|
'op.null': 'is empty',
|
|
504
504
|
'op.not_null': 'is not empty',
|
|
505
|
+
'op.in': "is one of",
|
|
506
|
+
'op.not_in': "is not one of",
|
|
507
|
+
'op.between': "is between",
|
|
508
|
+
'op.period': "is in",
|
|
509
|
+
'report.value_to': "To",
|
|
510
|
+
'report.values': "Values",
|
|
511
|
+
'report.period': "Period",
|
|
512
|
+
'report.and': "and",
|
|
513
|
+
'report.filter_help': "Is one of: values separated by commas, or ticked in the list. Is between: either value may stay empty. Is in: a period of a date column.",
|
|
514
|
+
'report.order_chip': "Own column order",
|
|
515
|
+
'report.order_reset': "Back to the report's column order",
|
|
516
|
+
'report.order_help': "Drag a column, or use its arrows, to change the order.",
|
|
517
|
+
'report.move_up': "Move {column} up",
|
|
518
|
+
'report.move_down': "Move {column} down",
|
|
519
|
+
'report.moved': "{column}: position {n} of {total}",
|
|
520
|
+
'period.today': "today",
|
|
521
|
+
'period.yesterday': "yesterday",
|
|
522
|
+
'period.last_7_days': "the last 7 days",
|
|
523
|
+
'period.last_30_days': "the last 30 days",
|
|
524
|
+
'period.next_7_days': "the next 7 days",
|
|
525
|
+
'period.this_month': "this month",
|
|
526
|
+
'period.last_month': "last month",
|
|
527
|
+
'period.this_year': "this year",
|
|
528
|
+
'period.last_year': "last year",
|
|
505
529
|
'grid.delete_row': 'Delete row {row}',
|
|
506
530
|
'grid.new': 'new',
|
|
507
531
|
'grid.row_changed': 'Row {row}: this row was changed outside the grid; reload the page.',
|
|
@@ -1382,6 +1406,30 @@ const nl: Record<MessageKey, string> = {
|
|
|
1382
1406
|
'op.not_contains': 'bevat niet',
|
|
1383
1407
|
'op.null': 'is leeg',
|
|
1384
1408
|
'op.not_null': 'is niet leeg',
|
|
1409
|
+
'op.in': "is een van",
|
|
1410
|
+
'op.not_in': "is geen van",
|
|
1411
|
+
'op.between': "ligt tussen",
|
|
1412
|
+
'op.period': "valt in",
|
|
1413
|
+
'report.value_to': "Tot",
|
|
1414
|
+
'report.values': "Waarden",
|
|
1415
|
+
'report.period': "Periode",
|
|
1416
|
+
'report.and': "en",
|
|
1417
|
+
'report.filter_help': "Is een van: waarden gescheiden door komma's, of aangevinkt in de lijst. Ligt tussen: een van beide waarden mag leeg blijven. Valt in: een periode van een datumkolom.",
|
|
1418
|
+
'report.order_chip': "Eigen kolomvolgorde",
|
|
1419
|
+
'report.order_reset': "Terug naar de kolomvolgorde van het rapport",
|
|
1420
|
+
'report.order_help': "Sleep een kolom, of gebruik de pijlen, om de volgorde te veranderen.",
|
|
1421
|
+
'report.move_up': "{column} omhoog",
|
|
1422
|
+
'report.move_down': "{column} omlaag",
|
|
1423
|
+
'report.moved': "{column}: positie {n} van {total}",
|
|
1424
|
+
'period.today': "vandaag",
|
|
1425
|
+
'period.yesterday': "gisteren",
|
|
1426
|
+
'period.last_7_days': "de laatste 7 dagen",
|
|
1427
|
+
'period.last_30_days': "de laatste 30 dagen",
|
|
1428
|
+
'period.next_7_days': "de komende 7 dagen",
|
|
1429
|
+
'period.this_month': "deze maand",
|
|
1430
|
+
'period.last_month': "vorige maand",
|
|
1431
|
+
'period.this_year': "dit jaar",
|
|
1432
|
+
'period.last_year': "vorig jaar",
|
|
1385
1433
|
'grid.delete_row': 'Rij {row} verwijderen',
|
|
1386
1434
|
'grid.new': 'nieuw',
|
|
1387
1435
|
'grid.row_changed': 'Rij {row}: deze rij is buiten het raster gewijzigd; laad de pagina opnieuw.',
|
package/src/runtime/ai-filter.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { applyPlan, checkPlan, chipsOf, ChipRefused, editChip, planIsEmpty, remo
|
|
|
13
13
|
import { parseQuestion, type Lookup } from './ir-phrases.ts';
|
|
14
14
|
import { applyFacetSettings, clearFacets, facetSettings } from './ask-facets.ts';
|
|
15
15
|
import { describeFacetFilter, reportFacetDefs, type FacetFilter } from './facet-state.ts';
|
|
16
|
-
import { AGGREGATES, fieldsOf, headingOf, HIGHLIGHT_COLORS, isNumeric, opLabel, OPERATORS, q, reportState, visibleColumns, withComputations } from './report.ts';
|
|
16
|
+
import { AGGREGATES, describeFilter, fieldsOf, listValues, rangeValues, headingOf, HIGHLIGHT_COLORS, HIGHLIGHT_OPERATORS, isNumeric, opLabel, OPERATORS, PERIODS, q, reportState, visibleColumns, withComputations } from './report.ts';
|
|
17
17
|
import { resolveRestRegion } from './rest-sources.ts';
|
|
18
18
|
import { loadContext, simplePage, txContext, type Req } from './routes.ts';
|
|
19
19
|
|
|
@@ -152,7 +152,7 @@ export function planSchema(columns: Column[]) {
|
|
|
152
152
|
properties: {
|
|
153
153
|
column: { type: 'string', enum: names },
|
|
154
154
|
operator: { type: 'string', enum: ops },
|
|
155
|
-
value: { type: 'string', description:
|
|
155
|
+
value: { type: 'string', description: `The value to compare with (a date as YYYY-MM-DD, a number without thousands separators); empty for null and not_null; for in and not_in the values separated by commas; for between "from,to" (either may be empty); for period one of ${Object.keys(PERIODS).join(', ')} (date columns only).` },
|
|
156
156
|
},
|
|
157
157
|
required: ['column', 'operator', 'value'],
|
|
158
158
|
additionalProperties: false,
|
|
@@ -163,7 +163,7 @@ export function planSchema(columns: Column[]) {
|
|
|
163
163
|
description: 'Rows to color (not to filter), at most 5.',
|
|
164
164
|
items: {
|
|
165
165
|
type: 'object',
|
|
166
|
-
properties: { column: { type: 'string', enum: names }, operator: { type: 'string', enum:
|
|
166
|
+
properties: { column: { type: 'string', enum: names }, operator: { type: 'string', enum: HIGHLIGHT_OPERATORS }, value: { type: 'string' }, color: { type: 'string', enum: HIGHLIGHT_COLORS } },
|
|
167
167
|
required: ['column', 'operator', 'value', 'color'],
|
|
168
168
|
additionalProperties: false,
|
|
169
169
|
},
|
|
@@ -246,7 +246,7 @@ const pageFacets = (ctx: PageContext, rid: number) => reportFacetDefs(ctx.page.r
|
|
|
246
246
|
function describePlan(p: Plan, t: T, label: (n: string) => string, facets: FacetFilter[] = []) {
|
|
247
247
|
return [
|
|
248
248
|
...(p.reset ? [t('report.reset')] : []),
|
|
249
|
-
...p.filters.map((f) =>
|
|
249
|
+
...p.filters.map((f) => describeFilter(t, label(f.column), f.operator, f.value)),
|
|
250
250
|
...facets.map((f) => describeFacetFilter(f, label(f.column), t)),
|
|
251
251
|
...(p.search ? [`"${p.search}"`] : []),
|
|
252
252
|
...(p.sort ? [t('ai_filter.sort', { column: `${p.sort.label}${p.desc ? ' ↓' : ''}` })] : []),
|
|
@@ -261,9 +261,14 @@ function describePlan(p: Plan, t: T, label: (n: string) => string, facets: Facet
|
|
|
261
261
|
].join('; ');
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
/** (143) a filter's value as its Edit field shows it: a list's values and a range's bounds separated by commas */
|
|
265
|
+
const editValue = (op: string, v: string) =>
|
|
266
|
+
OPERATORS[op]?.kind === 'list' ? listValues(v).join(', ') : OPERATORS[op]?.kind === 'range' ? rangeValues(v).join(', ') : v;
|
|
267
|
+
|
|
264
268
|
/** A chip's text (plain: it is escaped where it is used). */
|
|
265
269
|
function chipText(chip: Chip, t: T, label: (n: string) => string, byPos: (pos: number) => string) {
|
|
266
|
-
|
|
270
|
+
// (143) a list's values, a range's bounds and a period in words
|
|
271
|
+
const cond = (column: string, op: string, value: string) => describeFilter(t, label(column), op, value);
|
|
267
272
|
switch (chip.kind) {
|
|
268
273
|
case 'search': return `${t('report.search_chip')}${chip.column ? ` ${label(chip.column)}:` : ''} ${chip.value}`;
|
|
269
274
|
case 'filter': return cond(chip.column, chip.op, chip.value);
|
|
@@ -332,7 +337,7 @@ export async function renderAiFilter(ctx: PageContext, r: Region): Promise<Raw |
|
|
|
332
337
|
if (!columns.length) return '';
|
|
333
338
|
switch (ch.kind) {
|
|
334
339
|
case 'search': return input(i, 'a', t('report.search'), ch.value);
|
|
335
|
-
case 'filter': return html`${colSelect(i, 'a', t('report.column'), ch.column)}${ops(i, ch.op)}${input(i, 'c', t('report.value'), ch.value)}`;
|
|
340
|
+
case 'filter': return html`${colSelect(i, 'a', t('report.column'), ch.column)}${ops(i, ch.op)}${input(i, 'c', t('report.value'), editValue(ch.op, ch.value))}`;
|
|
336
341
|
case 'highlight': return html`${colSelect(i, 'a', t('report.column'), ch.column)}${ops(i, ch.op)}${input(i, 'c', t('report.value'), ch.value)}${listSelect(i, 'd', t('report.color'), ch.color, HIGHLIGHT_COLORS.map((x) => [x, t(`color.${x}`)]))}`;
|
|
337
342
|
case 'sort': return html`${colSelect(i, 'a', t('report.column'), columns.find((x) => x.pos === ch.pos)?.name ?? '', (x) => x.pos > 0)}${listSelect(i, 'b', t('report.sort'), ch.desc ? 'desc' : 'asc', [['asc', t('report.sort_asc')], ['desc', t('report.sort_desc')]])}`;
|
|
338
343
|
case 'break': case 'group': return colSelect(i, 'a', t('report.column'), ch.column);
|
package/src/runtime/ir-plan.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { REPORT_CHART_KINDS } from './charts.ts';
|
|
2
2
|
import { ComputeError, computeNameOk, computeSql } from './compute.ts';
|
|
3
3
|
import { facetFilters, facetKeys, facetParamNames, type FacetDef } from './facet-state.ts';
|
|
4
|
-
import { AGGREGATES, HIGHLIGHT_COLORS, MAX_COMPUTATIONS, OPERATORS } from './report.ts';
|
|
4
|
+
import { AGGREGATES, filterOk, HIGHLIGHT_COLORS, HIGHLIGHT_OPERATORS, MAX_COMPUTATIONS, OPERATORS } from './report.ts';
|
|
5
5
|
|
|
6
6
|
// (sprint 112) What "Ask in your own words" may do to an interactive report
|
|
7
7
|
// (APEX 26.1/26.2: AI interactive reports). An answer, from the AI service's
|
|
@@ -122,9 +122,9 @@ export function checkPlan(json: unknown, columns: Column[], fieldCount = columns
|
|
|
122
122
|
.filter((f) => col(f.column) && typeof f.operator === 'string' && Object.hasOwn(OPERATORS, f.operator) && typeof f.value === 'string')
|
|
123
123
|
.slice(0, MAX_FILTERS)
|
|
124
124
|
.map((f) => ({ column: f.column as string, operator: f.operator as string, value: OPERATORS[f.operator as string].noValue ? '' : text(f.value) }))
|
|
125
|
-
.filter((f) => OPERATORS[f.operator].noValue || f.value !== '');
|
|
125
|
+
.filter((f) => OPERATORS[f.operator].noValue || (f.value !== '' && filterOk(f.operator, f.value)));
|
|
126
126
|
const highlights = list<{ column: unknown; operator: unknown; value: unknown; color: unknown }>(a.highlights)
|
|
127
|
-
.filter((h) => col(h.column) && typeof h.operator === 'string' &&
|
|
127
|
+
.filter((h) => col(h.column) && typeof h.operator === 'string' && HIGHLIGHT_OPERATORS.includes(h.operator) && typeof h.value === 'string')
|
|
128
128
|
.slice(0, MAX_HIGHLIGHTS)
|
|
129
129
|
.map((h) => ({
|
|
130
130
|
column: h.column as string, operator: h.operator as string, value: OPERATORS[h.operator as string].noValue ? '' : text(h.value),
|
package/src/runtime/pdf.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { Region } from '../metadata.ts';
|
|
|
6
6
|
import { runtime, savepoint } from '../db.ts';
|
|
7
7
|
import { substitute, type PageContext } from './context.ts';
|
|
8
8
|
import { describeFacetFilter, facetFilters, reportFacetDefs } from './facet-state.ts';
|
|
9
|
-
import { buildSql, cell, columnFormats, headingOf, isNumeric, maxRows,
|
|
9
|
+
import { buildSql, cell, columnFormats, describeFilter, headingOf, isNumeric, maxRows, orderedColumns, PDF_MAX_ROWS, reportState } from './report.ts';
|
|
10
10
|
|
|
11
11
|
// Report printing: Actions → Download PDF. The same query, filters, sort
|
|
12
12
|
// and visibility as the report on screen (and as the CSV download), drawn
|
|
@@ -134,10 +134,10 @@ export function layoutText(text: string, extra: Record<string, string>, ctx?: Pa
|
|
|
134
134
|
return ctx ? substitute(replaced, ctx, (v) => v) : replaced;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
/** The columns a report prints, in order: its "pdf.columns", or those on screen. */
|
|
138
|
-
function printColumns(r: Region, fields: pg.FieldDef[]) {
|
|
137
|
+
/** The columns a report prints, in order: its "pdf.columns", or those on screen (143: in the user's order, without the ones they hid). */
|
|
138
|
+
function printColumns(r: Region, fields: pg.FieldDef[], st: { hideCols: string[]; order: string[] }) {
|
|
139
139
|
const wanted = (r.config.pdf as RegionPdf | undefined)?.columns;
|
|
140
|
-
if (!Array.isArray(wanted) || !wanted.length) return
|
|
140
|
+
if (!Array.isArray(wanted) || !wanted.length) return orderedColumns(r, fields, st);
|
|
141
141
|
const byName = new Map(fields.map((f, i) => [f.name.toLowerCase(), { f, i }]));
|
|
142
142
|
return wanted.flatMap((n) => {
|
|
143
143
|
const c = typeof n === 'string' ? byName.get(n.toLowerCase()) : undefined;
|
|
@@ -158,7 +158,7 @@ export async function reportPdf(ctx: PageContext, r: Region): Promise<Buffer> {
|
|
|
158
158
|
await savepoint(c, () => c.query({ text: `declare ${cursor} no scroll cursor for ${query.text}`, values: query.values }));
|
|
159
159
|
const fetch = () => savepoint(c, () => c.query({ text: `fetch ${PDF_BATCH} from ${cursor}`, rowMode: 'array' }));
|
|
160
160
|
const first = await fetch();
|
|
161
|
-
const cols = printColumns(r, first.fields);
|
|
161
|
+
const cols = printColumns(r, first.fields, st);
|
|
162
162
|
const limit = Math.min(PDF_MAX_ROWS, maxRows(r, null) ?? PDF_MAX_ROWS);
|
|
163
163
|
let truncated = false;
|
|
164
164
|
const fmtOf = columnFormats(ctx, r);
|
|
@@ -190,7 +190,7 @@ export async function reportPdf(ctx: PageContext, r: Region): Promise<Buffer> {
|
|
|
190
190
|
const title = text(layout.title ?? '&REPORT_TITLE.');
|
|
191
191
|
const filters = layout.show_filters
|
|
192
192
|
? [
|
|
193
|
-
...st.filters.map((f) =>
|
|
193
|
+
...st.filters.map((f) => describeFilter(t, headingOf(r, f.column, ctx.locale.tr), f.op, f.value)),
|
|
194
194
|
...(() => {
|
|
195
195
|
const defs = reportFacetDefs(ctx.page.regions, r.id, ctx.vis?.regions);
|
|
196
196
|
return facetFilters(ctx.params, r.id, defs, undefined, appDateReader(ctx)).map((f) => describeFacetFilter(f, defs.get(f.column)?.label ?? headingOf(r, f.column, ctx.locale.tr), t, defs.get(f.column)));
|
package/src/runtime/render.ts
CHANGED
|
@@ -327,7 +327,7 @@ const CLIENT_TEXTS = ['pwa.offline_banner', 'pwa.queued', 'pwa.queue_waiting', '
|
|
|
327
327
|
'push.turn_on', 'push.turn_off', 'push.on', 'push.off', 'push.blocked', 'push.unsupported', 'push.failed', 'page.unsaved_changes', 'page.link_copied', 'da.wait',
|
|
328
328
|
'session.warning', 'session.stay', 'session.max', 'session.ended', 'login.sign_in_link',
|
|
329
329
|
// (sprint 76) a report column heading's menu
|
|
330
|
-
'report.sort_asc', 'report.sort_desc', 'report.hide', 'report.break', 'report.filter_values', 'report.no_values',
|
|
330
|
+
'report.sort_asc', 'report.sort_desc', 'report.hide', 'report.break', 'report.filter_values', 'report.no_values', 'report.moved',
|
|
331
331
|
// (sprint 84) the date picker
|
|
332
332
|
'item.choose_date', 'calendar.previous', 'calendar.next', 'calendar.today', 'facets.clear_short'] as const;
|
|
333
333
|
export const clientTexts = (ctx: PageContext) => Object.fromEntries(CLIENT_TEXTS.map((k) => [k, ctx.locale.t(k)]));
|