Browse Source

Merge branch 'develop' into feat/attachments

merge with changes in develop
pull/4820/head
Raju Udava 2 years ago
parent
commit
e4c76242a9
  1. 7
      packages/nc-gui/assets/style.scss
  2. 4
      packages/nc-gui/components/cell/Currency.vue
  3. 5
      packages/nc-gui/components/cell/DatePicker.vue
  4. 7
      packages/nc-gui/components/cell/DateTimePicker.vue
  5. 3
      packages/nc-gui/components/cell/Decimal.vue
  6. 4
      packages/nc-gui/components/cell/Duration.vue
  7. 4
      packages/nc-gui/components/cell/Email.vue
  8. 3
      packages/nc-gui/components/cell/Float.vue
  9. 3
      packages/nc-gui/components/cell/Integer.vue
  10. 4
      packages/nc-gui/components/cell/Json.vue
  11. 3
      packages/nc-gui/components/cell/Percent.vue
  12. 4
      packages/nc-gui/components/cell/Text.vue
  13. 4
      packages/nc-gui/components/cell/TextArea.vue
  14. 7
      packages/nc-gui/components/cell/TimePicker.vue
  15. 4
      packages/nc-gui/components/cell/Url.vue
  16. 5
      packages/nc-gui/components/cell/YearPicker.vue
  17. 6
      packages/nc-gui/components/dashboard/settings/Misc.vue
  18. 1
      packages/nc-gui/composables/useGlobal/state.ts
  19. 1
      packages/nc-gui/composables/useGlobal/types.ts
  20. 224
      packages/nc-gui/lang/pl.json
  21. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  22. 9
      packages/nocodb/src/lib/meta/helpers/apiMetrics.ts
  23. 2
      tests/playwright/pages/Dashboard/Settings/Miscellaneous.ts

7
packages/nc-gui/assets/style.scss

