3
0

Add record from record selector field

This commit is contained in:
Katrin Yordanova 2024-06-25 16:33:41 +03:00 committed by Jože Fortun
parent a614efabb7
commit 5c1fb4a933
7 changed files with 291 additions and 132 deletions

View File

@ -40,85 +40,119 @@
:show-list="field.options.selectType !== 'multiple'"
>
<template #single>
<c-input-select
v-if="field.options.selectType === 'multiple'"
v-model="multipleSelected"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:clearable="false"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
multiple
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<b-input-group class="d-flex w-100">
<c-input-select
v-if="field.options.selectType === 'multiple'"
v-model="multipleSelected"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:clearable="false"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
multiple
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<c-input-select
v-else
ref="singleSelect"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:clearable="false"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
@input="selectChange($event)"
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<c-input-select
v-else
ref="singleSelect"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:clearable="false"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
@input="selectChange($event)"
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<b-input-group-append>
<b-button
v-if="canAddRecordThroughSelectField"
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
variant="light"
class="d-flex align-items-center"
@click="addRecordThroughRecordSelectField()"
>
<font-awesome-icon
:icon="['fas', 'plus']"
class="text-primary"
/>
</b-button>
</b-input-group-append>
</b-input-group>
</template>
<template #default="ctx">
<c-input-select
<b-input-group
v-if="field.options.selectType === 'each'"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
:value="getRecord(ctx.index)"
@input="setRecord($event, ctx.index)"
@search="search"
class="d-flex w-100"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<c-input-select
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:clearable="false"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
:placeholder="placeholder"
:value="getRecord(ctx.index)"
@input="setRecord($event, ctx.index)"
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<b-input-group-append>
<b-button
v-if="canAddRecordThroughSelectField"
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
variant="light"
class="d-flex align-items-center"
@click="addRecordThroughRecordSelectField()"
>
<font-awesome-icon
:icon="['fas', 'plus']"
class="text-primary"
/>
</b-button>
</b-input-group-append>
</b-input-group>
<b-spinner
v-else-if="resolving"
variant="primary"
@ -134,28 +168,44 @@
<template
v-else
>
<c-input-select
v-model="selected"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:placeholder="placeholder"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<b-input-group>
<c-input-select
v-model="selected"
:options="options"
:get-option-key="getOptionKey"
:get-option-label="getOptionLabel"
:disabled="!module"
:loading="processing"
:placeholder="placeholder"
:filterable="false"
:searchable="searchable"
:selectable="isSelectable"
@search="search"
>
<pagination
v-if="showPagination"
slot="list-footer"
:has-prev-page="hasPrevPage"
:has-next-page="hasNextPage"
@prev="goToPage(false)"
@next="goToPage(true)"
/>
</c-input-select>
<b-input-group-append>
<b-button
v-if="canAddRecordThroughSelectField"
v-b-tooltip.hover="{ title: $t('kind.record.tooltip.addRecord'), container: '#body' }"
variant="light"
class="d-flex align-items-center"
@click="addRecordThroughRecordSelectField()"
>
<font-awesome-icon
:icon="['fas', 'plus']"
class="text-primary"
/>
</b-button>
</b-input-group-append>
</b-input-group>
<errors :errors="errors" />
</template>
@ -207,6 +257,7 @@ export default {
getModuleByID: 'module/getByID',
findUserByID: 'user/findByID',
findRecordsByIDs: 'record/findByIDs',
pages: 'page/set',
}),
options () {
@ -262,6 +313,12 @@ export default {
hasNextPage () {
return !!this.filter.nextPage
},
canAddRecordThroughSelectField () {
if (this.module === undefined) return
return !!this.getRecordSelectorPage().page.pageID && this.module.canCreateRecord
},
},
watch: {
@ -303,6 +360,7 @@ export default {
createEvents () {
this.$root.$on('record-field-change', this.refetchOnPrefilterValueChange)
this.$root.$on('module-records-updated', this.refreshOnRelatedRecordsUpdate)
},
refetchOnPrefilterValueChange ({ fieldName }) {
@ -500,6 +558,55 @@ export default {
})
},
addRecordThroughRecordSelectField () {
const { page } = this.getRecordSelectorPage()
if (page === undefined) return
const { pageID } = page
const { recordSelectorAddRecordDisplayOption } = this.extraOptions
const route = {
name: 'page.record.create',
params: { pageID, edit: true },
}
if (recordSelectorAddRecordDisplayOption === 'modal') {
this.$root.$emit('show-record-modal', {
recordID: NoID,
recordPageID: pageID,
edit: true,
})
} else if (recordSelectorAddRecordDisplayOption === 'newTab') {
window.open(this.$router.resolve(route).href)
} else {
this.$router.push(route)
}
},
refreshOnRelatedRecordsUpdate () {
const { page } = this.getRecordSelectorPage()
if (page === undefined || this.module === undefined) return
if (page.pageID !== this.$route.params.pageID) {
this.loadLatest()
}
},
getRecordSelectorPage () {
const recordFieldModuleID = this.field.options.moduleID
if (!recordFieldModuleID) return
const recordFieldPage = this.pages.find(p => p.moduleID === recordFieldModuleID)
if (!recordFieldPage) return
return {
page: recordFieldPage,
}
},
selectChange ({ recordID } = {}) {
if (!recordID) return
@ -535,6 +642,7 @@ export default {
destroyEvents () {
this.$root.$off('record-field-change', this.refetchOnPrefilterValueChange)
this.$root.$off('module-records-updated', this.refreshOnRelatedRecordsUpdate)
},
setDefaultValues () {

View File

@ -57,6 +57,11 @@ export default {
type: Boolean,
default: false,
},
extraOptions: {
type: Object,
default: () => ({}),
},
},
computed: {

View File

@ -23,6 +23,72 @@
</b-form-group>
</b-col>
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.inlineEdit.enabled')"
label-class="text-primary"
>
<c-input-checkbox
v-model="inlineRecordEditEnabled"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.horizontalFormLayout')"
label-class="text-primary"
>
<c-input-checkbox
v-model="options.horizontalFieldLayoutEnabled"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
<template v-if="isRecordConfigured">
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.add')"
label-class="text-primary"
>
<c-input-checkbox
v-model="options.recordSelectorShowAddRecordButton"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.recordSelectorAddRecordDisplayOption')"
label-class="text-primary"
>
<b-form-select
v-model="options.recordSelectorAddRecordDisplayOption"
:options="recordDisplayOptions"
:disabled="!options.recordSelectorShowAddRecordButton"
/>
</b-form-group>
</b-col>
</template>
<b-col
cols="12"
lg="6"
@ -58,38 +124,6 @@
/>
</b-form-group>
</b-col>
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.inlineEdit.enabled')"
label-class="text-primary"
>
<c-input-checkbox
v-model="inlineRecordEditEnabled"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
<b-col
cols="12"
lg="6"
>
<b-form-group
:label="$t('record.horizontalFormLayout')"
label-class="text-primary"
>
<c-input-checkbox
v-model="options.horizontalFieldLayoutEnabled"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
</b-row>
</div>
@ -277,6 +311,10 @@ export default {
this.options.inlineRecordEditEnabled = v
},
},
isRecordConfigured () {
return this.module.fields.some(f => f.kind === 'Record')
},
},
created () {

View File

@ -26,6 +26,7 @@
v-bind="{ ...$props, errors: fieldErrors(field.name) }"
:horizontal="horizontal"
:field="field"
:extra-options="options"
@change="onFieldChange(field)"
/>

View File

@ -11,8 +11,10 @@ interface FieldCondition {
interface Options {
fields: unknown[];
fieldConditions: FieldCondition[];
recordSelectorShowAddRecordButton: boolean;
magnifyOption: string;
recordSelectorDisplayOption: string;
recordSelectorAddRecordDisplayOption: string;
referenceField?: string;
referenceModuleID?: string;
inlineRecordEditEnabled: boolean;
@ -22,8 +24,10 @@ interface Options {
const defaults: Readonly<Options> = Object.freeze({
fields: [],
fieldConditions: [],
recordSelectorShowAddRecordButton: false,
magnifyOption: '',
recordSelectorDisplayOption: 'sameTab',
recordSelectorAddRecordDisplayOption: 'sameTab',
referenceField: '',
referenceModuleID: undefined,
inlineRecordEditEnabled: false,
@ -43,8 +47,8 @@ export class PageBlockRecord extends PageBlock {
applyOptions (o?: Partial<Options>): void {
if (!o) return
Apply(this.options, o, String, 'magnifyOption', 'recordSelectorDisplayOption', 'referenceField', 'referenceModuleID')
Apply(this.options, o, Boolean, 'inlineRecordEditEnabled', 'horizontalFieldLayoutEnabled')
Apply(this.options, o, String, 'magnifyOption', 'recordSelectorDisplayOption', 'recordSelectorAddRecordDisplayOption', 'referenceField', 'referenceModuleID')
Apply(this.options, o, Boolean, 'recordSelectorShowAddRecordButton', 'inlineRecordEditEnabled', 'horizontalFieldLayoutEnabled')
if (o.fields) {
this.options.fields = o.fields

View File

@ -262,6 +262,7 @@ metric:
valueLabel: Value style
label: Metric
record:
add: Can create records via selector
referenceRecordField: Reference record field
referenceRecordFieldPlaceholder: Select reference record selector
referenceRecordFieldDescription: Multi value record selector fields are not available
@ -282,7 +283,7 @@ record:
fieldsFromModule: Single record block, displaying fields ({{0}}) from module {{1}}
untitled: Untitled
recordDeleted: This record was deleted
recordSelectorDisplayOptions: On record selector click
recordSelectorDisplayOptions: On record value click
openInSameTab: Open record in the same tab
openInNewTab: Open record in a new tab
openInModal: Open record in a modal
@ -296,6 +297,7 @@ record:
condition: Condition
tooltip:
performance: Using conditional fields will impact performance
recordSelectorAddRecordDisplayOption: On selector record create
recordList:
addRecord: Add
cancelSelection: Cancel
@ -526,7 +528,7 @@ recordList:
view: View
permissions: Permissions
recordDisplayOptions: On record click
recordSelectorDisplayOptions: On record selector click
recordSelectorDisplayOptions: On record value click
addRecordOptions: On add record click
textStyles: Text Styles
configureNonWrappingFelids: Configure non-wrapping fields

View File

@ -129,6 +129,7 @@ kind:
prefilterPlaceholder: field1 = 1 AND field2 = 232
tooltip:
moduleField: Selecting a record field will impact performance
addRecord: Add a record
select:
allow-duplicates: Allow duplicates
label: Select