mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-06 14:05:28 +00:00
Merge branch 'ab-fixes-before-public' into 'develop'
Minor Ab fixes before public Closes #2370 See merge request baserow/baserow!2138
This commit is contained in:
commit
f80d8c8ded
15 changed files with 97 additions and 86 deletions
.nvmrc
backend
src/baserow/contrib/builder
tests/baserow/contrib/builder/pages
enterprise/web-frontend/modules/baserow_enterprise
web-frontend
modules/builder
test/unit/builder
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
16
|
18
|
||||||
|
|
|
@ -107,6 +107,10 @@ class DomainHandler:
|
||||||
|
|
||||||
prepared_values = domain_type.prepare_values(allowed_values)
|
prepared_values = domain_type.prepare_values(allowed_values)
|
||||||
|
|
||||||
|
# Save only lower case domain
|
||||||
|
if "domain_name" in prepared_values:
|
||||||
|
prepared_values["domain_name"] = prepared_values["domain_name"].lower()
|
||||||
|
|
||||||
domain = model_class(builder=builder, order=last_order, **prepared_values)
|
domain = model_class(builder=builder, order=last_order, **prepared_values)
|
||||||
domain.save()
|
domain.save()
|
||||||
|
|
||||||
|
@ -138,6 +142,10 @@ class DomainHandler:
|
||||||
|
|
||||||
prepared_values = domain_type.prepare_values(allowed_values)
|
prepared_values = domain_type.prepare_values(allowed_values)
|
||||||
|
|
||||||
|
# Save only lower case domain
|
||||||
|
if "domain_name" in prepared_values:
|
||||||
|
prepared_values["domain_name"] = prepared_values["domain_name"].lower()
|
||||||
|
|
||||||
for key, value in prepared_values.items():
|
for key, value in prepared_values.items():
|
||||||
setattr(domain, key, value)
|
setattr(domain, key, value)
|
||||||
|
|
||||||
|
|
|
@ -228,9 +228,13 @@ class PageHandler:
|
||||||
:return: A unique path to use
|
:return: A unique path to use
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
page_path = proposed_path
|
||||||
|
if page_path.endswith("/"):
|
||||||
|
page_path = page_path[:-1]
|
||||||
|
|
||||||
existing_paths = list(builder.page_set.values_list("path", flat=True))
|
existing_paths = list(builder.page_set.values_list("path", flat=True))
|
||||||
return find_unused_name(
|
return find_unused_name(
|
||||||
[proposed_path], existing_paths, max_length=255, suffix="{0}"
|
[page_path], existing_paths, max_length=255, suffix="/{0}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_page_path_valid(
|
def is_page_path_valid(
|
||||||
|
|
|
@ -213,7 +213,7 @@ def test_is_page_path_valid_raises():
|
||||||
def test_find_unused_page_path(data_fixture):
|
def test_find_unused_page_path(data_fixture):
|
||||||
page = data_fixture.create_builder_page(path="/test")
|
page = data_fixture.create_builder_page(path="/test")
|
||||||
|
|
||||||
assert PageHandler().find_unused_page_path(page.builder, "/test") == "/test2"
|
assert PageHandler().find_unused_page_path(page.builder, "/test") == "/test/2"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import { AppAuthProviderType } from '@baserow/modules/core/appAuthProviderTypes'
|
import { AppAuthProviderType } from '@baserow/modules/core/appAuthProviderTypes'
|
||||||
import LocalBaserowUserSourceForm from '@baserow_enterprise/integrations/localBaserow/components/appAuthProviders/LocalBaserowPasswordAppAuthProviderForm'
|
import LocalBaserowUserSourceForm from '@baserow_enterprise/integrations/localBaserow/components/appAuthProviders/LocalBaserowPasswordAppAuthProviderForm'
|
||||||
import {
|
import { PasswordFieldType } from '@baserow/modules/database/fieldTypes'
|
||||||
TextFieldType,
|
|
||||||
LongTextFieldType,
|
|
||||||
} from '@baserow/modules/database/fieldTypes'
|
|
||||||
|
|
||||||
export class LocalBaserowPasswordAppAuthProviderType extends AppAuthProviderType {
|
export class LocalBaserowPasswordAppAuthProviderType extends AppAuthProviderType {
|
||||||
static getType() {
|
static getType() {
|
||||||
|
@ -23,7 +20,7 @@ export class LocalBaserowPasswordAppAuthProviderType extends AppAuthProviderType
|
||||||
* It's defined here so that it can be changed by a plugin.
|
* It's defined here so that it can be changed by a plugin.
|
||||||
*/
|
*/
|
||||||
get allowedPasswordFieldTypes() {
|
get allowedPasswordFieldTypes() {
|
||||||
return [TextFieldType.getType(), LongTextFieldType.getType()]
|
return [PasswordFieldType.getType()]
|
||||||
}
|
}
|
||||||
|
|
||||||
getOrder() {
|
getOrder() {
|
||||||
|
|
|
@ -296,6 +296,7 @@
|
||||||
"localBaserowPassword": "Email/Password"
|
"localBaserowPassword": "Email/Password"
|
||||||
},
|
},
|
||||||
"localBaserowPasswordAppAuthProviderForm": {
|
"localBaserowPasswordAppAuthProviderForm": {
|
||||||
"passwordFieldLabel": "Select password field"
|
"passwordFieldLabel": "Select password field",
|
||||||
|
"noFields": "No compatible fields"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
<component
|
<component
|
||||||
:is="`h${element.level}`"
|
:is="`h${element.level}`"
|
||||||
class="heading-element__heading"
|
class="heading-element__heading"
|
||||||
:class="{ [`ab-heading--h${element.level}`]: true }"
|
:class="`ab-heading--h${element.level}`"
|
||||||
:style="{
|
:style="{
|
||||||
'--color': resolveColor(element.font_color, headingColorVariables),
|
[`--heading-h${element.level}--color`]: resolveColor(
|
||||||
|
element.font_color,
|
||||||
|
headingColorVariables
|
||||||
|
),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ resolvedValue || $t('headingElement.noValue') }}
|
{{ resolvedValue || $t('headingElement.noValue') }}
|
||||||
|
|
|
@ -48,6 +48,9 @@
|
||||||
:label="$t('linkNavigationSelection.url')"
|
:label="$t('linkNavigationSelection.url')"
|
||||||
:placeholder="$t('linkNavigationSelection.urlPlaceholder')"
|
:placeholder="$t('linkNavigationSelection.urlPlaceholder')"
|
||||||
:data-providers-allowed="DATA_PROVIDERS_ALLOWED_ELEMENTS"
|
:data-providers-allowed="DATA_PROVIDERS_ALLOWED_ELEMENTS"
|
||||||
|
:application-context-additions="{
|
||||||
|
element,
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
:key="pathPart.key"
|
:key="`else_${pathPart.key}`"
|
||||||
class="preview-navigation-bar__address-bar-path"
|
class="preview-navigation-bar__address-bar-path"
|
||||||
>
|
>
|
||||||
{{ pathPart.value }}
|
{{ pathPart.value }}
|
||||||
|
|
|
@ -106,15 +106,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="theme_settings__section-preview">
|
<div class="theme_settings__section-preview">
|
||||||
<h1
|
<component
|
||||||
class="heading-element margin-bottom-2 theme_settings__section-ellipsis"
|
:is="`h${i}`"
|
||||||
|
class="margin-bottom-2 theme_settings__section-ellipsis"
|
||||||
|
:class="`ab-heading--h${i}`"
|
||||||
:style="{
|
:style="{
|
||||||
'--color': builder.theme[`heading_${i}_color`],
|
[`--heading-h${i}--color`]: builder.theme[`heading_${i}_color`],
|
||||||
'--font-size': builder.theme[`heading_${i}_font_size`] + 'px',
|
[`--heading-h${i}--font-size`]:
|
||||||
|
builder.theme[`heading_${i}_font_size`] + 'px',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ $t('mainThemeConfigBlock.headingValue', { i }) }}
|
{{ $t('mainThemeConfigBlock.headingValue', { i }) }}
|
||||||
</h1>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,10 @@ import TableElement from '@baserow/modules/builder/components/elements/component
|
||||||
import TableElementForm from '@baserow/modules/builder/components/elements/components/forms/general/TableElementForm'
|
import TableElementForm from '@baserow/modules/builder/components/elements/components/forms/general/TableElementForm'
|
||||||
|
|
||||||
import { ELEMENT_EVENTS } from '@baserow/modules/builder/enums'
|
import { ELEMENT_EVENTS } from '@baserow/modules/builder/enums'
|
||||||
import { ensureBoolean } from '@baserow/modules/core/utils/validator'
|
import {
|
||||||
|
ensureBoolean,
|
||||||
|
ensureString,
|
||||||
|
} from '@baserow/modules/core/utils/validator'
|
||||||
import ColumnElement from '@baserow/modules/builder/components/elements/components/ColumnElement'
|
import ColumnElement from '@baserow/modules/builder/components/elements/components/ColumnElement'
|
||||||
import ColumnElementForm from '@baserow/modules/builder/components/elements/components/forms/general/ColumnElementForm'
|
import ColumnElementForm from '@baserow/modules/builder/components/elements/components/forms/general/ColumnElementForm'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
@ -296,11 +299,10 @@ export class FormElementType extends ElementType {
|
||||||
*/
|
*/
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.label) {
|
if (element.label) {
|
||||||
const resolvedName = this.resolveFormula(
|
const resolvedName = ensureString(
|
||||||
element.label,
|
this.resolveFormula(element.label, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
return resolvedName || this.name
|
||||||
return resolvedName.length ? resolvedName : this.name
|
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -359,9 +361,11 @@ export class InputTextElementType extends FormElementType {
|
||||||
const displayValue =
|
const displayValue =
|
||||||
element.label || element.default_value || element.placeholder
|
element.label || element.default_value || element.placeholder
|
||||||
|
|
||||||
if (displayValue && displayValue.length) {
|
if (displayValue?.trim()) {
|
||||||
const resolvedName = this.resolveFormula(displayValue, applicationContext)
|
const resolvedName = ensureString(
|
||||||
return resolvedName.length ? resolvedName : this.name
|
this.resolveFormula(displayValue, applicationContext)
|
||||||
|
).trim()
|
||||||
|
return resolvedName || this.name
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -401,11 +405,10 @@ export class HeadingElementType extends ElementType {
|
||||||
|
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.value && element.value.length) {
|
if (element.value && element.value.length) {
|
||||||
const resolvedName = this.resolveFormula(
|
const resolvedName = ensureString(
|
||||||
element.value,
|
this.resolveFormula(element.value, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
return resolvedName || this.name
|
||||||
return resolvedName.length ? resolvedName : this.name
|
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -437,12 +440,11 @@ export class TextElementType extends ElementType {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.value && element.value.length) {
|
if (element.value) {
|
||||||
const resolvedName = this.resolveFormula(
|
const resolvedName = ensureString(
|
||||||
element.value,
|
this.resolveFormula(element.value, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
return resolvedName || this.name
|
||||||
return resolvedName.length ? resolvedName : this.name
|
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -489,10 +491,9 @@ export class LinkElementType extends ElementType {
|
||||||
destination = `${destinationPage.name}`
|
destination = `${destinationPage.name}`
|
||||||
}
|
}
|
||||||
} else if (element.navigation_type === 'custom') {
|
} else if (element.navigation_type === 'custom') {
|
||||||
destination = this.resolveFormula(
|
destination = ensureString(
|
||||||
element.navigate_to_url,
|
this.resolveFormula(element.navigate_to_url, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destination) {
|
if (destination) {
|
||||||
|
@ -500,7 +501,9 @@ export class LinkElementType extends ElementType {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.value) {
|
if (element.value) {
|
||||||
displayValue = this.resolveFormula(element.value, applicationContext)
|
displayValue = ensureString(
|
||||||
|
this.resolveFormula(element.value, applicationContext)
|
||||||
|
).trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
return displayValue
|
return displayValue
|
||||||
|
@ -535,12 +538,11 @@ export class ImageElementType extends ElementType {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.alt_text && element.alt_text.length) {
|
if (element.alt_text) {
|
||||||
const resolvedName = this.resolveFormula(
|
const resolvedName = ensureString(
|
||||||
element.alt_text,
|
this.resolveFormula(element.alt_text, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
return resolvedName || this.name
|
||||||
return resolvedName.length ? resolvedName : this.name
|
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -576,12 +578,11 @@ export class ButtonElementType extends ElementType {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.value && element.value.length) {
|
if (element.value) {
|
||||||
const resolvedName = this.resolveFormula(
|
const resolvedName = ensureString(
|
||||||
element.value,
|
this.resolveFormula(element.value, applicationContext)
|
||||||
applicationContext
|
).trim()
|
||||||
)
|
return resolvedName || this.name
|
||||||
return resolvedName.length ? resolvedName : this.name
|
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -654,16 +655,17 @@ export class TableElementType extends ElementType {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayName(element, { page }) {
|
getDisplayName(element, { page }) {
|
||||||
let displayValue = ''
|
let suffix = ''
|
||||||
|
|
||||||
if (element.data_source_id) {
|
if (element.data_source_id) {
|
||||||
const dataSource = this.app.store.getters[
|
const dataSource = this.app.store.getters[
|
||||||
'dataSource/getPageDataSourceById'
|
'dataSource/getPageDataSourceById'
|
||||||
](page, element.data_source_id)
|
](page, element.data_source_id)
|
||||||
displayValue = dataSource
|
|
||||||
? `${dataSource.name} ${this.name.toLowerCase()}`
|
suffix = dataSource ? ` - ${dataSource.name}` : ''
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
return displayValue.length ? displayValue : this.name
|
|
||||||
|
return `${this.name}${suffix}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,9 +709,11 @@ export class DropdownElementType extends FormElementType {
|
||||||
const displayValue =
|
const displayValue =
|
||||||
element.label || element.default_value || element.placeholder
|
element.label || element.default_value || element.placeholder
|
||||||
|
|
||||||
if (displayValue && displayValue.length) {
|
if (displayValue) {
|
||||||
const resolvedName = this.resolveFormula(displayValue, applicationContext)
|
const resolvedName = ensureString(
|
||||||
return resolvedName.length ? resolvedName : this.name
|
this.resolveFormula(displayValue, applicationContext)
|
||||||
|
).trim()
|
||||||
|
return resolvedName || this.name
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
@ -823,8 +827,10 @@ export class IFrameElementType extends ElementType {
|
||||||
|
|
||||||
getDisplayName(element, applicationContext) {
|
getDisplayName(element, applicationContext) {
|
||||||
if (element.url && element.url.length) {
|
if (element.url && element.url.length) {
|
||||||
const resolvedName = this.resolveFormula(element.url, applicationContext)
|
const resolvedName = ensureString(
|
||||||
return resolvedName.length ? resolvedName : this.name
|
this.resolveFormula(element.url, applicationContext)
|
||||||
|
)
|
||||||
|
return resolvedName || this.name
|
||||||
}
|
}
|
||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
"heading": "Heading",
|
"heading": "Heading",
|
||||||
"headingDescription": "Page heading title",
|
"headingDescription": "Page heading title",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"textDescription": "Single line text",
|
"textDescription": "Multi-line text",
|
||||||
"link": "Link",
|
"link": "Link",
|
||||||
"linkDescription": "A link to page/URL",
|
"linkDescription": "A link to page/URL",
|
||||||
"image": "Image",
|
"image": "Image",
|
||||||
|
@ -286,7 +286,7 @@
|
||||||
},
|
},
|
||||||
"horizontalAlignmentSelector": {
|
"horizontalAlignmentSelector": {
|
||||||
"alignment": "Horizontal alignment",
|
"alignment": "Horizontal alignment",
|
||||||
"alignmentLeft": "Link",
|
"alignmentLeft": "Left",
|
||||||
"alignmentCenter": "Center",
|
"alignmentCenter": "Center",
|
||||||
"alignmentRight": "Right"
|
"alignmentRight": "Right"
|
||||||
},
|
},
|
||||||
|
|
|
@ -96,10 +96,6 @@ import {
|
||||||
export default (context) => {
|
export default (context) => {
|
||||||
const { store, app, isDev } = context
|
const { store, app, isDev } = context
|
||||||
|
|
||||||
if (!app.$featureFlagIsEnabled('builder')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow locale file hot reloading in dev
|
// Allow locale file hot reloading in dev
|
||||||
if (isDev && app.i18n) {
|
if (isDev && app.i18n) {
|
||||||
const { i18n } = app
|
const { i18n } = app
|
||||||
|
@ -152,12 +148,10 @@ export default (context) => {
|
||||||
new DomainsBuilderSettingsType(context)
|
new DomainsBuilderSettingsType(context)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (app.$featureFlagIsEnabled('builder-user-source')) {
|
app.$registry.register(
|
||||||
app.$registry.register(
|
'builderSettings',
|
||||||
'builderSettings',
|
new UserSourcesBuilderSettingsType(context)
|
||||||
new UserSourcesBuilderSettingsType(context)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.$registry.register('errorPage', new PublicSiteErrorPageType(context))
|
app.$registry.register('errorPage', new PublicSiteErrorPageType(context))
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,6 @@ import {
|
||||||
routerOptions as defaultRouterOptions,
|
routerOptions as defaultRouterOptions,
|
||||||
} from './defaultRouter'
|
} from './defaultRouter'
|
||||||
|
|
||||||
import {
|
|
||||||
featureFlagIsEnabled,
|
|
||||||
getFeatureFlags,
|
|
||||||
} from '@baserow/modules/core/utils/env'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the official Nuxt `createRouter` function. If the request hostname is equal
|
* Replace the official Nuxt `createRouter` function. If the request hostname is equal
|
||||||
* to the `PUBLIC_WEB_FRONTEND_URL` hostname, the router will contain only routes that
|
* to the `PUBLIC_WEB_FRONTEND_URL` hostname, the router will contain only routes that
|
||||||
|
@ -37,11 +32,8 @@ export function createRouter(ssrContext, config) {
|
||||||
).hostname
|
).hostname
|
||||||
const requestHostname = new URL(`http://${req.headers.host}`).hostname
|
const requestHostname = new URL(`http://${req.headers.host}`).hostname
|
||||||
|
|
||||||
const featureFlags = getFeatureFlags(runtimeConfig.public)
|
|
||||||
// We allow published routes only if the builder feature flag is on
|
// We allow published routes only if the builder feature flag is on
|
||||||
isWebFrontendHostname =
|
isWebFrontendHostname = frontendHostname === requestHostname
|
||||||
frontendHostname === requestHostname ||
|
|
||||||
!featureFlagIsEnabled(featureFlags, 'builder')
|
|
||||||
|
|
||||||
// Send the variable to the frontend using the `__NUXT__` property
|
// Send the variable to the frontend using the `__NUXT__` property
|
||||||
ssrContext.nuxt.isWebFrontendHostname = isWebFrontendHostname
|
ssrContext.nuxt.isWebFrontendHostname = isWebFrontendHostname
|
||||||
|
|
|
@ -197,7 +197,7 @@ describe('elementTypes tests', () => {
|
||||||
}
|
}
|
||||||
expect(
|
expect(
|
||||||
elementType.getDisplayName({ data_source_id: 1 }, applicationContext)
|
elementType.getDisplayName({ data_source_id: 1 }, applicationContext)
|
||||||
).toBe('Customers elementtype.table')
|
).toBe('elementType.table - Customers')
|
||||||
|
|
||||||
// In the event we don't find the data source.
|
// In the event we don't find the data source.
|
||||||
expect(
|
expect(
|
||||||
|
|
Loading…
Add table
Reference in a new issue