Saving Fields Data in smart view (2)

Expected behavior

Hello, I’m creating a new topic similar to this one which was closed without answer Saving Fields Data in smart view

I’m wondering if there is any documentation around saving or updating fields within a smart view? Any help on this would be much appreciated

Context

  • Project name: mytraiteur
  • Team name : Operations
  • Environment name: Development | marco2
  • Agent type & version:
  • forest-express-sequelize version: 8.5.3
  • express version: 4.17.1
  • sequelize version: 5.15.1

Smart Views are more meant to replace the table-view by something which is content-specific for specific use-cases than to build full-featured forms and so on.

To modify data from a smart-view, the simpler way is to trigger smart actions (you may use “smart action forms”).

If you want to edit the records directly, you may get away with using ember-data directly.
Under the hood, a smart-view is simply an ember component which is getting injected in the application.

I’m trying to update smart field, so I’m trying not to duplicate code that is already in
I’m talking about set of smart field :

{
  field: 'field',
  type: 'String',
  get: async (row) => {
    // doesn't matter
  },
  set: async (row) => {
    // code that I don't want to duplicate
  },
}

Is there a way to use the default put route ?

router.put('/table/:recordId', permissionMiddlewareCreator.details(), async (req, res, next) => {
 // I would like to access this route from smart view
})

I want to trigger this when clicking on

<BetaCheckbox @value={{someValue}} @small={{true}} @disabled={{false}} @onChange={{fn this.updateRecord  this.currentRecord}} />

or

<BetaRadioButton @onChange={{fn this.updateRecord this.currentRecord}} @class='c-beta-radio-button-duration' @namePath='label' @options={{options}} @value={{someValue}} @valuePath='value' />

Looking at the ember-data documentation, would that work?

import { action } from '@ember/object';

class MyComponent {
  [...]

  @action
  async updateRecord(record) {
    record.yourField = 'something';
    await record.save();
  }

Yes it’s working but as I said i’m trying to update smart field. When I update smart fields that I’m using inside the smart view I’m not really updating a record. I’m updating a value inside redis :

 {
  field: 'One of my smart field',
  type: 'Enum',
  enums: ['NA', 'À faire', 'À préparer', 'Envoyé', 'Validé', 'Modifié'],
  get: async function (order) {
    const equipment = await Redis.get(`order:${order.id}:equipment`)
    if (!equipment) {
      await Redis.set(`order:${order.id}:equipment`, order.equipment ? 'À faire' : 'NA')
    }
    return Redis.get(`order:${order.id}:equipment`)
  },
  set: (order, equipment) => {
    Redis.set(`order:${order.id}:equipment`, equipment)
    return order
  },
}

And I’m importing redis like this :

const Redis = require('../config/redis')

And I can’t find a way to import my redis conf inside the component of my smart view

From the smart-view point of view, a smartfield is just another field, so this should not cause issues.

Are you having an error?

Oh ok I didn’t get that.

I have this inside my template handlebar :

<BetaCheckbox @value={{false}} @small={{true}} @disabled={{false}} @onChange={{fn this.updateRecord this.currentRecord type supplier}} />

I’m doing this in my component :

  @tracked currentRecord = null

  @action
  selectRecord(record) {
    this.currentRecord = record
  }

  @action
  async updateRecord(record, type, supplier, value) {
    record.productOrder = { type, supplier, value }
    await record.save()
    return record
  }

with this smart field :

 {
  field: 'productOrder',
  type: 'String',
  get: async function (order) {
    // some stuff
  },
  set: (logistic, { type, supplier, value }) => {
    console.log(logistic.id)
    console.log(type)
    console.log(supplier)
    console.log(value)

    return logistic
  },
}

and this route :

router.put('/logistics/:recordId', permissionMiddlewareCreator.details(), async (req, res, next) => {
  const { body, params, query, user } = req
  console.log(body)
  // logic for update
})

But log of the body doesn’t contain productOrder. So it doesn’t go inside the set of my smart field

That’s weird, I tried with this another action =>

<BetaRadioButton @onChange={{fn this.updateShipping this.currentRecord}} @class='c-beta-radio-button-duration' @namePath='label' @options={{this.shipping}} @value={{this.currentRecord.forest-Shipping}} @valuePath='value' />
  @action
  async updateShipping(record, value) {
    record.shipping = value
    await record.save()
  }

And I do have the attributes logged :

{
  data: {
    id: '7652',
    attributes: { Shipping: 'NA' },
    relationships: { admin: [Object] },
    type: 'logistics'
  }
}

I will continue to investigate

Ok it seems that this line is useless

  @action
  async updateShipping(record, value) {
    record.shipping = value // this line is useless
    await record.save()
  }

The attributes seems to be directly recovered from the template. So I need to do the same for checkboxes :

@value={{this.currentRecord.forest-productOrder}}

on my

<BetaCheckbox @value={{this.currentRecord.forest-productOrder}} @small={{true}} @disabled={{false}} @onChange={{fn this.updateRecord this.currentRecord type supplier}} />

It’s working but it doesn’t send what I want. Only true or false depending on the checkbox. And I need more info => { type, supplier, value }. I also have multiple checkboxes on the same view that are linked to productOrder field. So with this @value they are connected and I don’t want that.

I need multiple checkboxes that update the same smart field with different value depending on the checkbox. Do you think there is a way to do that ? (I can’t make multiple smart field because checkboxes are made dynamically depending on the content of my record)

It was just

  @action
  async updateRecord(record, type, supplier, value) {
    record['forest-productOrder'] = JSON.stringify({ type, supplier, value })
    await record.save()
  }

Thanks for the help !