Missing freshly created smart actions

Hello,

Still on my translation into typescript using a side new project to better understand and upgrade my “real” project (to upgrade from v5 to v8), I now have mostly everything working as I can see but struggling with smart actions…

In fact, I imported my smart actions, I can (from the layout editor) make them visible, even make them accessible only to certain users whatever, but they don’t appear while using the app.

Expected behavior

I want my smart action to be accessible from the UI.

Actual behavior

I don’t see my smart action(s)

a.export

b.action visible

Failure Logs

I have no logs at all ^^’

Context

Let me share you my files :slight_smile:

config/database.ts

import { ConnectionOptions } from "mongoose";
import { DatabaseConfiguration } from "forest-express-mongoose";
import { resolve } from 'path';

const databaseOptions: ConnectionOptions = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
};

const databasesConfiguration: DatabaseConfiguration[] = [{
  name: 'default',
  modelsDir: resolve(__dirname, '../models'),
  connection: {
    url: process.env.DATABASE_URL,
    options: { ...databaseOptions },
  },
}];

export default databasesConfiguration;

forest/notes.ts

import {collection} from 'forest-express-mongoose';

// This file allows you to add to your Forest UI:
// - Smart actions: https://docs.forestadmin.com/documentation/reference-guide/actions/create-and-manage-smart-actions
// - Smart fields: https://docs.forestadmin.com/documentation/reference-guide/fields/create-and-manage-smart-fields
// - Smart relationships: https://docs.forestadmin.com/documentation/reference-guide/relationships/create-a-smart-relationship
// - Smart segments: https://docs.forestadmin.com/documentation/reference-guide/segments/smart-segments
collection('notes', {
    actions: [{
        name: 'Upload note picture',
        endpoint: '/forest/actions/notes/upload-note-picture',
        httpMethod: 'POST',
        type: 'single',
        fields: [{
            field: 'Note picture',
            description: 'Upload a note picture.',
            type: 'File',
            isRequired: true
        }]
    }],
    fields: [/*...*/],
    segments: [],
});

middlewares/forestadmin.ts

import * as chalk from 'chalk';
import { join } from 'path';
import { init, LianaOptions } from "forest-express-mongoose";
import { objectMapping, connections } from '../models';
import { Application } from "express";

export = async function forestadmin(app: Application): Promise<void> {
  const lianaOptions: LianaOptions = {
    configDir: join(__dirname, '../forest'),
    envSecret: process.env.FOREST_ENV_SECRET,
    authSecret: process.env.FOREST_AUTH_SECRET,
    objectMapping,
    connections,
  }

  app.use(await init(lianaOptions));

  console.log(chalk.cyan('Your admin panel is available here: https://app.forestadmin.com/projects'));

  return;
};

models/notes.ts

// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
import {Schema} from 'mongoose';

export interface INote {
    created_at: number,
    name: string,
    content: string,
}

// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = new Schema<INote>({
    'created_at': {type: Number, required: true},
    'name': {type: String, required: true},
    'content': {type: String, required: true},
}, {
    timestamps: false,
});

export default schema;

models/index.ts

import * as Mongoose from 'mongoose';
import databasesConfiguration from '../config/databases';
import noteSchema, {INote} from './note';

const connections: Record<string, Mongoose.Connection> = {};
const objectMapping = Mongoose;

const connection = Mongoose.createConnection(databasesConfiguration[0].connection.url, databasesConfiguration[0].connection.options);
connections[connection.name] = connection;

let Notes = connection.model<INote>('Notes', noteSchema, 'Notes');

export {
    objectMapping,
    connections,
    Notes,
};

package.json

{
  "name": "emixam23-update1",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node ./dist/server.js",
    "build": "rm -rf ./dist && npm run compile && npm run cp-config",
    "dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
    "compile": "tsc",
    "lint": "eslint . -c .eslintrc.json --ext .ts",
    "cp-config": "cp .env ./dist/"
  },
  "dependencies": {
    "body-parser": "1.19.0",
    "chalk": "~1.1.3",
    "cookie-parser": "1.4.4",
    "cors": "2.8.5",
    "debug": "~4.0.1",
    "dotenv": "~6.1.0",
    "express": "~4.17.1",
    "express-jwt": "6.0.0",
    "forest-express-mongoose": "^8.0.0",
    "mongoose": "~5.8.2",
    "morgan": "1.9.1",
    "require-all": "^3.0.0"
  },
  "devDependencies": {
    "@types/express": "^4.17.13",
    "@types/mongoose": "^5.11.97",
    "@types/node": "^16.4.3",
    "tsc-watch": "^4.4.0",
    "typescript": "^4.3.5"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "pretty": true,
    "sourceMap": false,
    "target": "es2017",
    "outDir": "./dist",
    "baseUrl": "./",
    "types" : ["node", "express", "forest-express-mongoose"],
    "allowJs": true
  },
  "include": ["./**/*", ".env"],
  "exclude": ["node_modules", "dist"]
}

.forestadmin-schema.json

{
  "collections": [
    {
      "name": "notes",
      "nameOld": "Notes",
      "icon": null,
      "integration": null,
      "isReadOnly": false,
      "isSearchable": true,
      "isVirtual": false,
      "onlyForRelationships": false,
      "paginationType": "page",
      "fields": [
        /* ... */
      ],
      "segments": [],
      "actions": [
        {
          "name": "Upload note picture",
          "type": "single",
          "baseUrl": null,
          "endpoint": "/forest/actions/notes/upload-note-picture",
          "httpMethod": "POST",
          "redirect": null,
          "download": false,
          "fields": [
            {
              "field": "Profile note",
              "type": "File",
              "defaultValue": null,
              "enums": null,
              "isRequired": true,
              "reference": null,
              "description": "The uploaded note picture.",
              "position": 0,
              "widget": null
            }
          ],
          "hooks": {
            "load": false,
            "change": []
          }
        }
      ]
    },
  ],
  "meta": {
    "liana": "forest-express-mongoose",
    "liana_version": "8.0.2",
    "stack": {
      "database_type": "MongoDB",
      "engine": "nodejs",
      "engine_version": "10.15.2",
      "orm_version": "5.8.13"
    }
  }
}

If you come and saw my previous post, sources are the same (so I copied/pasted) but I added two new files:

  • forest/notes.ts
  • .forestadmin-schema.json

Thanks again for your work

Max

Hello @Emixam23,

I see that you declared a single smart action.
Did you select a record then clin on the Actions button?

Let me know if it works :wink:

Hey @Guillaume_Cisco (pinging @Steve_Bunlon as he asked)

I am so sorry… How stupid I am… It wasn’t related to Single tho, it’s a mistake on my end in the example I provided you…

My issue is related to Bulk smart actions but… with your answer, I realized that I need to select n items to see these actions available :slight_smile:

So definitely a miss use on my end :stuck_out_tongue:

Thanks for your fast reply :slight_smile:

2 Likes