File: /home/posscale/public_html/printmanager/vendor/filament/forms/resources/js/components/key-value.js
export default function keyValueFormComponent({ state }) {
return {
state,
rows: [],
shouldUpdateRows: true,
init: function () {
this.updateRows()
if (this.rows.length <= 0) {
this.rows.push({ key: '', value: '' })
} else {
this.updateState()
}
this.$watch('state', (state, oldState) => {
const getLength = (value) => {
if (value === null) {
return 0
}
if (Array.isArray(value)) {
return value.length
}
if (typeof value !== 'object') {
return 0
}
return Object.keys(value).length
}
if (getLength(state) === 0 && getLength(oldState) === 0) {
return
}
this.updateRows()
})
},
addRow: function () {
this.rows.push({ key: '', value: '' })
this.updateState()
},
deleteRow: function (index) {
this.rows.splice(index, 1)
if (this.rows.length <= 0) {
this.addRow()
}
this.updateState()
},
reorderRows: function (event) {
const rows = Alpine.raw(this.rows)
this.rows = []
const reorderedRow = rows.splice(event.oldIndex, 1)[0]
rows.splice(event.newIndex, 0, reorderedRow)
this.$nextTick(() => {
this.rows = rows
this.updateState()
})
},
updateRows: function () {
if (!this.shouldUpdateRows) {
this.shouldUpdateRows = true
return
}
let rows = []
for (let [key, value] of Object.entries(this.state ?? {})) {
rows.push({
key,
value,
})
}
this.rows = rows
},
updateState: function () {
let state = {}
this.rows.forEach((row) => {
if (row.key === '' || row.key === null) {
return
}
state[row.key] = row.value
})
// This is a hack to prevent the component from updating rows again
// after a state update, which would otherwise be done by the `state`
// watcher. If rows are updated again, duplicate keys are removed.
//
// https://github.com/filamentphp/filament/issues/1107
this.shouldUpdateRows = false
this.state = state
},
}
}