Skip to content

Commit

Permalink
Fix bug where certain crudRecordInterfaces were not rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
big213 committed Apr 11, 2021
1 parent e995e5e commit 397e76c
Show file tree
Hide file tree
Showing 8 changed files with 3,889 additions and 2,246 deletions.
2 changes: 0 additions & 2 deletions frontend/components/interface/crud/crudRecordInterface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,6 @@
import crudMixin from '~/mixins/crud'
export default {
name: 'CrudRecordInterface',
mixins: [crudMixin],
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,232 +530,9 @@

<script>
import crudMixin from '~/mixins/crud'
import {
collapseObject,
handleError,
serializeNestedProperty,
getPaginatorData,
} from '~/services/base'
import { executeGiraffeql } from '~/services/giraffeql'
export default {
name: 'CrudRecordInterface',
mixins: [crudMixin],
data() {
return {
rankIndex: null,
requiredFilters: [
'event.id',
'pbClass.id',
'setSize',
'createdBy.isPublic',
'isCurrent',
],
}
},
computed: {
// render the rank header ONLY if sorting by score AND with event, pbClass, setSize, isPublic, and isCurrent filters applied
isRankMode() {
let rankMode = false
if (this.options.sortBy[0] === 'score') {
const requiredFiltersSet = new Set(this.requiredFilters)
this.filters.concat(this.lockedFilters).forEach((filterObject) => {
if (requiredFiltersSet.has(filterObject.field)) {
requiredFiltersSet.delete(filterObject.field)
}
})
// if all required fields were present, add the header
if (requiredFiltersSet.size < 1) {
rankMode = true
}
}
return rankMode
},
headers() {
return (this.isRankMode
? [
{
text: 'Rank',
sortable: false,
value: 'rank',
align: 'right',
width: '50px',
},
]
: []
).concat(
this.recordInfo.paginationOptions.headers
.filter(
(headerInfo) => !this.hiddenHeaders.includes(headerInfo.field)
)
.map((headerInfo) => {
const fieldInfo = this.recordInfo.fields[headerInfo.field]
// field unknown, abort
if (!fieldInfo)
throw new Error('Unknown field: ' + headerInfo.field)
return {
text: fieldInfo.text ?? headerInfo.field,
align: headerInfo.align ?? 'left',
sortable: headerInfo.sortable,
value: fieldInfo.compoundOptions
? fieldInfo.compoundOptions.primaryField
: headerInfo.field,
width: headerInfo.width ?? null,
fieldInfo,
path: fieldInfo.compoundOptions
? fieldInfo.compoundOptions.pathPrefix
: headerInfo.field,
// headerInfo,
}
})
.concat({
text: 'Actions',
sortable: false,
value: null,
width: '50px',
...this.recordInfo.paginationOptions.headerActionOptions,
})
)
},
},
methods: {
renderRank(index) {
// if sorting desc, index must be negative
const diff = this.pageOptions.sortDesc[0] ? -1 * index : index
return this.rankIndex ? this.rankIndex + diff : ''
},
async loadData() {
this.loading.loadData = true
try {
// create a map field -> serializeFn for fast serialization
const serializeMap = new Map()
const query = collapseObject(
this.recordInfo.paginationOptions.headers
.concat(
(this.recordInfo.requiredFields ?? []).map((field) => ({
field,
}))
)
.reduce(
(total, headerInfo) => {
const fieldInfo = this.recordInfo.fields[headerInfo.field]
// field unknown, abort
if (!fieldInfo)
throw new Error('Unknown field: ' + headerInfo.field)
// if field has '+', add all of the fields
if (headerInfo.field.match(/\+/)) {
headerInfo.field.split(/\+/).forEach((field) => {
total[field] = true
// assuming all fields are valid
serializeMap.set(
field,
this.recordInfo.fields[field].serialize
)
})
} else {
total[headerInfo.field] = true
serializeMap.set(headerInfo.field, fieldInfo.serialize)
}
return total
},
{ id: true } // always add id
)
)
const args = {
[this.positivePageDelta ? 'first' : 'last']: this.options
.itemsPerPage,
...(this.options.page > 1 &&
this.positivePageDelta && {
after: this.currentPaginatorInfo.endCursor,
}),
...(!this.positivePageDelta && {
before: this.currentPaginatorInfo.startCursor,
}),
sortBy: this.options.sortBy,
sortDesc: this.options.sortDesc,
filterBy: [
this.filters.concat(this.lockedFilters).reduce((total, ele) => {
if (!total[ele.field]) total[ele.field] = {}
// check if there is a parser on the fieldInfo
const fieldInfo = this.recordInfo.fields[ele.field]
// field unknown, abort
if (!fieldInfo) throw new Error('Unknown field: ' + ele.field)
// parse '__null' to null first
const value = ele.value === '__null' ? null : ele.value
// apply parseValue function, if any
total[ele.field][ele.operator] = fieldInfo.parseValue
? fieldInfo.parseValue(value)
: value
return total
}, {}),
],
...(this.search && { search: this.search }),
...(this.groupBy && { groupBy: this.groupBy }),
}
const results = await getPaginatorData(
this,
'get' + this.capitalizedType + 'Paginator',
query,
args
)
// if any rows returned AND in isRankMode, fetch the rank of the first row
if (results.edges.length > 0 && this.isRankMode) {
const rankResults = await executeGiraffeql(this, {
getPersonalBest: {
ranking: true,
__args: {
id: results.edges[0].node.id,
},
},
})
this.rankIndex = rankResults.ranking
} else {
this.rankIndex = null
}
// remove any undefined serializeMap elements
serializeMap.forEach((val, key) => {
if (val === undefined) serializeMap.delete(key)
})
// apply serialization to results
results.edges.forEach((ele) => {
serializeMap.forEach((serialzeFn, field) => {
serializeNestedProperty(ele.node, field, serialzeFn)
})
})
this.records = results.edges.map((ele) => ele.node)
this.nextPaginatorInfo = results.paginatorInfo
} catch (err) {
handleError(this, err)
}
this.loading.loadData = false
},
},
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
>{{ item.value ? 'Following' : 'Follow' }}</v-btn
>
</div>

<GenericInput v-else :item="item" :mode="mode"></GenericInput>
</v-col>
</v-row>
Expand Down
20 changes: 18 additions & 2 deletions frontend/components/interface/viewPbCardInterface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,18 @@
v-if="editable"
small
@click.stop="
openAddRecordDialog(props.item.event.id, headerItem.value)
openEditDialog('edit', props.item[headerItem.value])
"
>mdi-pencil</v-icon
>
<v-icon
v-if="editable"
small
@click.stop="
openAddRecordDialog(props.item.event.id, headerItem.value)
"
>mdi-plus</v-icon
>
</span>
</div>
</td>
Expand Down Expand Up @@ -107,10 +115,18 @@
v-if="editable"
small
@click.stop="
openAddRecordDialog(props.item.event.id, headerItem.value)
openEditDialog('edit', props.item[headerItem.value])
"
>mdi-pencil</v-icon
>
<v-icon
v-if="editable"
small
@click.stop="
openAddRecordDialog(props.item.event.id, headerItem.value)
"
>mdi-plus</v-icon
>
</span>
</td>
</tr>
Expand Down
5 changes: 1 addition & 4 deletions frontend/components/page/crudRecordPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ export default {
},
computed: {
interfaceComponent() {
return (
this.recordInfo.paginationOptions.interfaceComponent ||
CrudRecordInterface
)
return CrudRecordInterface
},
capitalizedTypename() {
Expand Down
5 changes: 3 additions & 2 deletions frontend/mixins/crud.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
executeGiraffeqlSubscription,
} from '~/services/giraffeql'
import { unsubscribeChannels } from '~/services/pusher'
import CrudRecordInterface from '~/components/interface/crud/crudRecordInterface.vue'
import EditRecordDialog from '~/components/dialog/editRecordDialog.vue'
import SearchDialog from '~/components/dialog/searchDialog.vue'
import {
Expand All @@ -22,6 +21,8 @@ import {
} from '~/services/base'

export default {
name: 'CrudRecordInterface',

components: {
EditRecordDialog,
SearchDialog,
Expand Down Expand Up @@ -167,7 +168,7 @@ export default {
? this.expandTypeObject.component ||
this.expandTypeObject.recordInfo.paginationOptions
.interfaceComponent ||
CrudRecordInterface
'CrudRecordInterface'
: null
},
capitalizedType() {
Expand Down
Loading

0 comments on commit 397e76c

Please sign in to comment.