mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-17 02:17:49 +00:00
🌈 5️⃣ - Row coloring v5 - Add color to Gallery and Kanban view types
This commit is contained in:
parent
df48bf7986
commit
224d5dfee3
30 changed files with 2234 additions and 1102 deletions
backend/src/baserow/contrib/database/views
changelog.mdpremium
backend/src/baserow_premium/views
web-frontend/modules/baserow_premium
web-frontend
modules
core/assets/scss/components
database
components
card
view
mixins
test
fixtures
unit/database
components/view
__snapshots__
gallery
grid
viewDecoratorContext.spec.js
|
@ -290,6 +290,7 @@ class GalleryViewType(ViewType):
|
||||||
api_exceptions_map = {
|
api_exceptions_map = {
|
||||||
FieldNotInTable: ERROR_FIELD_NOT_IN_TABLE,
|
FieldNotInTable: ERROR_FIELD_NOT_IN_TABLE,
|
||||||
}
|
}
|
||||||
|
can_decorate = True
|
||||||
|
|
||||||
def get_api_urls(self):
|
def get_api_urls(self):
|
||||||
from baserow.contrib.database.api.views.gallery import urls as api_urls
|
from baserow.contrib.database.api.views.gallery import urls as api_urls
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
* Added row coloring for Kanban and Gallery views
|
||||||
|
|
||||||
## Released (2022-10-05 1.10.0)
|
## Released (2022-10-05 1.10.0)
|
||||||
|
|
||||||
* Added batch create/update/delete rows endpoints. These endpoints make it possible to
|
* Added batch create/update/delete rows endpoints. These endpoints make it possible to
|
||||||
|
|
|
@ -52,6 +52,7 @@ class KanbanViewType(ViewType):
|
||||||
),
|
),
|
||||||
FieldNotInTable: ERROR_FIELD_NOT_IN_TABLE,
|
FieldNotInTable: ERROR_FIELD_NOT_IN_TABLE,
|
||||||
}
|
}
|
||||||
|
can_decorate = True
|
||||||
|
|
||||||
def get_api_urls(self):
|
def get_api_urls(self):
|
||||||
from baserow_premium.api.views.kanban import urls as api_urls
|
from baserow_premium.api.views.kanban import urls as api_urls
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
.left-border-decorator {
|
.left-border-decorator {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
height: 24px;
|
align-self: stretch;
|
||||||
margin: 0 4px;
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
margin: 4px;
|
||||||
|
|
||||||
@include add-shadow-on-same-background();
|
@include add-shadow-on-same-background();
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
v-show="slot.position != -1"
|
v-show="slot.position != -1"
|
||||||
:key="'card-' + slot.id"
|
:key="'card-' + slot.id"
|
||||||
:fields="cardFields"
|
:fields="cardFields"
|
||||||
|
:decorations-by-place="decorationsByPlace"
|
||||||
:row="slot.row"
|
:row="slot.row"
|
||||||
:cover-image-field="coverImageField"
|
:cover-image-field="coverImageField"
|
||||||
:style="{
|
:style="{
|
||||||
|
@ -138,11 +139,12 @@ import InfiniteScroll from '@baserow/modules/core/components/helpers/InfiniteScr
|
||||||
import { populateRow } from '@baserow_premium/store/view/kanban'
|
import { populateRow } from '@baserow_premium/store/view/kanban'
|
||||||
import KanbanViewStackContext from '@baserow_premium/components/views/kanban/KanbanViewStackContext'
|
import KanbanViewStackContext from '@baserow_premium/components/views/kanban/KanbanViewStackContext'
|
||||||
import { getCardHeight } from '@baserow/modules/database/utils/card'
|
import { getCardHeight } from '@baserow/modules/database/utils/card'
|
||||||
|
import viewDecoration from '@baserow/modules/database/mixins/viewDecoration'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'KanbanViewStack',
|
name: 'KanbanViewStack',
|
||||||
components: { InfiniteScroll, RowCard, KanbanViewStackContext },
|
components: { InfiniteScroll, RowCard, KanbanViewStackContext },
|
||||||
mixins: [kanbanViewHelper],
|
mixins: [kanbanViewHelper, viewDecoration],
|
||||||
props: {
|
props: {
|
||||||
option: {
|
option: {
|
||||||
validator: (prop) => typeof prop === 'object' || prop === null,
|
validator: (prop) => typeof prop === 'object' || prop === null,
|
||||||
|
|
|
@ -107,7 +107,11 @@ export class ConditionalColorValueProviderType extends DecoratorValueProviderTyp
|
||||||
getValue({ options, fields, row }) {
|
getValue({ options, fields, row }) {
|
||||||
const { $registry } = this.app
|
const { $registry } = this.app
|
||||||
for (const { color, filters, operator } of options.colors) {
|
for (const { color, filters, operator } of options.colors) {
|
||||||
if (matchSearchFilters($registry, operator, filters, fields, row)) {
|
if (
|
||||||
|
row.id !== -1 &&
|
||||||
|
row.id !== undefined &&
|
||||||
|
matchSearchFilters($registry, operator, filters, fields, row)
|
||||||
|
) {
|
||||||
return color
|
return color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import { ViewDecoratorType } from '@baserow/modules/database/viewDecorators'
|
import { ViewDecoratorType } from '@baserow/modules/database/viewDecorators'
|
||||||
import { PremiumPlugin } from '@baserow_premium/plugins'
|
import { PremiumPlugin } from '@baserow_premium/plugins'
|
||||||
|
|
||||||
|
import {
|
||||||
|
GridViewType,
|
||||||
|
GalleryViewType,
|
||||||
|
} from '@baserow/modules/database/viewTypes'
|
||||||
|
|
||||||
|
import { KanbanViewType } from './viewTypes'
|
||||||
|
|
||||||
import leftBorderDecoratorImage from '@baserow_premium/assets/images/leftBorderDecorator.svg'
|
import leftBorderDecoratorImage from '@baserow_premium/assets/images/leftBorderDecorator.svg'
|
||||||
import backgroundDecoratorImage from '@baserow_premium/assets/images/backgroundDecorator.svg'
|
import backgroundDecoratorImage from '@baserow_premium/assets/images/backgroundDecorator.svg'
|
||||||
|
|
||||||
|
@ -71,7 +78,13 @@ export class LeftBorderColorViewDecoratorType extends ViewDecoratorType {
|
||||||
isCompatible(view) {
|
isCompatible(view) {
|
||||||
const { store } = this.app
|
const { store } = this.app
|
||||||
|
|
||||||
return ['grid'].includes(view.type) && !store.getters['view/grid/isPublic']
|
return (
|
||||||
|
[
|
||||||
|
GridViewType.getType(),
|
||||||
|
GalleryViewType.getType(),
|
||||||
|
KanbanViewType.getType(),
|
||||||
|
].includes(view.type) && !store.getters['view/grid/isPublic']
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +127,13 @@ export class BackgroundColorViewDecoratorType extends ViewDecoratorType {
|
||||||
isCompatible(view) {
|
isCompatible(view) {
|
||||||
const { store } = this.app
|
const { store } = this.app
|
||||||
|
|
||||||
return ['grid'].includes(view.type) && !store.getters['view/grid/isPublic']
|
return (
|
||||||
|
[
|
||||||
|
GridViewType.getType(),
|
||||||
|
GalleryViewType.getType(),
|
||||||
|
KanbanViewType.getType(),
|
||||||
|
].includes(view.type) && !store.getters['view/grid/isPublic']
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeactivatedText() {
|
getDeactivatedText() {
|
||||||
|
|
|
@ -68,8 +68,13 @@
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card__content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.card__fields {
|
.card__fields {
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card__field {
|
.card__field {
|
||||||
|
|
|
@ -6,4 +6,5 @@
|
||||||
@extend %ellipsis;
|
@extend %ellipsis;
|
||||||
|
|
||||||
@include select-option-style(inline-block);
|
@include select-option-style(inline-block);
|
||||||
|
@include add-shadow-on-same-background();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,41 +6,65 @@
|
||||||
@mousemove="$emit('mousemove', $event)"
|
@mousemove="$emit('mousemove', $event)"
|
||||||
@mouseenter="$emit('mouseenter', $event)"
|
@mouseenter="$emit('mouseenter', $event)"
|
||||||
>
|
>
|
||||||
<div v-if="coverImageField !== null" class="card__cover">
|
<RecursiveWrapper
|
||||||
<div
|
:components="
|
||||||
v-if="coverImageUrl !== null"
|
wrapperDecorations.map((comp) => ({
|
||||||
class="card__cover-image"
|
...comp,
|
||||||
:style="{
|
props: comp.propsFn(row),
|
||||||
'background-image': 'url(' + coverImageUrl + ')',
|
}))
|
||||||
}"
|
"
|
||||||
></div>
|
>
|
||||||
</div>
|
<div v-if="coverImageField !== null" class="card__cover">
|
||||||
<div class="card__fields">
|
<div
|
||||||
<div v-for="field in fields" :key="field.id" class="card__field">
|
v-if="coverImageUrl !== null"
|
||||||
<div class="card__field-name">{{ field.name }}</div>
|
class="card__cover-image"
|
||||||
<div class="card__field-value">
|
:style="{
|
||||||
<component
|
'background-image': 'url(' + coverImageUrl + ')',
|
||||||
:is="getCardComponent(field)"
|
}"
|
||||||
v-if="!loading"
|
></div>
|
||||||
:field="field"
|
</div>
|
||||||
:value="row['field_' + field.id]"
|
<div class="card__content">
|
||||||
/>
|
<component
|
||||||
|
:is="dec.component"
|
||||||
|
v-for="dec in firstCellDecorations"
|
||||||
|
:key="dec.decoration.id"
|
||||||
|
v-bind="dec.propsFn(row)"
|
||||||
|
/>
|
||||||
|
<div class="card__fields">
|
||||||
|
<div v-for="field in fields" :key="field.id" class="card__field">
|
||||||
|
<div class="card__field-name">{{ field.name }}</div>
|
||||||
|
<div class="card__field-value">
|
||||||
|
<component
|
||||||
|
:is="getCardComponent(field)"
|
||||||
|
v-if="!loading"
|
||||||
|
:field="field"
|
||||||
|
:value="row['field_' + field.id]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</RecursiveWrapper>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { FileFieldType } from '@baserow/modules/database/fieldTypes'
|
import { FileFieldType } from '@baserow/modules/database/fieldTypes'
|
||||||
|
import RecursiveWrapper from '@baserow/modules/database/components/RecursiveWrapper'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'RowCard',
|
name: 'RowCard',
|
||||||
|
components: { RecursiveWrapper },
|
||||||
props: {
|
props: {
|
||||||
fields: {
|
fields: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
decorationsByPlace: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
row: {
|
row: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -80,6 +104,12 @@ export default {
|
||||||
|
|
||||||
return image.thumbnails.card_cover.url
|
return image.thumbnails.card_cover.url
|
||||||
},
|
},
|
||||||
|
firstCellDecorations() {
|
||||||
|
return this.decorationsByPlace?.first_cell || []
|
||||||
|
},
|
||||||
|
wrapperDecorations() {
|
||||||
|
return this.decorationsByPlace?.wrapper || []
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getCardComponent(field) {
|
getCardComponent(field) {
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
<ViewDecoratorItem :decorator-type="dec.decoratorType" />
|
<ViewDecoratorItem :decorator-type="dec.decoratorType" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-show="dec.decoration.value_provider_type"
|
v-show="dec.valueProviderType"
|
||||||
class="decorator-context__decorator-header-select"
|
class="decorator-context__decorator-header-select"
|
||||||
>
|
>
|
||||||
<Picker
|
<Picker
|
||||||
v-if="dec.decoration.value_provider_type"
|
v-if="dec.valueProviderType"
|
||||||
:icon="dec.valueProviderType.getIconClass()"
|
:icon="dec.valueProviderType.getIconClass()"
|
||||||
:name="dec.valueProviderType.getName()"
|
:name="dec.valueProviderType.getName()"
|
||||||
@select="selectValueProvider(dec.decoration, $event)"
|
@select="selectValueProvider(dec.decoration, $event)"
|
||||||
|
@ -104,6 +104,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import context from '@baserow/modules/core/mixins/context'
|
import context from '@baserow/modules/core/mixins/context'
|
||||||
|
import viewDecoration from '@baserow/modules/database/mixins/viewDecoration'
|
||||||
import ViewDecoratorList from '@baserow/modules/database/components/view/ViewDecoratorList'
|
import ViewDecoratorList from '@baserow/modules/database/components/view/ViewDecoratorList'
|
||||||
import ViewDecoratorItem from '@baserow/modules/database/components/view/ViewDecoratorItem'
|
import ViewDecoratorItem from '@baserow/modules/database/components/view/ViewDecoratorItem'
|
||||||
import SelectViewDecoratorContext from '@baserow/modules/database/components/view/SelectViewDecoratorContext'
|
import SelectViewDecoratorContext from '@baserow/modules/database/components/view/SelectViewDecoratorContext'
|
||||||
|
@ -120,7 +121,7 @@ export default {
|
||||||
SelectViewDecoratorContext,
|
SelectViewDecoratorContext,
|
||||||
DecoratorValueProviderList,
|
DecoratorValueProviderList,
|
||||||
},
|
},
|
||||||
mixins: [context],
|
mixins: [context, viewDecoration],
|
||||||
props: {
|
props: {
|
||||||
primary: {
|
primary: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -143,42 +144,6 @@ export default {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
allFields() {
|
|
||||||
return [this.primary, ...this.fields]
|
|
||||||
},
|
|
||||||
augmentedDecorations() {
|
|
||||||
return this.view.decorations.map((decoration) => {
|
|
||||||
const deco = { decoration }
|
|
||||||
deco.decoratorType = this.$registry.get(
|
|
||||||
'viewDecorator',
|
|
||||||
decoration.type
|
|
||||||
)
|
|
||||||
|
|
||||||
if (decoration.value_provider_type) {
|
|
||||||
deco.valueProviderType = this.$registry.get(
|
|
||||||
'decoratorValueProvider',
|
|
||||||
decoration.value_provider_type
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
deco.availableValueProviderTypes = this.$registry
|
|
||||||
.getOrderedList('decoratorValueProvider')
|
|
||||||
.filter((valueProviderType) =>
|
|
||||||
valueProviderType.isCompatible(deco.decoratorType)
|
|
||||||
)
|
|
||||||
|
|
||||||
deco.isDeactivated = deco.decoratorType.isDeactivated({
|
|
||||||
view: this.view,
|
|
||||||
})
|
|
||||||
|
|
||||||
return deco
|
|
||||||
})
|
|
||||||
},
|
|
||||||
activeDecorations() {
|
|
||||||
return this.augmentedDecorations.filter((deco) => !deco.isDeactivated)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async removeDecoration(decoration) {
|
async removeDecoration(decoration) {
|
||||||
try {
|
try {
|
||||||
|
@ -202,7 +167,7 @@ export default {
|
||||||
value_provider_type: valueProviderType.getType(),
|
value_provider_type: valueProviderType.getType(),
|
||||||
value_provider_conf: valueProviderType.getDefaultConfiguration({
|
value_provider_conf: valueProviderType.getDefaultConfiguration({
|
||||||
view: this.view,
|
view: this.view,
|
||||||
fields: this.allFields,
|
fields: this.allTableFields,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
decoration,
|
decoration,
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
:row="slot.item || {}"
|
:row="slot.item || {}"
|
||||||
:loading="slot.item === null"
|
:loading="slot.item === null"
|
||||||
:cover-image-field="coverImageField"
|
:cover-image-field="coverImageField"
|
||||||
|
:decorations-by-place="decorationsByPlace"
|
||||||
class="gallery-view__card"
|
class="gallery-view__card"
|
||||||
:style="{
|
:style="{
|
||||||
width: cardWidth + 'px',
|
width: cardWidth + 'px',
|
||||||
|
@ -93,11 +94,12 @@ import RowCreateModal from '@baserow/modules/database/components/row/RowCreateMo
|
||||||
import RowEditModal from '@baserow/modules/database/components/row/RowEditModal'
|
import RowEditModal from '@baserow/modules/database/components/row/RowEditModal'
|
||||||
import bufferedRowsDragAndDrop from '@baserow/modules/database/mixins/bufferedRowsDragAndDrop'
|
import bufferedRowsDragAndDrop from '@baserow/modules/database/mixins/bufferedRowsDragAndDrop'
|
||||||
import viewHelpers from '@baserow/modules/database/mixins/viewHelpers'
|
import viewHelpers from '@baserow/modules/database/mixins/viewHelpers'
|
||||||
|
import viewDecoration from '@baserow/modules/database/mixins/viewDecoration'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GalleryView',
|
name: 'GalleryView',
|
||||||
components: { RowCard, RowCreateModal, RowEditModal },
|
components: { RowCard, RowCreateModal, RowEditModal },
|
||||||
mixins: [viewHelpers, bufferedRowsDragAndDrop],
|
mixins: [viewHelpers, bufferedRowsDragAndDrop, viewDecoration],
|
||||||
props: {
|
props: {
|
||||||
primary: {
|
primary: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
ref="left"
|
ref="left"
|
||||||
class="grid-view__left"
|
class="grid-view__left"
|
||||||
:fields="leftFields"
|
:fields="leftFields"
|
||||||
:all-table-fields="allTableFields"
|
:decorations-by-place="decorationsByPlace"
|
||||||
:table="table"
|
:table="table"
|
||||||
:view="view"
|
:view="view"
|
||||||
:include-field-width-handles="false"
|
:include-field-width-handles="false"
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
ref="right"
|
ref="right"
|
||||||
class="grid-view__right"
|
class="grid-view__right"
|
||||||
:fields="visibleFields"
|
:fields="visibleFields"
|
||||||
:all-table-fields="allTableFields"
|
:decorations-by-place="decorationsByPlace"
|
||||||
:table="table"
|
:table="table"
|
||||||
:view="view"
|
:view="view"
|
||||||
:include-add-field="true"
|
:include-add-field="true"
|
||||||
|
@ -188,6 +188,7 @@ import gridViewHelpers from '@baserow/modules/database/mixins/gridViewHelpers'
|
||||||
import { maxPossibleOrderValue } from '@baserow/modules/database/viewTypes'
|
import { maxPossibleOrderValue } from '@baserow/modules/database/viewTypes'
|
||||||
import viewHelpers from '@baserow/modules/database/mixins/viewHelpers'
|
import viewHelpers from '@baserow/modules/database/mixins/viewHelpers'
|
||||||
import { isElement } from '@baserow/modules/core/utils/dom'
|
import { isElement } from '@baserow/modules/core/utils/dom'
|
||||||
|
import viewDecoration from '@baserow/modules/database/mixins/viewDecoration'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GridView',
|
name: 'GridView',
|
||||||
|
@ -197,7 +198,7 @@ export default {
|
||||||
GridViewRowDragging,
|
GridViewRowDragging,
|
||||||
RowEditModal,
|
RowEditModal,
|
||||||
},
|
},
|
||||||
mixins: [viewHelpers, gridViewHelpers],
|
mixins: [viewHelpers, gridViewHelpers, viewDecoration],
|
||||||
props: {
|
props: {
|
||||||
primary: {
|
primary: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -280,9 +281,6 @@ export default {
|
||||||
leftWidth() {
|
leftWidth() {
|
||||||
return this.leftFieldsWidth + this.gridViewRowDetailsWidth
|
return this.leftFieldsWidth + this.gridViewRowDetailsWidth
|
||||||
},
|
},
|
||||||
allTableFields() {
|
|
||||||
return [this.primary, ...this.fields]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
fieldOptions: {
|
fieldOptions: {
|
||||||
|
|
|
@ -128,10 +128,9 @@ export default {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
decorations: {
|
decorationsByPlace: {
|
||||||
type: Array,
|
type: Object,
|
||||||
required: false,
|
required: true,
|
||||||
default: () => [],
|
|
||||||
},
|
},
|
||||||
allFields: {
|
allFields: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -212,10 +211,10 @@ export default {
|
||||||
return fields
|
return fields
|
||||||
},
|
},
|
||||||
firstCellDecorations() {
|
firstCellDecorations() {
|
||||||
return this.decorations.filter(({ place }) => place === 'first_cell')
|
return this.decorationsByPlace?.first_cell || []
|
||||||
},
|
},
|
||||||
wrapperDecorations() {
|
wrapperDecorations() {
|
||||||
return this.decorations.filter(({ place }) => place === 'wrapper')
|
return this.decorationsByPlace?.wrapper || []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
:all-fields="allFields"
|
:all-fields="allFields"
|
||||||
:field-widths="fieldWidths"
|
:field-widths="fieldWidths"
|
||||||
:include-row-details="includeRowDetails"
|
:include-row-details="includeRowDetails"
|
||||||
:decorations="augmentedDecorations"
|
:decorations-by-place="decorationsByPlace"
|
||||||
:read-only="readOnly"
|
:read-only="readOnly"
|
||||||
:can-drag="view.sortings.length === 0"
|
:can-drag="view.sortings.length === 0"
|
||||||
:store-prefix="storePrefix"
|
:store-prefix="storePrefix"
|
||||||
|
@ -41,8 +41,8 @@ export default {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
allTableFields: {
|
decorationsByPlace: {
|
||||||
type: Array,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
leftOffset: {
|
leftOffset: {
|
||||||
|
@ -72,42 +72,6 @@ export default {
|
||||||
})
|
})
|
||||||
return fieldWidths
|
return fieldWidths
|
||||||
},
|
},
|
||||||
augmentedDecorations() {
|
|
||||||
return this.view.decorations
|
|
||||||
.filter(({ value_provider_type: valPro }) => valPro)
|
|
||||||
.map((decoration) => {
|
|
||||||
const deco = { decoration }
|
|
||||||
|
|
||||||
deco.decorationType = this.$registry.get(
|
|
||||||
'viewDecorator',
|
|
||||||
decoration.type
|
|
||||||
)
|
|
||||||
|
|
||||||
deco.component = deco.decorationType.getComponent()
|
|
||||||
deco.place = deco.decorationType.getPlace()
|
|
||||||
|
|
||||||
deco.valueProviderType = this.$registry.get(
|
|
||||||
'decoratorValueProvider',
|
|
||||||
decoration.value_provider_type
|
|
||||||
)
|
|
||||||
|
|
||||||
deco.propsFn = (row) => {
|
|
||||||
return {
|
|
||||||
value: deco.valueProviderType.getValue({
|
|
||||||
row,
|
|
||||||
fields: this.allTableFields,
|
|
||||||
options: decoration.value_provider_conf,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return deco
|
|
||||||
})
|
|
||||||
.filter(
|
|
||||||
({ decorationType }) =>
|
|
||||||
!decorationType.isDeactivated({ view: this.view })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
this.$options.computed = {
|
this.$options.computed = {
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
:view="view"
|
:view="view"
|
||||||
:fields="fieldsToRender"
|
:fields="fieldsToRender"
|
||||||
:all-fields="fields"
|
:all-fields="fields"
|
||||||
:all-table-fields="allTableFields"
|
:decorations-by-place="decorationsByPlace"
|
||||||
:left-offset="fieldsLeftOffset"
|
:left-offset="fieldsLeftOffset"
|
||||||
:include-row-details="includeRowDetails"
|
:include-row-details="includeRowDetails"
|
||||||
:read-only="readOnly"
|
:read-only="readOnly"
|
||||||
|
@ -127,8 +127,8 @@ export default {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
allTableFields: {
|
decorationsByPlace: {
|
||||||
type: Array,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
|
|
75
web-frontend/modules/database/mixins/viewDecoration.js
Normal file
75
web-frontend/modules/database/mixins/viewDecoration.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/**
|
||||||
|
* A mixin that can be used in combination with the view filter input components. If
|
||||||
|
* contains the expected props and it has a computed property that finds the field
|
||||||
|
* object related to filter field id.
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
view: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
allTableFields() {
|
||||||
|
return [this.primary, ...this.fields]
|
||||||
|
},
|
||||||
|
activeDecorations() {
|
||||||
|
return this.view.decorations
|
||||||
|
.map((decoration) => {
|
||||||
|
const deco = { decoration }
|
||||||
|
|
||||||
|
deco.decoratorType = this.$registry.get(
|
||||||
|
'viewDecorator',
|
||||||
|
decoration.type
|
||||||
|
)
|
||||||
|
|
||||||
|
deco.component = deco.decoratorType.getComponent()
|
||||||
|
deco.place = deco.decoratorType.getPlace()
|
||||||
|
|
||||||
|
if (decoration.value_provider_type) {
|
||||||
|
deco.valueProviderType = this.$registry.get(
|
||||||
|
'decoratorValueProvider',
|
||||||
|
decoration.value_provider_type
|
||||||
|
)
|
||||||
|
|
||||||
|
deco.propsFn = (row) => {
|
||||||
|
return {
|
||||||
|
value: deco.valueProviderType.getValue({
|
||||||
|
row,
|
||||||
|
fields: this.allTableFields,
|
||||||
|
options: decoration.value_provider_conf,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deco
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
({ decoratorType }) =>
|
||||||
|
!decoratorType.isDeactivated({ view: this.view })
|
||||||
|
)
|
||||||
|
},
|
||||||
|
decorationsByPlace() {
|
||||||
|
return this.activeDecorations
|
||||||
|
.filter(({ valueProviderType }) => valueProviderType)
|
||||||
|
.reduce((prev, deco) => {
|
||||||
|
if (deco.valueProviderType) {
|
||||||
|
const decType = deco.decoratorType.getPlace()
|
||||||
|
prev[decType] = [...(prev[decType] || []), deco]
|
||||||
|
}
|
||||||
|
return prev
|
||||||
|
}, {})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
49
web-frontend/test/fixtures/gallery.js
vendored
Normal file
49
web-frontend/test/fixtures/gallery.js
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
export function createGalleryView(
|
||||||
|
mock,
|
||||||
|
application,
|
||||||
|
table,
|
||||||
|
{
|
||||||
|
viewType = 'gallery',
|
||||||
|
viewId = 1,
|
||||||
|
filters = [],
|
||||||
|
sortings = [],
|
||||||
|
decorations = [],
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const tableId = table.id
|
||||||
|
const galleryView = {
|
||||||
|
id: viewId,
|
||||||
|
table_id: tableId,
|
||||||
|
name: `mock_view_${viewId}`,
|
||||||
|
order: 0,
|
||||||
|
type: viewType,
|
||||||
|
table: {
|
||||||
|
id: tableId,
|
||||||
|
name: table.name,
|
||||||
|
order: 0,
|
||||||
|
database_id: application.id,
|
||||||
|
},
|
||||||
|
filter_type: 'AND',
|
||||||
|
filters_disabled: false,
|
||||||
|
filters,
|
||||||
|
sortings,
|
||||||
|
decorations,
|
||||||
|
}
|
||||||
|
mock.onGet(`/database/views/table/${tableId}/`).reply(200, [galleryView])
|
||||||
|
return galleryView
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createGalleryRows(mock, view, fields, rows = []) {
|
||||||
|
const fieldOptions = {}
|
||||||
|
for (let i = 1; i < fields.length; i++) {
|
||||||
|
fieldOptions[i] = {
|
||||||
|
hidden: false,
|
||||||
|
order: i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mock.onGet(`/database/views/gallery/${view.id}/`).reply(200, {
|
||||||
|
count: rows.length,
|
||||||
|
results: rows,
|
||||||
|
field_options: fieldOptions,
|
||||||
|
})
|
||||||
|
}
|
2
web-frontend/test/fixtures/grid.js
vendored
2
web-frontend/test/fixtures/grid.js
vendored
|
@ -1,4 +1,4 @@
|
||||||
export function createRows(mock, gridView, fields, rows = []) {
|
export function createGridRows(mock, gridView, fields, rows = []) {
|
||||||
const fieldOptions = {}
|
const fieldOptions = {}
|
||||||
for (let i = 1; i < fields.length; i++) {
|
for (let i = 1; i < fields.length; i++) {
|
||||||
fieldOptions[i] = {
|
fieldOptions[i] = {
|
||||||
|
|
30
web-frontend/test/fixtures/mockServer.js
vendored
30
web-frontend/test/fixtures/mockServer.js
vendored
|
@ -7,8 +7,12 @@ import {
|
||||||
import { createFields } from '@baserow/test/fixtures/fields'
|
import { createFields } from '@baserow/test/fixtures/fields'
|
||||||
import {
|
import {
|
||||||
createPublicGridViewRows,
|
createPublicGridViewRows,
|
||||||
createRows,
|
createGridRows,
|
||||||
} from '@baserow/test/fixtures/grid'
|
} from '@baserow/test/fixtures/grid'
|
||||||
|
import {
|
||||||
|
createGalleryRows,
|
||||||
|
createGalleryView,
|
||||||
|
} from '@baserow/test/fixtures/gallery'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MockServer is responsible for being the single place where we mock out calls to the
|
* MockServer is responsible for being the single place where we mock out calls to the
|
||||||
|
@ -39,12 +43,13 @@ export class MockServer {
|
||||||
createGridView(
|
createGridView(
|
||||||
application,
|
application,
|
||||||
table,
|
table,
|
||||||
{ filters = [], sortings = [], decorations = [] }
|
{ filters = [], sortings = [], decorations = [], ...rest }
|
||||||
) {
|
) {
|
||||||
return createGridView(this.mock, application, table, {
|
return createGridView(this.mock, application, table, {
|
||||||
filters,
|
filters,
|
||||||
sortings,
|
sortings,
|
||||||
decorations,
|
decorations,
|
||||||
|
...rest,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +61,29 @@ export class MockServer {
|
||||||
return createPublicGridViewRows(this.mock, viewSlug, fields, rows)
|
return createPublicGridViewRows(this.mock, viewSlug, fields, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createGalleryView(
|
||||||
|
application,
|
||||||
|
table,
|
||||||
|
{ filters = [], sortings = [], decorations = [], ...rest }
|
||||||
|
) {
|
||||||
|
return createGalleryView(this.mock, application, table, {
|
||||||
|
filters,
|
||||||
|
sortings,
|
||||||
|
decorations,
|
||||||
|
...rest,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
createFields(application, table, fields) {
|
createFields(application, table, fields) {
|
||||||
return createFields(this.mock, application, table, fields)
|
return createFields(this.mock, application, table, fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
createRows(gridView, fields, rows) {
|
createGridRows(gridView, fields, rows) {
|
||||||
return createRows(this.mock, gridView, fields, rows)
|
return createGridRows(this.mock, gridView, fields, rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
createGalleryRows(gridView, fields, rows) {
|
||||||
|
return createGalleryRows(this.mock, gridView, fields, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
nextSearchForTermWillReturn(searchTerm, gridView, results) {
|
nextSearchForTermWillReturn(searchTerm, gridView, results) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ exports[`GridViewRows component with decoration Default component 1`] = `
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`GridViewRows component with decoration Should show can add decorator tooltip 1`] = `
|
exports[`GridViewRows component with decoration Should show cant add decorator tooltip 1`] = `
|
||||||
<body>
|
<body>
|
||||||
<div
|
<div
|
||||||
class="tooltip tooltip--body tooltip--center"
|
class="tooltip tooltip--body tooltip--center"
|
||||||
|
@ -95,303 +95,6 @@ exports[`GridViewRows component with decoration Should show can add decorator to
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="tooltip tooltip--body tooltip--center"
|
|
||||||
style="top: 4px; left: 0px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="tooltip__content"
|
|
||||||
>
|
|
||||||
unavailability reason
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list__item decorator-list__item--disabled"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-select"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="dropdown"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="dropdown__selected"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="dropdown__selected-icon fas fa-filter"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Fake value provider
|
|
||||||
|
|
||||||
<i
|
|
||||||
class="dropdown__toggle-icon fas fa-caret-down"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-trash"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__decorator-header-trash-link"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-trash"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
fake_value_provider_form
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-select"
|
|
||||||
style="display: none;"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-trash"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__decorator-header-trash-link"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-trash"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="value-provider-list value-provider-list--row"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-list__item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-item__title"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-filter value-provider-item__icon"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Fake value provider
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="value-provider-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake value provider description.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__footer"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__add"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-plus"
|
|
||||||
/>
|
|
||||||
|
|
||||||
viewDecoratorContext.addDecorator
|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context visibility-hidden"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context picker__context visibility-hidden"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list__item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -447,253 +150,6 @@ exports[`GridViewRows component with decoration Should show unavailable decorato
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-select"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="dropdown"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="dropdown__selected"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="dropdown__selected-icon fas fa-filter"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Fake value provider
|
|
||||||
|
|
||||||
<i
|
|
||||||
class="dropdown__toggle-icon fas fa-caret-down"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-trash"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__decorator-header-trash-link"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-trash"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
fake_value_provider_form
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-select"
|
|
||||||
style="display: none;"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__decorator-header-trash"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__decorator-header-trash-link"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-trash"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="value-provider-list value-provider-list--row"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-list__item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="value-provider-item__title"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-filter value-provider-item__icon"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Fake value provider
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="value-provider-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake value provider description.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-context__footer"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="decorator-context__add"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-plus"
|
|
||||||
/>
|
|
||||||
|
|
||||||
viewDecoratorContext.addDecorator
|
|
||||||
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context visibility-hidden"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context picker__context visibility-hidden"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-list__item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="decorator-item__image"
|
|
||||||
src="fake/url.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="decorator-item__title"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="decorator-item__description"
|
|
||||||
>
|
|
||||||
|
|
||||||
Fake decorator description
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GalleryView component with decoration Default component with first_cell decoration 1`] = `
|
||||||
|
<div
|
||||||
|
class="gallery-view"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="gallery-view__add"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fas fa-plus"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="gallery-view__scroll"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="gallery-view__cards"
|
||||||
|
style="height: 410px;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card gallery-view__card"
|
||||||
|
style="width: -60px; transform: translateX(30px) translateY(30px);"
|
||||||
|
>
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__content"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
fake_decoration: fake_value
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
fake_decoration: fake_value
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__fields"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
first
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Surname
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
Bram
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Address
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GalleryView component with decoration Default component with row wrapper decoration 1`] = `
|
||||||
|
<div
|
||||||
|
class="gallery-view"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="gallery-view__add"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fas fa-plus"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="gallery-view__scroll"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="gallery-view__cards"
|
||||||
|
style="height: 410px;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card gallery-view__card"
|
||||||
|
style="width: -60px; transform: translateX(30px) translateY(30px);"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="test-wrapper"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GalleryView component with decoration Default component with unavailable decoration 1`] = `
|
||||||
|
<div
|
||||||
|
class="gallery-view"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="gallery-view__add"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fas fa-plus"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="gallery-view__scroll"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="gallery-view__cards"
|
||||||
|
style="height: 410px;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card gallery-view__card"
|
||||||
|
style="width: -60px; transform: translateX(30px) translateY(30px);"
|
||||||
|
>
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__content"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__fields"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
first
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Surname
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
Bram
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="card__field"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card__field-name"
|
||||||
|
>
|
||||||
|
Address
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="card__field-value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="card-text"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`;
|
|
@ -0,0 +1,252 @@
|
||||||
|
import { TestApp } from '@baserow/test/helpers/testApp'
|
||||||
|
import GalleryView from '@baserow/modules/database/components/view/gallery/GalleryView'
|
||||||
|
import { DecoratorValueProviderType } from '@baserow/modules/database/decoratorValueProviders'
|
||||||
|
import { ViewDecoratorType } from '@baserow/modules/database/viewDecorators'
|
||||||
|
|
||||||
|
export class FakeDecoratorType extends ViewDecoratorType {
|
||||||
|
static getType() {
|
||||||
|
return 'fake_decorator'
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlace() {
|
||||||
|
return 'first_cell'
|
||||||
|
}
|
||||||
|
|
||||||
|
isDeactivated({ view }) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
getComponent() {
|
||||||
|
const component = {
|
||||||
|
functional: true,
|
||||||
|
|
||||||
|
render(h, ctx) {
|
||||||
|
return h('div', `fake_decoration: ${ctx.props.value}`)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FakeValueProviderType extends DecoratorValueProviderType {
|
||||||
|
static getType() {
|
||||||
|
return 'fake_value_provider_type'
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue({ options, fields, row }) {
|
||||||
|
return 'fake_value'
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormComponent() {
|
||||||
|
const component = {
|
||||||
|
functional: true,
|
||||||
|
|
||||||
|
render(h) {
|
||||||
|
return h('div', 'fake_value_provider_form')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Name',
|
||||||
|
order: 0,
|
||||||
|
type: 'text',
|
||||||
|
primary: true,
|
||||||
|
text_default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Surname',
|
||||||
|
type: 'text',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'Address',
|
||||||
|
type: 'text',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
order: '2.00000000000000000000',
|
||||||
|
field_1: 'first',
|
||||||
|
field_2: 'Bram',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
order: '2.50000000000000000000',
|
||||||
|
field_1: 'second',
|
||||||
|
field_2: 'foo',
|
||||||
|
field_3: 'bar',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
describe('GalleryView component with decoration', () => {
|
||||||
|
let testApp = null
|
||||||
|
let mockServer = null
|
||||||
|
let store = null
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
testApp = new TestApp()
|
||||||
|
store = testApp.store
|
||||||
|
mockServer = testApp.mockServer
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
testApp.afterEach().then(done)
|
||||||
|
// Clean up potentially registered stuff
|
||||||
|
try {
|
||||||
|
store.$registry.unregister('viewDecorator', 'fake_decorator')
|
||||||
|
} catch {}
|
||||||
|
try {
|
||||||
|
store.$registry.unregister(
|
||||||
|
'decoratorValueProvider',
|
||||||
|
'fake_value_provider_type'
|
||||||
|
)
|
||||||
|
} catch {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mountComponent = (props, slots = {}) => {
|
||||||
|
return testApp.mount(GalleryView, { propsData: props, slots })
|
||||||
|
}
|
||||||
|
|
||||||
|
const populateStore = async (decorations) => {
|
||||||
|
const table = mockServer.createTable()
|
||||||
|
const { application } = await mockServer.createAppAndGroup(table)
|
||||||
|
const view = mockServer.createGalleryView(application, table, {
|
||||||
|
decorations,
|
||||||
|
})
|
||||||
|
mockServer.createFields(application, table, fieldData)
|
||||||
|
await store.dispatch('field/fetchAll', table)
|
||||||
|
const primary = store.getters['field/getPrimary']
|
||||||
|
const fields = store.getters['field/getAll']
|
||||||
|
|
||||||
|
mockServer.createGalleryRows(view, fields, rows)
|
||||||
|
await store.dispatch('page/view/gallery/fetchInitial', {
|
||||||
|
viewId: 1,
|
||||||
|
fields,
|
||||||
|
primary,
|
||||||
|
})
|
||||||
|
await store.dispatch('view/fetchAll', { id: 1 })
|
||||||
|
|
||||||
|
return { table, primary, fields, view }
|
||||||
|
}
|
||||||
|
|
||||||
|
test('Default component with first_cell decoration', async () => {
|
||||||
|
const { table, primary, fields, view } = await populateStore([
|
||||||
|
{
|
||||||
|
type: 'fake_decorator',
|
||||||
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
value_provider_conf: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'fake_decorator',
|
||||||
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
value_provider_conf: {},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
|
||||||
|
store.$registry.register('viewDecorator', fakeDecorator)
|
||||||
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
|
view,
|
||||||
|
primary,
|
||||||
|
fields,
|
||||||
|
readOnly: false,
|
||||||
|
storePrefix: 'page/',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(wrapper1.element).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Default component with row wrapper decoration', async () => {
|
||||||
|
const { table, primary, fields, view } = await populateStore([
|
||||||
|
{
|
||||||
|
type: 'fake_decorator',
|
||||||
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
value_provider_conf: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'fake_decorator',
|
||||||
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
value_provider_conf: {},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
|
||||||
|
fakeDecorator.getPlace = () => 'wrapper'
|
||||||
|
fakeDecorator.getComponent = () => {
|
||||||
|
const component = {
|
||||||
|
functional: true,
|
||||||
|
|
||||||
|
render(h, ctx) {
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
{ class: { 'test-wrapper': true } },
|
||||||
|
ctx.slots().default
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
|
||||||
|
store.$registry.register('viewDecorator', fakeDecorator)
|
||||||
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
|
view,
|
||||||
|
primary,
|
||||||
|
fields,
|
||||||
|
readOnly: false,
|
||||||
|
storePrefix: 'page/',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(wrapper1.element).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Default component with unavailable decoration', async () => {
|
||||||
|
const { table, primary, fields, view } = await populateStore([
|
||||||
|
{
|
||||||
|
type: 'fake_decorator',
|
||||||
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
value_provider_conf: {},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
|
||||||
|
fakeDecorator.isDeactivated = () => true
|
||||||
|
|
||||||
|
store.$registry.register('viewDecorator', fakeDecorator)
|
||||||
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
|
view,
|
||||||
|
primary,
|
||||||
|
fields,
|
||||||
|
readOnly: false,
|
||||||
|
storePrefix: 'page/',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(wrapper1.element).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
File diff suppressed because it is too large
Load diff
|
@ -1,303 +0,0 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`GridViewRows component with decoration Default component with firs_cell decoration 1`] = `
|
|
||||||
<div
|
|
||||||
class="grid-view__rows"
|
|
||||||
style="transform: translateY(0px) translateX(0px);"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 70px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-count"
|
|
||||||
title="2"
|
|
||||||
>
|
|
||||||
|
|
||||||
2
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__row-drag"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<a
|
|
||||||
class="grid-view__row-more"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-expand"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
fake_decoration: fake_value
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
fake_decoration: fake_value
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
Bram
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__row"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 70px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-count"
|
|
||||||
title="4"
|
|
||||||
>
|
|
||||||
|
|
||||||
4
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__row-drag"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<a
|
|
||||||
class="grid-view__row-more"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-expand"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
fake_decoration: fake_value
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
fake_decoration: fake_value
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
foo
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
bar
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`GridViewRows component with decoration Default component with row wrapper decoration 1`] = `
|
|
||||||
<div
|
|
||||||
class="grid-view__rows"
|
|
||||||
style="transform: translateY(0px) translateX(0px);"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="testWrapper"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="testWrapper"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`GridViewRows component with decoration Default component with unavailable decoration 1`] = `
|
|
||||||
<div
|
|
||||||
class="grid-view__rows"
|
|
||||||
style="transform: translateY(0px) translateX(0px);"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 70px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-count"
|
|
||||||
title="2"
|
|
||||||
>
|
|
||||||
|
|
||||||
2
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__row-drag"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<a
|
|
||||||
class="grid-view__row-more"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-expand"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
Bram
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__row"
|
|
||||||
>
|
|
||||||
<!---->
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 70px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-info"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__row-count"
|
|
||||||
title="4"
|
|
||||||
>
|
|
||||||
|
|
||||||
4
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__row-drag"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<a
|
|
||||||
class="grid-view__row-more"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fas fa-expand"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
foo
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="grid-view__column"
|
|
||||||
style="width: 200px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-view__cell"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="grid-field-text"
|
|
||||||
>
|
|
||||||
bar
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { TestApp } from '@baserow/test/helpers/testApp'
|
import { TestApp } from '@baserow/test/helpers/testApp'
|
||||||
import GridViewRows from '@baserow/modules/database/components/view/grid/GridViewRows'
|
import GridView from '@baserow/modules/database/components/view/grid/GridView'
|
||||||
import { DecoratorValueProviderType } from '@baserow/modules/database/decoratorValueProviders'
|
import { DecoratorValueProviderType } from '@baserow/modules/database/decoratorValueProviders'
|
||||||
import { ViewDecoratorType } from '@baserow/modules/database/viewDecorators'
|
import { ViewDecoratorType } from '@baserow/modules/database/viewDecorators'
|
||||||
|
|
||||||
|
@ -49,7 +49,48 @@ export class FakeValueProviderType extends DecoratorValueProviderType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('GridViewRows component with decoration', () => {
|
const fieldData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Name',
|
||||||
|
order: 0,
|
||||||
|
type: 'text',
|
||||||
|
primary: true,
|
||||||
|
text_default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Surname',
|
||||||
|
type: 'text',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'Address',
|
||||||
|
type: 'text',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
order: '2.00000000000000000000',
|
||||||
|
field_1: 'first',
|
||||||
|
field_2: 'Bram',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
order: '2.50000000000000000000',
|
||||||
|
field_1: 'second',
|
||||||
|
field_2: 'foo',
|
||||||
|
field_3: 'bar',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
describe('GridView component with decoration', () => {
|
||||||
let testApp = null
|
let testApp = null
|
||||||
let mockServer = null
|
let mockServer = null
|
||||||
let store = null
|
let store = null
|
||||||
|
@ -75,69 +116,32 @@ describe('GridViewRows component with decoration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const mountComponent = (props, slots = {}) => {
|
const mountComponent = (props, slots = {}) => {
|
||||||
return testApp.mount(GridViewRows, { propsData: props, slots })
|
return testApp.mount(GridView, { propsData: props, slots })
|
||||||
}
|
}
|
||||||
|
|
||||||
const primary = {
|
|
||||||
id: 1,
|
|
||||||
name: 'Name',
|
|
||||||
order: 0,
|
|
||||||
type: 'text',
|
|
||||||
primary: true,
|
|
||||||
text_default: '',
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldData = [
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'Surname',
|
|
||||||
type: 'text',
|
|
||||||
text_default: '',
|
|
||||||
primary: false,
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'Address',
|
|
||||||
type: 'text',
|
|
||||||
text_default: '',
|
|
||||||
primary: false,
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const rows = [
|
|
||||||
{ id: 2, order: '2.00000000000000000000', field_2: 'Bram' },
|
|
||||||
{ id: 4, order: '2.50000000000000000000', field_2: 'foo', field_3: 'bar' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const populateStore = async (decorations) => {
|
const populateStore = async (decorations) => {
|
||||||
const table = mockServer.createTable()
|
const table = mockServer.createTable()
|
||||||
const { application } = await mockServer.createAppAndGroup(table)
|
const { application } = await mockServer.createAppAndGroup(table)
|
||||||
const view = mockServer.createGridView(application, table, {
|
const view = mockServer.createGridView(application, table, {
|
||||||
decorations,
|
decorations,
|
||||||
})
|
})
|
||||||
const fields = mockServer.createFields(application, table, fieldData)
|
mockServer.createFields(application, table, fieldData)
|
||||||
|
await store.dispatch('field/fetchAll', table)
|
||||||
|
const primary = store.getters['field/getPrimary']
|
||||||
|
const fields = store.getters['field/getAll']
|
||||||
|
|
||||||
mockServer.createRows(view, fields, rows)
|
mockServer.createGridRows(view, fields, rows)
|
||||||
await store.dispatch('page/view/grid/fetchInitial', {
|
await store.dispatch('page/view/grid/fetchInitial', {
|
||||||
gridId: 1,
|
gridId: 1,
|
||||||
fields,
|
fields,
|
||||||
primary,
|
primary,
|
||||||
})
|
})
|
||||||
await store.dispatch('view/fetchAll', { id: 1 })
|
await store.dispatch('view/fetchAll', { id: 1 })
|
||||||
return { table, fields, view }
|
return { table, primary, fields, view }
|
||||||
}
|
}
|
||||||
|
|
||||||
test('Default component with firs_cell decoration', async () => {
|
test('Default component with first_cell decoration', async () => {
|
||||||
const { fields, view } = await populateStore([
|
const { table, primary, fields, view } = await populateStore([
|
||||||
{
|
{
|
||||||
type: 'fake_decorator',
|
type: 'fake_decorator',
|
||||||
value_provider_type: 'fake_value_provider_type',
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
@ -157,12 +161,11 @@ describe('GridViewRows component with decoration', () => {
|
||||||
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
const wrapper1 = await mountComponent({
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
view,
|
view,
|
||||||
|
primary,
|
||||||
fields,
|
fields,
|
||||||
allFields: fields,
|
|
||||||
leftOffset: 0,
|
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
includeRowDetails: true,
|
|
||||||
storePrefix: 'page/',
|
storePrefix: 'page/',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ describe('GridViewRows component with decoration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Default component with row wrapper decoration', async () => {
|
test('Default component with row wrapper decoration', async () => {
|
||||||
const { fields, view } = await populateStore([
|
const { table, primary, fields, view } = await populateStore([
|
||||||
{
|
{
|
||||||
type: 'fake_decorator',
|
type: 'fake_decorator',
|
||||||
value_provider_type: 'fake_value_provider_type',
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
@ -192,7 +195,11 @@ describe('GridViewRows component with decoration', () => {
|
||||||
functional: true,
|
functional: true,
|
||||||
|
|
||||||
render(h, ctx) {
|
render(h, ctx) {
|
||||||
return h('div', { class: { testWrapper: true } }, ctx.slots().default)
|
return h(
|
||||||
|
'div',
|
||||||
|
{ class: { 'test-wrapper': true } },
|
||||||
|
ctx.slots().default
|
||||||
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return component
|
return component
|
||||||
|
@ -202,12 +209,11 @@ describe('GridViewRows component with decoration', () => {
|
||||||
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
const wrapper1 = await mountComponent({
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
view,
|
view,
|
||||||
|
primary,
|
||||||
fields,
|
fields,
|
||||||
allFields: fields,
|
|
||||||
leftOffset: 0,
|
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
includeRowDetails: false,
|
|
||||||
storePrefix: 'page/',
|
storePrefix: 'page/',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -215,7 +221,7 @@ describe('GridViewRows component with decoration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Default component with unavailable decoration', async () => {
|
test('Default component with unavailable decoration', async () => {
|
||||||
const { fields, view } = await populateStore([
|
const { table, primary, fields, view } = await populateStore([
|
||||||
{
|
{
|
||||||
type: 'fake_decorator',
|
type: 'fake_decorator',
|
||||||
value_provider_type: 'fake_value_provider_type',
|
value_provider_type: 'fake_value_provider_type',
|
||||||
|
@ -232,12 +238,11 @@ describe('GridViewRows component with decoration', () => {
|
||||||
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
store.$registry.register('decoratorValueProvider', fakeValueProvider)
|
||||||
|
|
||||||
const wrapper1 = await mountComponent({
|
const wrapper1 = await mountComponent({
|
||||||
|
table,
|
||||||
view,
|
view,
|
||||||
|
primary,
|
||||||
fields,
|
fields,
|
||||||
allFields: fields,
|
|
||||||
leftOffset: 0,
|
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
includeRowDetails: true,
|
|
||||||
storePrefix: 'page/',
|
storePrefix: 'page/',
|
||||||
})
|
})
|
||||||
|
|
|
@ -67,7 +67,7 @@ describe('GridViewRows component', () => {
|
||||||
const view = mockServer.createGridView(application, table, {})
|
const view = mockServer.createGridView(application, table, {})
|
||||||
const fields = mockServer.createFields(application, table, fieldData)
|
const fields = mockServer.createFields(application, table, fieldData)
|
||||||
|
|
||||||
mockServer.createRows(view, fields, rows)
|
mockServer.createGridRows(view, fields, rows)
|
||||||
await store.dispatch('page/view/grid/fetchInitial', {
|
await store.dispatch('page/view/grid/fetchInitial', {
|
||||||
gridId: 1,
|
gridId: 1,
|
||||||
fields,
|
fields,
|
||||||
|
|
|
@ -32,6 +32,17 @@ export class FakeDecoratorType extends ViewDecoratorType {
|
||||||
return 'unavailability reason'
|
return 'unavailability reason'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getComponent() {
|
||||||
|
const component = {
|
||||||
|
functional: true,
|
||||||
|
|
||||||
|
render(h, ctx) {
|
||||||
|
return h('div', `fake_decoration: ${ctx.props.value}`)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
|
||||||
canAdd({ view }) {
|
canAdd({ view }) {
|
||||||
return [true]
|
return [true]
|
||||||
}
|
}
|
||||||
|
@ -70,19 +81,51 @@ export class FakeValueProviderType extends DecoratorValueProviderType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fieldData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Name',
|
||||||
|
order: 0,
|
||||||
|
type: 'text',
|
||||||
|
primary: true,
|
||||||
|
text_default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'Surname',
|
||||||
|
type: 'text',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'Status',
|
||||||
|
type: 'single_select',
|
||||||
|
text_default: '',
|
||||||
|
primary: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const rows = [
|
||||||
|
{ id: 2, order: '2.00000000000000000000', field_2: 'Bram' },
|
||||||
|
{ id: 4, order: '2.50000000000000000000', field_2: 'foo', field_3: 'bar' },
|
||||||
|
]
|
||||||
|
|
||||||
describe('GridViewRows component with decoration', () => {
|
describe('GridViewRows component with decoration', () => {
|
||||||
let testApp = null
|
let testApp = null
|
||||||
let mockServer = null
|
let mockServer = null
|
||||||
let store = null
|
let store = null
|
||||||
|
let wrapperToDestroy = null
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
testApp = new TestApp()
|
testApp = new TestApp()
|
||||||
store = testApp.store
|
store = testApp.store
|
||||||
mockServer = testApp.mockServer
|
mockServer = testApp.mockServer
|
||||||
|
store.$registry.registerNamespace('viewDecorator')
|
||||||
|
store.$registry.registerNamespace('decoratorValueProvider')
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach((done) => {
|
afterEach((done) => {
|
||||||
testApp.afterEach().then(done)
|
|
||||||
// Clean up potentially registered stuff
|
// Clean up potentially registered stuff
|
||||||
try {
|
try {
|
||||||
store.$registry.unregister('viewDecorator', 'fake_decorator')
|
store.$registry.unregister('viewDecorator', 'fake_decorator')
|
||||||
|
@ -93,64 +136,34 @@ describe('GridViewRows component with decoration', () => {
|
||||||
'fake_value_provider_type'
|
'fake_value_provider_type'
|
||||||
)
|
)
|
||||||
} catch {}
|
} catch {}
|
||||||
|
if (wrapperToDestroy) {
|
||||||
|
wrapperToDestroy.destroy()
|
||||||
|
wrapperToDestroy = null
|
||||||
|
}
|
||||||
|
testApp.afterEach().then(done)
|
||||||
})
|
})
|
||||||
|
|
||||||
const primary = {
|
const populateStore = async ({ viewId = 1, decorations } = {}) => {
|
||||||
id: 1,
|
|
||||||
name: 'Name',
|
|
||||||
order: 0,
|
|
||||||
type: 'text',
|
|
||||||
primary: true,
|
|
||||||
text_default: '',
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldData = [
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'Surname',
|
|
||||||
type: 'text',
|
|
||||||
text_default: '',
|
|
||||||
primary: false,
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'Status',
|
|
||||||
type: 'select',
|
|
||||||
text_default: '',
|
|
||||||
primary: false,
|
|
||||||
_: {
|
|
||||||
loading: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const rows = [
|
|
||||||
{ id: 2, order: '2.00000000000000000000', field_2: 'Bram' },
|
|
||||||
{ id: 4, order: '2.50000000000000000000', field_2: 'foo', field_3: 'bar' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const populateStore = async (decorations) => {
|
|
||||||
const table = mockServer.createTable()
|
const table = mockServer.createTable()
|
||||||
const { application } = await mockServer.createAppAndGroup(table)
|
const { application } = await mockServer.createAppAndGroup(table)
|
||||||
const view = mockServer.createGridView(application, table, {
|
const view = mockServer.createGridView(application, table, {
|
||||||
decorations,
|
decorations,
|
||||||
|
viewId,
|
||||||
})
|
})
|
||||||
const fields = mockServer.createFields(application, table, fieldData)
|
|
||||||
|
|
||||||
mockServer.createRows(view, fields, rows)
|
mockServer.createFields(application, table, fieldData)
|
||||||
|
await store.dispatch('field/fetchAll', table)
|
||||||
|
const primary = store.getters['field/getPrimary']
|
||||||
|
const fields = store.getters['field/getAll']
|
||||||
|
|
||||||
|
mockServer.createGridRows(view, fields, rows)
|
||||||
await store.dispatch('page/view/grid/fetchInitial', {
|
await store.dispatch('page/view/grid/fetchInitial', {
|
||||||
gridId: 1,
|
gridId: view.id,
|
||||||
fields,
|
fields,
|
||||||
primary,
|
primary,
|
||||||
})
|
})
|
||||||
await store.dispatch('view/fetchAll', { id: 1 })
|
await store.dispatch('view/fetchAll', { id: table.id })
|
||||||
return { table, fields, view }
|
return { table, primary, fields, view }
|
||||||
}
|
}
|
||||||
|
|
||||||
const mountComponent = async (props) => {
|
const mountComponent = async (props) => {
|
||||||
|
@ -160,11 +173,15 @@ describe('GridViewRows component with decoration', () => {
|
||||||
|
|
||||||
await wrapper.vm.show(document.body)
|
await wrapper.vm.show(document.body)
|
||||||
await wrapper.vm.$nextTick()
|
await wrapper.vm.$nextTick()
|
||||||
|
|
||||||
|
// Allow to clean the DOM after the test
|
||||||
|
wrapperToDestroy = wrapper
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
test('Default component', async () => {
|
test('Default component', async () => {
|
||||||
const { table, fields, view } = await populateStore()
|
const { table, primary, fields, view } = await populateStore()
|
||||||
|
|
||||||
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
@ -184,20 +201,22 @@ describe('GridViewRows component with decoration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('View with decoration configured', async () => {
|
test('View with decoration configured', async () => {
|
||||||
const { table, fields, view } = await populateStore([
|
const { table, primary, fields, view } = await populateStore({
|
||||||
{
|
decorations: [
|
||||||
type: 'fake_decorator',
|
{
|
||||||
value_provider_type: 'fake_value_provider_type',
|
type: 'fake_decorator',
|
||||||
value_provider_conf: {},
|
value_provider_type: 'fake_value_provider_type',
|
||||||
_: { loading: false },
|
value_provider_conf: {},
|
||||||
},
|
_: { loading: false },
|
||||||
{
|
},
|
||||||
type: 'fake_decorator',
|
{
|
||||||
value_provider_type: '',
|
type: 'fake_decorator',
|
||||||
value_provider_conf: {},
|
value_provider_type: '',
|
||||||
_: { loading: false },
|
value_provider_conf: {},
|
||||||
},
|
_: { loading: false },
|
||||||
])
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
@ -217,7 +236,7 @@ describe('GridViewRows component with decoration', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Should show unavailable decorator tooltip', async () => {
|
test('Should show unavailable decorator tooltip', async () => {
|
||||||
const { table, fields, view } = await populateStore()
|
const { table, primary, fields, view } = await populateStore()
|
||||||
|
|
||||||
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
@ -242,8 +261,8 @@ describe('GridViewRows component with decoration', () => {
|
||||||
expect(document.body).toMatchSnapshot()
|
expect(document.body).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Should show can add decorator tooltip', async () => {
|
test('Should show cant add decorator tooltip', async () => {
|
||||||
const { table, fields, view } = await populateStore()
|
const { table, primary, fields, view } = await populateStore()
|
||||||
|
|
||||||
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
const fakeDecorator = new FakeDecoratorType({ app: testApp })
|
||||||
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
const fakeValueProvider = new FakeValueProviderType({ app: testApp })
|
||||||
|
|
|
@ -144,7 +144,7 @@ describe('Table Component Tests', () => {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
mockServer.createRows(gridView, fields, [
|
mockServer.createGridRows(gridView, fields, [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
order: 0,
|
order: 0,
|
||||||
|
|
|
@ -54,7 +54,7 @@ describe('View Filter Tests', () => {
|
||||||
})
|
})
|
||||||
const fields = mockServer.createFields(application, table, [field])
|
const fields = mockServer.createFields(application, table, [field])
|
||||||
|
|
||||||
mockServer.createRows(gridView, fields, [row])
|
mockServer.createGridRows(gridView, fields, [row])
|
||||||
await store.dispatch('page/view/grid/fetchInitial', {
|
await store.dispatch('page/view/grid/fetchInitial', {
|
||||||
gridId: 1,
|
gridId: 1,
|
||||||
fields: [field],
|
fields: [field],
|
||||||
|
|
Loading…
Add table
Reference in a new issue