Is it possible to add label to rjsf `oneOf` controling select? - reactjs

Let's take the default oneOf example from rjsf docs:
const schema = const schema = {
type: 'object',
oneOf: [
{
properties: {
lorem: {
type: 'string'
}
},
required: ['lorem']
},
{
properties: {
ipsum: { type: 'string' }
},
required: ['ipsum']
}
]
}
official codepen demo here
Is it possible to add a label to the select that switches between oneOf items?

You can add a field (in the example I named it "dropdownField") whose value is the condition for showing the other fields.
That field can have a title just like the others.
{
type: "object",
properties: {
dropdownField: {
title: "Your label goes here",
type: "string",
enum: ["Option 1", "Option 2"],
default: "Option 1",
},
},
dependencies: {
dropdown: {
oneOf: [
{
properties: {
dropdown: { enum: ["Option 1"] },
lorem: {
type: "string",
},
},
required: ["lorem"],
},
{
properties: {
dropdown: { enum: ["Option 2"] },
ipsum: {
type: "string",
},
},
required: ["ipsum"],
},
],
},
},
}
You can read more at the "dependencies" page.

Related

How do I update individual fields in nested objects that are in arrays in MongoDB using Mongoose?

This is my first post so please bear with me. I am building a LinkedIn clone and I am trying to keep track of the work experience, projects and courses of the users, and those will be kept in an array of objects inside of the User schema. Now let's say a user will try to add or update one of the elements in one of those arrays, I have the user ID and I am passing it to findOneAndUpdate() as the filter.
Here is my User schema:
const userSchema = new mongoose.Schema({
user_id: {
type: String,
required: [true, 'User ID required.'],
unique: true,
immutable: true,
},
name: {
type: String,
required: [true, 'Name required.'],
},
email: {
type: String,
required: [true, 'Email required.'],
unique: true,
lowercase: true,
immutable: true,
},
title: {
type: String,
},
location: {
type: String,
},
phone_number: {
type: String,
},
contact_email: {
type: String,
},
photo: {
type: String,
},
website: {
type: String,
},
backdrop: {
type: String,
},
summary: {
type: String,
},
work: {
type: String,
},
connections: {
type: Number,
},
projects: [
{
title: {
type: String,
},
description: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
technologies: {
type: String,
},
picture: {
type: String,
},
},
],
skills: [{
skill: {
name: {
type: String,
},
level: {
type: String,
},
},
}],
experience: [
{
company: {
type: String,
},
logo: {
type: String,
},
title: {
type: String,
},
location: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
education: [
{
school: {
type: String,
},
logo: {
type: String,
},
degree: {
type: String,
},
location: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
languages: [
{
name: {
type: String,
},
level: {
type: String,
},
},
],
awards: [
{
title: {
type: String,
},
date: {
type: Date,
},
awarder: {
type: String,
},
summary: {
type: String,
},
},
],
courses: [
{
title: {
type: String,
},
number: {
type: String,
},
school: {
type: String,
},
start_date: {
type: Date,
},
end_date: {
type: Date,
},
description: {
type: String,
},
},
],
});
And in my UserController.ts file, I tried using this:
const updateUser = async (req: Request, res: Response) => {
try {
const filter = { user_id: req.body.user_id };
const update = req.body;
const updatedUser = await User.findOneAndUpdate(filter, update, {
new: true,
upsert: true,
});
res.status(201).json({
status: 'success',
data: {
user: updatedUser,
},
});
} catch (err) {
res.status(400).json({
status: `ERROR: ${err}`,
message: 'error updating user',
});
}
};
And in my request using the format of the schema but that didn't work out as expected. I know mongoose will automatically give it an _id field to each of the individual objects in the array, but again, I have had no luck updating them. I tried sending a PATCH request with this as the body to add a skill like so:
{
"user_id": "xxxxxxxxxxxxxxxx",
"title": "Mr.",
"skills" : {
"name": "Flute",
"level": "Novice"
}
}
And this was the response I got. It created a skill but didnt add the data in the skill object:
{
"status": "success",
"data": {
"user": {
"_id": "63d3715f2ef9698667230a53",
"user_id": "xxxxxxxxxxxxxxxx",
"name": "Jonathan Abitbol",
"email": "yoniabitbol1#gmail.com",
"projects": [],
"skills": [
{
"_id": "63d4068d2df30c9e943e4608"
}
],
"experience": [],
"education": [],
"languages": [],
"awards": [],
"courses": [],
"__v": 0,
"title": "Mr."
}
}
}
Any help on how to add/edit the nested objects would be appreciated.

Subtract value in array based on other collection mongoose

I have the following collections
const TransactionSchema = mongoose.Schema({
schedule: {
type: mongoose.Schema.ObjectId,
required: true,
ref: "Schedule"
},
uniqueCode: {
type: String,
required: true
},
item: {
type: mongoose.Schema.ObjectId,
required: false,
ref: "Item"
},
created: {
type: Date,
default: Date.now
},
status: {
type: String,
required: false
},
})
schedule
const ScheduleSchema = mongoose.Schema({
start: {
type: Date,
required: true,
},
end: {
type: Date,
required: false,
},
questions: {
type: Array,
default: [],
},
items: [{
item: {
type: mongoose.Schema.ObjectId,
require: true,
ref: "Item"
},
stock: {
type: Number,
required: true
}
}],
status: {
type: String,
required: false
},
})
I want to return how many times the item appear in transaction and reduce it with the number of total item I have in array of objects items in schedule collection.
For example I have the following data:
transaction
[
{
"_id":ObjectId('626134d547c28b6ecc6d0c6c'),
"schedule":624edc44ac2edc1cf07821de,
"uniqueCode":"312312312312",
"created":2022-04-21T10:41:25.901+00:00,
"item": 61efd8a812432135c08a748d,
"status": "Active"
},
{
"_id":ObjectId('62615ea3db7d00061b7cc437'),
"schedule":624edc44ac2edc1cf07821de,
"uniqueCode":"1213123123",
"created":2022-04-21T13:39:47.351+00:00,
"item": 624c6b26a41c439987b1eb42,
"status": "Active"
}
]
schedule
[
{
"_id":ObjectId('624edc44ac2edc1cf07821de'),
"start":2000-01-01T00:00:00.000+00:00,
"end":2000-01-01T00:00:00.000+00:00,
"questions":[
12,
32,
122
],
"items":[
{
"item":61efd8a812432135c08a748d,
"stock":120
},
{
"item":624c6b26a41c439987b1eb42,
"stock":1000
}
],
"status":"Active"
},
]
Item
[
{
"_id": ObjectId('61efd8a812432135c08a748d'),
"name": "Samsung S21"
},
{
"_id": ObjectId('624c6b26a41c439987b1eb42'),
"name": "Iphone 10"
}
]
I want to get the following result:
[
{
"item":"Samsung S21",
"total":119
},
{
"item":"Iphone 10",
"total":999
}
]
Note: I want the query to query one schedule data only so the result only shows the items in that schedule. The first row shows 119 from total stock of item 120 - 1 which is how many times the item appeared in transaction (where the status is active). The second row shows 999 because the item has appeared in one transaction.
Thank you. Sorry for my bad English.

How to create a list of options for slash commands in discord.js

I'd like to know if it's possible to create a slash command in the discord.js bot with one of the options receiving the type as an array of options, likely the following:
export enum LabTypes {
Simulated = "SIMULATED",
Odyssey = "ODYSSEY",
Guided = "GUIDED",
CloudCity = "CLOUD_CITY",
CommandCenter = "COMMAND_CENTER",
Embeded = "EMBEDED"
}
And
{
name: "type",
description: "Enter the HOL type",
type: this.commandsType.LAB_TYPES,
required: true,
}
I would like in the type parameter, the LabTypes options to be suggested.
Resolved by including the choices on my question.
Here's the code:
{
name: "type",
description: "Enter the HOL type",
type: this.commandsType.STRING,
required: true,
choices: [
{
name: "GUIDED",
value: "GUIDED"
},
{
name: "ODYSSEY",
value: "ODYSSEY"
},
{
name: "SIMULATED",
value: "SIMULATED"
},
{
name: "CLOUD CITY",
value: "CLOUD_CITY"
},
{
name: "COMMAND CENTER",
value: "COMMAND_CENTER"
},
{
name: "EMBEDED",
value: "EMBEDED"
},
]
}
Simple as that.
References: https://canary.discord.com/developers/docs/interactions/slash-commands

How to make a dynamic watch()/usewatch() with react-hook-forms

I am having an issue were I need to generate a form from a schema and have fields dependent on each other such as enabled/disable show/hide etc.
my schema looks something like this.
contractorInformation: {
title: "ContractorInformation",
type: "object",
properties: {
contractorName: {
title: "Contractor Name",
type: "string",
ui: "input",
constraints: {
required: true
}
},
contractorFavouriteAnimal: {
title: "Contractor Favourite Animal",
type: "string",
ui: "input",
constraints: {},
dependencies: {
disabled: true,
watching: "contractorName"
// //disabled={!fullName || fullName.length === 0 || errors.fullName}
}
},
contractorEmail: {
title: "Contractor Email",
type: "string",
ui: "input",
constraints: {
common: 10
}
}
}
},
agencyInformation: {
title: "ContractorInformation",
type: "object",
properties: {
contractorName: {
title: "Contractor Name",
type: "string",
ui: "input",
constraints: {
required: true,
minLength: 3,
maxLength: 5
},
dependencies: {
disabled: true,
watching: "agencyName"
}
}
}
}
}
const watchThese = watch()
would allow me to watch everything but if I wanted to change this field from disabled to enabled I could use
<input disabled={!watchThese || watchThese.length === 0 || watchThese.fullName}/>
which works but is obviously triggered by every field.
How could I generate a dynamic watch()/useWatch() from a schema and be able to access the specific dependencies I need to enable/disable the input.
Any help would be gratefully received.
For future reference I solved it by using
export const FormField = () =>
{Object.entries(schema?.actions ?? {}).forEach(([key, value]) => value(watch(key)));
return (<div></div>)}
and update schema to match.

I want to create checkbox checked in nested data in react js

My data is in nested array objects. I want to make checked/unchecked the nodes like a tree view. ie. when any child node is selected then the parent node is checked itself.
This is my nested JSON. From this object, I create a tree view from this data:
const nodes = [
{
value: "/app",
label: "app",
children: [
{
value: "/app/Http",
label: "Http",
children: [
{
value: "/app/Http/Controllers",
label: "Controllers",
children: [
{
value: "/app/Http/Controllers/WelcomeController.js",
label: "WelcomeController.js",
},
],
},
{
value: "/app/Http/routes.js",
label: "routes.js",
},
],
},
{
value: "/app/Providers",
label: "Providers",
children: [
{
value: "/app/Http/Providers/EventServiceProvider.js",
label: "EventServiceProvider.js",
},
],
},
],
},
{
value: "/config",
label: "config",
children: [
{
value: "/config/app.js",
label: "app.js",
},
{
value: "/config/database.js",
label: "database.js",
},
],
},
{
value: "/public",
label: "public",
children: [
{
value: "/public/assets/",
label: "assets",
children: [
{
value: "/public/assets/style.css",
label: "style.css",
},
],
},
{
value: "/public/index.html",
label: "index.html",
},
],
},
{
value: "/.env",
label: ".env",
},
{
value: "/.gitignore",
label: ".gitignore",
},
{
value: "/README.md",
label: "README.md",
},
];
I am using this function to make parent checked when child is checked.
checkChange(targetNode: any, event) {
/// debugger;
const targetNodeId = targetNode.id;
this.findIndexNestedforCheckbox(targetNode, targetNodeId);
let newTableData = [...this.state.tableData];
this.setState({ tableData: newTableData, isActionFooter: true });
}
findIndexNestedforCheckbox(data, index) {
if (data.id === index) data.isChecked = "Yes";
let result;
const i = (data.children || []).findIndex((child) => {
child.isChecked = "Yes";
return (result = this.findIndexNestedforCheckbox(child, index));
});
if (result) return [i, ...result];
}
npm install react-checkbox-tree
import React from 'react';
import CheckboxTree from 'react-checkbox-tree';
const nodes = [{
value: 'mars',
label: 'Mars',
children: [
{ value: 'phobos', label: 'Phobos' },
{ value: 'deimos', label: 'Deimos' },
],
}];
class Widget extends React.Component {
state = {
checked: [],
expanded: [],
};
render() {
return (
<CheckboxTree
nodes={nodes}
checked={this.state.checked}
expanded={this.state.expanded}
onCheck={checked => this.setState({ checked })}
onExpand={expanded => this.setState({ expanded })}
/>
);
}
}

Resources