@ -294,3 +294,10 @@ a {
.ant-select-selection-search-input:focus { .ant-select-selection-search-input:focus {
@apply !ring-0; @apply !ring-0;
} }
.nc-null {
@apply text-gray-300 italic;
input::placeholder {
@apply text-gray-300 italic;
}
}

4
packages/nc-gui/components/cell/Currency.vue

@ -10,6 +10,8 @@ const props = defineProps<Props>()
const emit = defineEmits(['update:modelValue', 'save']) const emit = defineEmits(['update:modelValue', 'save'])
const { showNull } = useGlobal()
const column = inject(ColumnInj)! const column = inject(ColumnInj)!
const editEnabled = inject(EditModeInj)! const editEnabled = inject(EditModeInj)!
@ -81,6 +83,8 @@ onMounted(() => {
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else-if="vModel">{{ currency }}</span> <span v-else-if="vModel">{{ currency }}</span>
<span v-else /> <span v-else />

5
packages/nc-gui/components/cell/DatePicker.vue

@ -22,6 +22,8 @@ const { modelValue, isPk } = defineProps<Props>()
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const { showNull } = useGlobal()
const columnMeta = inject(ColumnInj, null)! const columnMeta = inject(ColumnInj, null)!
const readOnly = inject(ReadonlyInj, ref(false)) const readOnly = inject(ReadonlyInj, ref(false))
@ -71,7 +73,7 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (isDateInvalid ? 'Invalid date' : '')) const placeholder = computed(() => (modelValue === null && showNull.value ? 'NULL' : isDateInvalid ? 'Invalid date' : ''))
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => { useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) { switch (e.key) {
@ -169,6 +171,7 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
v-model:value="localState" v-model:value="localState"
:bordered="false" :bordered="false"
class="!w-full !px-0 !border-none" class="!w-full !px-0 !border-none"
:class="{ 'nc-null': modelValue === null && showNull }"
:format="dateFormat" :format="dateFormat"
:placeholder="placeholder" :placeholder="placeholder"
:allow-clear="!readOnly && !localState && !isPk" :allow-clear="!readOnly && !localState && !isPk"

7
packages/nc-gui/components/cell/DateTimePicker.vue

@ -25,6 +25,8 @@ const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject() const { isMysql } = useProject()
const { showNull } = useGlobal()
const readOnly = inject(ReadonlyInj, ref(false)) const readOnly = inject(ReadonlyInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
@ -79,6 +81,8 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (modelValue === null && showNull.value ? 'NULL' : isDateInvalid ? 'Invalid date' : ''))
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => { useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) { switch (e.key) {
case 'Enter': case 'Enter':
@ -172,8 +176,9 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
:show-time="true" :show-time="true"
:bordered="false" :bordered="false"
class="!w-full !px-0 !border-none" class="!w-full !px-0 !border-none"
:class="{ 'nc-null': modelValue === null && showNull }"
:format="dateTimeFormat" :format="dateTimeFormat"
:placeholder="isDateInvalid ? 'Invalid date' : ''" :placeholder="placeholder"
:allow-clear="!readOnly && !localState && !isPk" :allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true" :input-read-only="true"
:dropdown-class-name="`${randomClass} nc-picker-datetime ${open ? 'active' : ''}`" :dropdown-class-name="`${randomClass} nc-picker-datetime ${open ? 'active' : ''}`"

3
packages/nc-gui/components/cell/Decimal.vue

@ -14,6 +14,8 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const _vModel = useVModel(props, 'modelValue', emits) const _vModel = useVModel(props, 'modelValue', emits)
@ -49,6 +51,7 @@ const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
@selectstart.capture.stop @selectstart.capture.stop
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else class="text-sm">{{ vModel }}</span> <span v-else class="text-sm">{{ vModel }}</span>
</template> </template>

4
packages/nc-gui/components/cell/Duration.vue

@ -19,6 +19,8 @@ const { modelValue } = defineProps<Props>()
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const { showNull } = useGlobal()
const column = inject(ColumnInj) const column = inject(ColumnInj)
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
@ -93,6 +95,8 @@ const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="modelValue === null && showNull" class="nc-null">NULL</span>
<span v-else> {{ localState }}</span> <span v-else> {{ localState }}</span>
<div v-if="showWarningMessage" class="duration-warning"> <div v-if="showWarningMessage" class="duration-warning">

4
packages/nc-gui/components/cell/Email.vue

@ -14,6 +14,8 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const vModel = useVModel(props, 'modelValue', emits) const vModel = useVModel(props, 'modelValue', emits)
@ -39,6 +41,8 @@ const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<a v-else-if="validEmail" class="text-sm underline hover:opacity-75" :href="`mailto:${vModel}`" target="_blank"> <a v-else-if="validEmail" class="text-sm underline hover:opacity-75" :href="`mailto:${vModel}`" target="_blank">
{{ vModel }} {{ vModel }}
</a> </a>

3
packages/nc-gui/components/cell/Float.vue

@ -14,6 +14,8 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const _vModel = useVModel(props, 'modelValue', emits) const _vModel = useVModel(props, 'modelValue', emits)
@ -49,6 +51,7 @@ const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
@selectstart.capture.stop @selectstart.capture.stop
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else class="text-sm">{{ vModel }}</span> <span v-else class="text-sm">{{ vModel }}</span>
</template> </template>

3
packages/nc-gui/components/cell/Integer.vue

@ -14,6 +14,8 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const _vModel = useVModel(props, 'modelValue', emits) const _vModel = useVModel(props, 'modelValue', emits)
@ -53,6 +55,7 @@ function onKeyDown(evt: KeyboardEvent) {
@selectstart.capture.stop @selectstart.capture.stop
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else class="text-sm">{{ vModel }}</span> <span v-else class="text-sm">{{ vModel }}</span>
</template> </template>

4
packages/nc-gui/components/cell/Json.vue

@ -25,6 +25,8 @@ const props = defineProps<Props>()
const emits = defineEmits<Emits>() const emits = defineEmits<Emits>()
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj, ref(false)) const editEnabled = inject(EditModeInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
@ -154,6 +156,8 @@ useSelectedCellKeyupListener(active, (e) => {
</span> </span>
</div> </div>
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else>{{ vModel }}</span> <span v-else>{{ vModel }}</span>
</component> </component>
</template> </template>

3
packages/nc-gui/components/cell/Percent.vue

@ -10,6 +10,8 @@ const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue']) const emits = defineEmits(['update:modelValue'])
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const _vModel = useVModel(props, 'modelValue', emits) const _vModel = useVModel(props, 'modelValue', emits)
@ -47,5 +49,6 @@ const focus: VNodeRef = (el) => {
@selectstart.capture.stop @selectstart.capture.stop
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<span v-else>{{ vModel }}</span> <span v-else>{{ vModel }}</span>
</template> </template>

4
packages/nc-gui/components/cell/Text.vue

@ -10,6 +10,8 @@ const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue']) const emits = defineEmits(['update:modelValue'])
const { showNull } = useGlobal()
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const readonly = inject(ReadonlyInj, ref(false)) const readonly = inject(ReadonlyInj, ref(false))
@ -38,5 +40,7 @@ const focus: VNodeRef = (el) => {
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<LazyCellClampedText v-else :value="vModel" :lines="1" /> <LazyCellClampedText v-else :value="vModel" :lines="1" />
</template> </template>

4
packages/nc-gui/components/cell/TextArea.vue

@ -11,6 +11,8 @@ const emits = defineEmits(['update:modelValue'])
const editEnabled = inject(EditModeInj) const editEnabled = inject(EditModeInj)
const { showNull } = useGlobal()
const view = inject(ActiveViewInj, ref()) const view = inject(ActiveViewInj, ref())
const vModel = useVModel(props, 'modelValue', emits, { defaultValue: '' }) const vModel = useVModel(props, 'modelValue', emits, { defaultValue: '' })
@ -55,6 +57,8 @@ const rowHeight = computed(() => {
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<LazyCellClampedText v-else-if="rowHeight" :value="vModel" :lines="rowHeight" /> <LazyCellClampedText v-else-if="rowHeight" :value="vModel" :lines="rowHeight" />
<span v-else>{{ vModel }}</span> <span v-else>{{ vModel }}</span>

7
packages/nc-gui/components/cell/TimePicker.vue

@ -13,6 +13,8 @@ const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject() const { isMysql } = useProject()
const { showNull } = useGlobal()
const readOnly = inject(ReadonlyInj, ref(false)) const readOnly = inject(ReadonlyInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
@ -72,6 +74,8 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (modelValue === null && showNull.value ? 'NULL' : isTimeInvalid ? 'Invalid time' : ''))
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => { useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) { switch (e.key) {
case 'Enter': case 'Enter':
@ -97,7 +101,8 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
use12-hours use12-hours
format="HH:mm" format="HH:mm"
class="!w-full !px-0 !border-none" class="!w-full !px-0 !border-none"
:placeholder="isTimeInvalid ? 'Invalid time' : ''" :class="{ 'nc-null': modelValue === null && showNull }"
:placeholder="placeholder"
:allow-clear="!readOnly && !localState && !isPk" :allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true" :input-read-only="true"
:open="(readOnly || (localState && isPk)) && !active && !editable ? false : open" :open="(readOnly || (localState && isPk)) && !active && !editable ? false : open"

4
packages/nc-gui/components/cell/Url.vue

@ -24,6 +24,8 @@ const emit = defineEmits(['update:modelValue'])
const { t } = useI18n() const { t } = useI18n()
const { showNull } = useGlobal()
const column = inject(ColumnInj)! const column = inject(ColumnInj)!
const editEnabled = inject(EditModeInj)! const editEnabled = inject(EditModeInj)!
@ -88,6 +90,8 @@ watch(
@mousedown.stop @mousedown.stop
/> />
<span v-else-if="vModel === null && showNull" class="nc-null">NULL</span>
<nuxt-link <nuxt-link
v-else-if="isValid && !cellUrlOptions?.overlay" v-else-if="isValid && !cellUrlOptions?.overlay"
no-prefetch no-prefetch

5
packages/nc-gui/components/cell/YearPicker.vue

@ -11,6 +11,8 @@ const { modelValue, isPk = false } = defineProps<Props>()
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const { showNull } = useGlobal()
const readOnly = inject(ReadonlyInj, ref(false)) const readOnly = inject(ReadonlyInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
@ -58,7 +60,7 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (isYearInvalid ? 'Invalid year' : '')) const placeholder = computed(() => (modelValue === null && showNull.value ? 'NULL' : isYearInvalid ? 'Invalid year' : ''))
useSelectedCellKeyupListener(active, (e: KeyboardEvent) => { useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
switch (e.key) { switch (e.key) {
@ -82,6 +84,7 @@ useSelectedCellKeyupListener(active, (e: KeyboardEvent) => {
picker="year" picker="year"
:bordered="false" :bordered="false"
class="!w-full !px-0 !border-none" class="!w-full !px-0 !border-none"
:class="{ 'nc-null': modelValue === null && showNull }"
:placeholder="placeholder" :placeholder="placeholder"
:allow-clear="!readOnly && !localState && !isPk" :allow-clear="!readOnly && !localState && !isPk"
:input-read-only="true" :input-read-only="true"

6
packages/nc-gui/components/dashboard/settings/Misc.vue

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useGlobal, useProject, watch } from '#imports' import { useGlobal, useProject, watch } from '#imports'
const { includeM2M } = useGlobal() const { includeM2M, showNull } = useGlobal()
const { loadTables } = useProject() const { loadTables } = useProject()
watch(includeM2M, async () => await loadTables()) watch(includeM2M, async () => await loadTables())
@ -16,6 +16,10 @@ watch(includeM2M, async () => await loadTables())
{{ $t('msg.info.showM2mTables') }} {{ $t('msg.info.showM2mTables') }}
</a-checkbox> </a-checkbox>
</div> </div>
<div class="flex flex-row items-center w-full mb-4 gap-2">
<!-- Show NULL -->
<a-checkbox v-model:checked="showNull" v-e="['c:settings:show-null']" class="nc-settings-show-null">Show NULL</a-checkbox>
</div>
</div> </div>
</div> </div>
</template> </template>

1
packages/nc-gui/composables/useGlobal/state.ts

@ -62,6 +62,7 @@ export function useGlobalState(storageKey = 'nocodb-gui-v2'): State {
filterAutoSave: true, filterAutoSave: true,
previewAs: null, previewAs: null,
includeM2M: false, includeM2M: false,
showNull: false,
currentVersion: null, currentVersion: null,
latestRelease: null, latestRelease: null,
hiddenRelease: null, hiddenRelease: null,

1
packages/nc-gui/composables/useGlobal/types.ts

@ -30,6 +30,7 @@ export interface StoredState {
filterAutoSave: boolean filterAutoSave: boolean
previewAs: ProjectRole | null previewAs: ProjectRole | null
includeM2M: boolean includeM2M: boolean
showNull: boolean
currentVersion: string | null currentVersion: string | null
latestRelease: string | null latestRelease: string | null
hiddenRelease: string | null hiddenRelease: string | null

224
packages/nc-gui/lang/pl.json

@ -1,31 +1,31 @@
{ {
"general": { "general": {
"home": "Dom", "home": "Start",
"load": "Obciążenie", "load": "Załaduj",
"open": "otwarty", "open": "Otwórz",
"close": "Blisko", "close": "Zamknij",
"yes": "tak", "yes": "Tak",
"no": "Nie", "no": "Nie",
"ok": "ok", "ok": "OK",
"and": "i", "and": "i",
"or": "Lub", "or": "Lub",
"add": "Dodać", "add": "Dodaj",
"edit": "Edytować", "edit": "Edytuj",
"remove": "Usunąć", "remove": "Usuń",
"save": "Zapis", "save": "Zapisz",
"cancel": "Anuluj", "cancel": "Anuluj",
"submit": "Składać", "submit": "Zapisz",
"create": "Utwórz", "create": "Utwórz",
"duplicate": "Duplikuj", "duplicate": "Duplikuj",
"insert": "Wstaw", "insert": "Wstaw",
"delete": "Kasować", "delete": "Usuń",
"update": "Aktualizacja", "update": "Aktualizuj",
"rename": "Przemianować", "rename": "Zmień nazwę",
"reload": "Przeładować", "reload": "Przeładuj",
"reset": "Resetowanie", "reset": "Reset",
"install": "zainstalować", "install": "Zainstaluj",
"show": "Pokazać", "show": "Pokaż",
"hide": "Ukrywać", "hide": "Ukryj",
"showAll": "Pokaż wszystko", "showAll": "Pokaż wszystko",
"hideAll": "Schowaj wszystko", "hideAll": "Schowaj wszystko",
"showMore": "Pokaż więcej", "showMore": "Pokaż więcej",
@ -33,31 +33,31 @@
"hideOptions": "Ukryj opcje", "hideOptions": "Ukryj opcje",
"showMenu": "Pokaż menu", "showMenu": "Pokaż menu",
"hideMenu": "Ukryj menu", "hideMenu": "Ukryj menu",
"addAll": "Dodać wszystko", "addAll": "Dodaj wszystko",
"removeAll": "Usuń wszystko", "removeAll": "Usuń wszystko",
"signUp": "Zapisać się", "signUp": "ZAREJESTRUJ SIĘ",
"signIn": "ZALOGUJ SIĘ", "signIn": "Zaloguj",
"signOut": "Wyloguj się", "signOut": "Wyloguj",
"required": "Wymagany", "required": "Wymagany",
"preferred": "Preferowany", "preferred": "Preferowany",
"mandatory": "Obowiązkowy", "mandatory": "Obowiązkowy",
"loading": "Ładowanie ...", "loading": "Ładowanie ...",
"title": "Tytuł", "title": "Tytuł",
"upload": "Wgrywać", "upload": "Prześlij",
"download": "Pobier", "download": "Pobierz",
"default": "Domyślna", "default": "Domyślny",
"more": "Więcej", "more": "Więcej",
"less": "Mniej", "less": "Mniej",
"event": "Wydarzenie", "event": "Zdarzenie",
"condition": "Stan: schorzenie", "condition": "Stan",
"after": "Później", "after": "Po",
"before": "Zanim", "before": "Przed",
"search": "Szukaj", "search": "Szukaj",
"notification": "Powiadomienie", "notification": "Powiadomienie",
"reference": "Sprawdzenie", "reference": "Odniesienie",
"function": "Funkcjonować", "function": "Funkcja",
"confirm": "Zatwierdź", "confirm": "Zatwierdź",
"generate": "Wygeneruj", "generate": "Generuj",
"copy": "Kopiuj", "copy": "Kopiuj",
"misc": "Pozostałe", "misc": "Pozostałe",
"lock": "Zablokuj", "lock": "Zablokuj",
@ -74,51 +74,51 @@
"insertBefore": "Wstaw przed", "insertBefore": "Wstaw przed",
"hideField": "Ukryj pole", "hideField": "Ukryj pole",
"sortAsc": "Sortowanie rosnące", "sortAsc": "Sortowanie rosnące",
"sortDesc": "Sortuj w dół" "sortDesc": "Sortuj malejąco"
}, },
"objects": { "objects": {
"project": "Projekt", "project": "Projekt",
"projects": "Projektowanie", "projects": "Projekty",
"table": "Tabela", "table": "Tabela",
"tables": "Stoły", "tables": "Tabele",
"field": "Pole", "field": "Pole",
"fields": "Pola", "fields": "Pola",
"column": "Kolumna", "column": "Kolumna",
"columns": "Kolumny", "columns": "Kolumny",
"page": "Strona", "page": "Strona",
"pages": "Strony", "pages": "Strony",
"record": "Nagrywać", "record": "rekord",
"records": "Dokumentacja", "records": "rekordy",
"webhook": "WebHook.", "webhook": "WebHook.",
"webhooks": "Webhooks.", "webhooks": "Webhooks.",
"view": "Pogląd", "view": "Widok",
"views": "Wyświetlenia", "views": "Widoki",
"viewType": { "viewType": {
"grid": "Siatka", "grid": "Tabela",
"gallery": "Galeria", "gallery": "Galeria",
"form": "Formularz", "form": "Formularz",
"kanban": "Kanban.", "kanban": "Kanban",
"calendar": "Kalendarz" "calendar": "Kalendarz"
}, },
"user": "Użytkownik", "user": "Użytkownik",
"users": "Użytkownicy.", "users": "Użytkownicy",
"role": "Rola", "role": "Rola",
"roles": "Role.", "roles": "Role",
"roleType": { "roleType": {
"owner": "Właściciel", "owner": "Właściciel",
"creator": "Twórca", "creator": "Projektant",
"editor": "Redaktor", "editor": "Edytor",
"commenter": "Komentator", "commenter": "Komentator",
"viewer": "Widz", "viewer": "Obserwator",
"orgLevelCreator": "Poziom organizacji Twórca", "orgLevelCreator": "Poziom organizacji Projektant",
"orgLevelViewer": "Przeglądarka poziomu organizacji" "orgLevelViewer": "Poziomu organizacji obserwator"
}, },
"sqlVIew": "Widok SQL" "sqlVIew": "Widok SQL"
}, },
"datatype": { "datatype": {
"ID": "Identyfikator", "ID": "Identyfikator",
"ForeignKey": "Klucz obcy", "ForeignKey": "Klucz obcy",
"SingleLineText": "Tekst pojedynczy linii", "SingleLineText": "Tekst w pojedynczej linii",
"LongText": "Długi tekst", "LongText": "Długi tekst",
"Attachment": "Załącznik", "Attachment": "Załącznik",
"Checkbox": "Pole wyboru", "Checkbox": "Pole wyboru",
@ -138,20 +138,20 @@
"Duration": "Czas trwania", "Duration": "Czas trwania",
"Rating": "Ocena", "Rating": "Ocena",
"Formula": "Formuła", "Formula": "Formuła",
"Rollup": "Rollup.", "Rollup": "Zliczanie",
"Count": "Licz", "Count": "Licznik",
"Lookup": "Spojrzeć w górę", "Lookup": "Wyszukaj",
"DateTime": "Czas daty", "DateTime": "Data",
"CreateTime": "Utwórz czas", "CreateTime": "Data utworzenia",
"LastModifiedTime": "Ostatni zmodyfikowany czas", "LastModifiedTime": "Data modyfikacji",
"AutoNumber": "Numer samochodu", "AutoNumber": "Automatyczny numer",
"Barcode": "kod kreskowy", "Barcode": "Kod kreskowy",
"Button": "Przycisk", "Button": "Przycisk",
"Password": "Hasło", "Password": "Hasło",
"relationProperties": { "relationProperties": {
"noAction": "Bez akcji", "noAction": "Bez akcji",
"cascade": "Kaskada", "cascade": "Kaskada",
"restrict": "Ogranicz", "restrict": "Ograniczenie",
"setNull": "Ustaw null.", "setNull": "Ustaw null.",
"setDefault": "Ustaw domyślny" "setDefault": "Ustaw domyślny"
} }
@ -159,8 +159,8 @@
"filterOperation": { "filterOperation": {
"isEqual": "jest równy", "isEqual": "jest równy",
"isNotEqual": "nie jest równy", "isNotEqual": "nie jest równy",
"isLike": "jest jak", "isLike": "podobny do",
"isNot like": "nie jest taki", "isNot like": "różny od",
"isEmpty": "jest pusty", "isEmpty": "jest pusty",
"isNotEmpty": "nie jest pusty", "isNotEmpty": "nie jest pusty",
"isNull": "jest null.", "isNull": "jest null.",
@ -170,31 +170,31 @@
"erdView": "Widok ERD", "erdView": "Widok ERD",
"newProj": "Nowy projekt", "newProj": "Nowy projekt",
"myProject": "Moje projekty", "myProject": "Moje projekty",
"formTitle": "Tytuł formy", "formTitle": "Tytuł formularza",
"collabView": "Widok współpracy", "collabView": "Współtworzony",
"lockedView": "Zamknięty widok", "lockedView": "Zablokowany widok",
"personalView": "Widok osobisty", "personalView": "Widok osobisty",
"appStore": "Sklep z aplikacjami", "appStore": "Sklep z aplikacjami",
"teamAndAuth": "Team & Auth.", "teamAndAuth": "Zespół i autoryzacja",
"rolesUserMgmt": "Role i zarządzanie użytkownikami", "rolesUserMgmt": "Role i zarządzanie użytkownikami",
"userMgmt": "Zarządzanie użytkownikami", "userMgmt": "Zarządzanie użytkownikami",
"apiTokenMgmt": "Zarządzanie Tokeny API.", "apiTokenMgmt": "Zarządzanie Tokenami API",
"rolesMgmt": "Zarządzanie rólami", "rolesMgmt": "Zarządzanie rolami",
"projMeta": "Metadane projektu.", "projMeta": "Metadane projektu.",
"metaMgmt": "Meta Management.", "metaMgmt": "Zarządzanie Meta",
"metadata": "Metadata.", "metadata": "Metadata",
"exportImportMeta": "Eksport / Importuj metadane", "exportImportMeta": "Eksport / Importuj Metadane",
"uiACL": "Kontrola dostępu do interfejsu użytkownika", "uiACL": "Kontrola dostępu do interfejsu użytkownika",
"metaOperations": "Operacje metadanych", "metaOperations": "Operacje na metadanych",
"audit": "Rewizja", "audit": "Rewizja",
"auditLogs": "Dziennik kontroli", "auditLogs": "Dziennik zmian",
"sqlMigrations": "Migracje SQL.", "sqlMigrations": "Migracja SQL",
"dbCredentials": "Poświadczenia bazy danych.", "dbCredentials": "Poświadczenia bazy danych",
"advancedParameters": "Parametry SSL i zaawansowane", "advancedParameters": "SSL i parametry zaawansowane",
"headCreateProject": "Utwórz projekt |. NOCODB.", "headCreateProject": "Utwórz projekt | Nocodb",
"headLogin": "Zaloguj się | NOCODB.", "headLogin": "Zaloguj się | Nocodb",
"resetPassword": "Zresetuj swoje hasło", "resetPassword": "Resetowanie hasła",
"teamAndSettings": "Ustawienia zespołu", "teamAndSettings": "Zespół i ustawienia",
"apiDocs": "Dokumentacja API", "apiDocs": "Dokumentacja API",
"importFromAirtable": "Importuj z Airtable", "importFromAirtable": "Importuj z Airtable",
"generateToken": "Wygeneruj token", "generateToken": "Wygeneruj token",
@ -209,19 +209,19 @@
}, },
"labels": { "labels": {
"createdBy": "Stworzony przez", "createdBy": "Stworzony przez",
"notifyVia": "Powiadomić VIA.", "notifyVia": "Powiadomienie przez",
"projName": "Nazwa Projektu", "projName": "Nazwa Projektu",
"tableName": "Nazwa tabeli", "tableName": "Nazwa tabeli",
"viewName": "Zobacz nazwę.", "viewName": "Nazwa widoku",
"viewLink": "Wyświetl link", "viewLink": "Zobacz link",
"columnName": "Nazwa kolumny", "columnName": "Nazwa kolumny",
"columnType": "Typ kolumny", "columnType": "Typ kolumny",
"roleName": "Nazwa roli.", "roleName": "Nazwa roli",
"roleDescription": "opis roli", "roleDescription": "Opisy roli",
"databaseType": "Wpisz bazy danych", "databaseType": "Typ w bazie danych",
"lengthValue": "Długość / wartość", "lengthValue": "Długość / wartość",
"dbType": "Typ bazy danych.", "dbType": "Typ bazy danych",
"sqliteFile": "Plik sqlite.", "sqliteFile": "Plik SQLite",
"hostAddress": "Adres hosta", "hostAddress": "Adres hosta",
"port": "Numer portu", "port": "Numer portu",
"username": "Nazwa użytkownika", "username": "Nazwa użytkownika",
@ -229,13 +229,13 @@
"schemaName": "Nazwa schematu", "schemaName": "Nazwa schematu",
"database": "Baza danych", "database": "Baza danych",
"action": "Akcja", "action": "Akcja",
"actions": "działania", "actions": "Akcje",
"operation": "Operacja", "operation": "Operacja",
"operationType": "Typ pracy", "operationType": "Typ operacji",
"operationSubType": "Podtypowy typ pracy", "operationSubType": "Podtypowy akcji",
"description": "Opis", "description": "Opis",
"authentication": "Uwierzytelnianie", "authentication": "Uwierzytelnianie",
"token": "Znak", "token": "Token",
"where": "Gdzie", "where": "Gdzie",
"cache": "Pamięć podręczna", "cache": "Pamięć podręczna",
"chat": "Czat", "chat": "Czat",
@ -243,49 +243,49 @@
"storage": "Przechowywanie", "storage": "Przechowywanie",
"uiAcl": "UI-ACL", "uiAcl": "UI-ACL",
"models": "Modele", "models": "Modele",
"syncState": "Synchronizowany stan", "syncState": "Stan synchronizacji",
"created": "Utworzony", "created": "Utworzony",
"sqlOutput": "Wyjście SQL.", "sqlOutput": "Wyjście SQL.",
"addOption": "Dodaj opcję.", "addOption": "Dodaj opcję",
"qrCodeValueColumn": "Kolumna z wartością kodu QR", "qrCodeValueColumn": "Kolumna z wartością kodu QR",
"barcodeValueColumn": "Kolumna z wartością kodu kreskowego", "barcodeValueColumn": "Kolumna z wartością kodu kreskowego",
"barcodeFormat": "Format kodu kreskowego", "barcodeFormat": "Format kodu kreskowego",
"qrCodeValueTooLong": "Zbyt wiele znaków dla kodu QR", "qrCodeValueTooLong": "Zbyt wiele znaków dla kodu QR",
"barcodeValueTooLong": "Zbyt wiele znaków dla kodu kreskowego", "barcodeValueTooLong": "Zbyt wiele znaków dla kodu kreskowego",
"aggregateFunction": "Funkcja kruszywa", "aggregateFunction": "Funkcja agregacji",
"dbCreateIfNotExists": "Baza danych: Utwórz, jeśli nie istnieje", "dbCreateIfNotExists": "Baza danych: Utwórz, jeśli nie istnieje",
"clientKey": "Klucz klienta", "clientKey": "Klucz klienta",
"clientCert": "Cert Client.", "clientCert": "Certyfikat klienta",
"serverCA": "Serwer ca.", "serverCA": "Serwer ca.",
"requriedCa": "Wymagany-ca.", "requriedCa": "Wymagany-CA",
"requriedIdentity": "Wymagana tożsamość", "requriedIdentity": "Wymagana IDENTYFIKACJA",
"inflection": { "inflection": {
"tableName": "Nazwa tabeli", "tableName": "Nazwa tabeli",
"columnName": "Fleksja - Nazwa kolumny" "columnName": "Nazwa tabeli"
}, },
"community": { "community": {
"starUs1": "Gwiazda", "starUs1": "Gwiazda",
"starUs2": "My na Github.", "starUs2": "My na Github.",
"bookDemo": "Zarezerwuj darmowe demo", "bookDemo": "Zarezerwuj darmowe demo",
"getAnswered": "Odpowiedzi na pytania", "getAnswered": "Odpowiedzi na pytania",
"joinDiscord": "Dołącz do Discord.", "joinDiscord": "Dołącz do Discord",
"joinCommunity": "Dołącz do społeczności NocoDB", "joinCommunity": "Dołącz do społeczności NocoDB",
"joinReddit": "Dołącz /r/NocoDB", "joinReddit": "Dołącz /r/NocoDB",
"followNocodb": "Śledź NocoDB" "followNocodb": "Śledź NocoDB"
}, },
"docReference": "Odnośnik do dokumentu", "docReference": "Odnośnik do dokumentu",
"selectUserRole": "Wybierz rolę użytkownika", "selectUserRole": "Wybierz rolę użytkownika",
"childTable": "Stół dziecka.", "childTable": "Tabele podrzędne",
"childColumn": "Kolumna dla dzieci", "childColumn": "Kolumna podrzędna",
"linkToAnotherRecord": "Link do innego rekordu", "linkToAnotherRecord": "Link do innego rekordu",
"onUpdate": "Na aktualizacji", "onUpdate": "Przy aktualizacji",
"onDelete": "Na delete.", "onDelete": "Przy usuwaniu",
"account": "Konto", "account": "Konto",
"language": "Język", "language": "Język",
"primaryColor": "Kolor podstawowy", "primaryColor": "Kolor podstawowy",
"accentColor": "Kolor akcentu", "accentColor": "Kolor akcentu",
"customTheme": "Motyw Niestandardowy", "customTheme": "Motyw indywidualny",
"requestDataSource": "Poproś o źródło danych, którego potrzebujesz.", "requestDataSource": "Poproś o źródło danych, którego potrzebujesz",
"apiKey": "Klucz API", "apiKey": "Klucz API",
"sharedBase": "Udostępniona baza", "sharedBase": "Udostępniona baza",
"importData": "Import Danych", "importData": "Import Danych",
@ -295,7 +295,7 @@
"importAttachmentColumns": "Importuj kolumny załączników", "importAttachmentColumns": "Importuj kolumny załączników",
"importFormulaColumns": "Importuj kolumny formuły", "importFormulaColumns": "Importuj kolumny formuły",
"noData": "Brak danych", "noData": "Brak danych",
"goToDashboard": "Przejdź do pulpitu", "goToDashboard": "Przejdź do panelu",
"importing": "Importowanie", "importing": "Importowanie",
"flattenNested": "Spłaszcz zagnieżdżone", "flattenNested": "Spłaszcz zagnieżdżone",
"downloadAllowed": "Pobieranie dozwolone", "downloadAllowed": "Pobieranie dozwolone",
@ -313,18 +313,18 @@
"agreeToTos": "Rejestrując się, akceptujesz warunki korzystania z usługi", "agreeToTos": "Rejestrując się, akceptujesz warunki korzystania z usługi",
"welcomeToNc": "Witaj w NocoDB!", "welcomeToNc": "Witaj w NocoDB!",
"inviteOnlySignup": "Zezwalaj na rejestrację tylko przy użyciu adresu url zaproszenia", "inviteOnlySignup": "Zezwalaj na rejestrację tylko przy użyciu adresu url zaproszenia",
"nextRow": "Następny rząd", "nextRow": "Następny wiersz",
"prevRow": "Poprzedni wiersz" "prevRow": "Poprzedni wiersz"
}, },
"activity": { "activity": {
"createProject": "Utwórz projekt", "createProject": "Utwórz projekt",
"importProject": "Importuj projekt.", "importProject": "Importuj projekt.",
"searchProject": "Szukaj projektu", "searchProject": "Szukaj projektu",
"editProject": "Edytuj projekt.", "editProject": "Edytuj projekt",
"stopProject": "Zatrzymaj projekt", "stopProject": "Zatrzymaj projekt",
"startProject": "Rozpocznij projekt.", "startProject": "Rozpocznij projekt",
"restartProject": "Restartuj projekt", "restartProject": "Restartuj projekt",
"deleteProject": "Usuń Projekt.", "deleteProject": "Usuń Projekt",
"refreshProject": "Odśwież projekty", "refreshProject": "Odśwież projekty",
"saveProject": "Zapisz Projekt", "saveProject": "Zapisz Projekt",
"deleteKanbanStack": "Usunąć stos?", "deleteKanbanStack": "Usunąć stos?",
@ -337,7 +337,7 @@
"upgrade": { "upgrade": {
"available": "Aktualizacja dostępna", "available": "Aktualizacja dostępna",
"releaseNote": "Informacje o wydaniu", "releaseNote": "Informacje o wydaniu",
"howTo": "Jak ulepszyć?" "howTo": "Jak uaktualnić?"
}, },
"translate": "Pomóż przetłumaczyć", "translate": "Pomóż przetłumaczyć",
"account": { "account": {

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

@ -123,7 +123,7 @@ const pg = {
.join(' AND ')}` .join(' AND ')}`
) )
.wrap('(', ')') .wrap('(', ')')
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` .toQuery()} THEN TRUE ELSE FALSE END ${args.colAlias}`
); );
}, },
OR: (args: MapFnArgs) => { OR: (args: MapFnArgs) => {
@ -135,7 +135,7 @@ const pg = {
.join(' OR ')}` .join(' OR ')}`
) )
.wrap('(', ')') .wrap('(', ')')
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` .toQuery()} THEN TRUE ELSE FALSE END ${args.colAlias}`
); );
}, },
SUBSTR: ({ fn, knex, pt, colAlias }: MapFnArgs) => { SUBSTR: ({ fn, knex, pt, colAlias }: MapFnArgs) => {

9
packages/nocodb/src/lib/meta/helpers/apiMetrics.ts

@ -3,6 +3,7 @@ import { Tele } from 'nc-help';
const countMap = {}; const countMap = {};
// @ts-ignore
const metrics = async (req: Request, c = 150) => { const metrics = async (req: Request, c = 150) => {
if (!req?.route?.path) return; if (!req?.route?.path) return;
const event = `a:api:${req.route.path}:${req.method}`; const event = `a:api:${req.route.path}:${req.method}`;
@ -13,12 +14,12 @@ const metrics = async (req: Request, c = 150) => {
} }
}; };
const metaApiMetrics = (req: Request, _res, next) => { const metaApiMetrics = (_req: Request, _res, next) => {
metrics(req, 50).then(() => {}); // metrics(req, 50).then(() => {});
next(); next();
}; };
export default (req: Request, _res, next) => { export default (_req: Request, _res, next) => {
metrics(req).then(() => {}); // metrics(req).then(() => {});
next(); next();
}; };

2
tests/playwright/pages/Dashboard/Settings/Miscellaneous.ts

@ -14,7 +14,7 @@ export class MiscSettingsPage extends BasePage {
} }
async clickShowM2MTables() { async clickShowM2MTables() {
const clickAction = this.get().locator('input[type="checkbox"]').click(); const clickAction = this.get().locator('input[type="checkbox"]').first().click();
await this.waitForResponse({ await this.waitForResponse({
uiAction: clickAction, uiAction: clickAction,
requestUrlPathToMatch: 'tables?includeM2M', requestUrlPathToMatch: 'tables?includeM2M',

Loading…
Cancel
Save