Having a little trouble getting started

Hey,

I had .Name in the mix as that was the label in the objecttype but I changed that so all I am focusing on now is the leaveStartDate attribute ID 2468.

Here is the code which sadly still isn’t working. The URL I am using for the fetch is the create one I found in the API. If I get this to work I will set it differently and capture workspace ID as the variable as I will want to have these entered when the app is configured for the first time for each customer I use this for (a whole new level of confusion right there).

Here is the code with the fixes in place that I think you were referring in your reply, still no joy though.

import ForgeUI, { Form, DatePicker, UserPicker, Toggle, render, QueuePage } from '@forge/ui';
import fetch from '@forge/api';

const App = () => {
  async function createAsset(attributeValues) {
    const accessToken = 'TOKEN'; // Replace with your actual access token
    const assetsUrl = 'https://api.atlassian.com/jsm/assets/workspace/WORKSPACEVALUE/v1';

    try {
      const response = await fetch(`${assetsUrl}/object/create`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          objectTypeId: '256', // Replace with the actual object type ID
          attributes: [
            {
              objectTypeAttributeId: 2468, // Replace with actual Object Type Attribute Id
              objectAttributeValues: [
                {
                  value: attributeValues.leaveStartDate
                }
              ] // Closing square bracket for objectAttributeValues
            }
          ] // Closing square bracket for attributes
        })
      });

      if (response.ok) {
        const responseData = await response.json();
        console.log('New asset created in Assets:', responseData);
      } else {
        console.error('Error creating asset in Assets:', response.statusText);
      }
    } catch (error) {
      console.error('Error:', error);
    }
  }

  async function onSubmit(formProps) {
    const newAssetValues = {
      leaveStartDate: formProps.date

      // Add more attribute values as needed
    };

    try {
      await createAsset(newAssetValues);
      console.log('Asset creation successful');
    } catch (error) {
      console.error('Error creating asset:', error);
    }
  }

  return (
    <Form onSubmit={onSubmit}>
      <DatePicker
        name="date"
        label="Leave Start Date"
        description="First day of your OOO period"
      />
      <DatePicker
        name="date2"
        label="Leave End Date"
        description="Last day of your OOO period"
      />
      <UserPicker
        name="User"
        label="Select User"
      />
      <Toggle
        label="Out of Office already"
        name="isSectionVisible"
      />
      {/* Add more form fields as needed */}
    </Form>
  );
};

export const run = render(
  <QueuePage>
    <App />
  </QueuePage>
);

when I run forge log I can see this

ERROR   2023-08-09T22:59:16.546Z 9e7aa110-7d6d-400c-ac8d-4c1577913228 Error creating asset in Assets: { code: 401, message: 'Unauthorized' }
INFO    2023-08-09T22:59:16.547Z 9e7aa110-7d6d-400c-ac8d-4c1577913228 Asset creation successful

I ran a little powershell script using the exact same token and it connects fine to the sandbox. Not sure why I am getting a 401 error.

I assume this is correct

        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json',
        },

I used the token to generate the workspaceID so I know it is valid.
Something is and isn’t working… SURELY I am close now :smiley:

@StevenLeesSmith,

You narrowed it down so well! The Assets docs has a section on auth, which refers to a section of the Confluence docs on auth on Basic Auth. In which there is a simple example showing that we mean Basic Auth, not Bearer Tokens for the API Tokens. When you “translated” from Powershell to JavaScript did you change the auth pattern?

I was just going to reply to say IT WORKED.

I was following a template I saw online and against my better judgement changed it to Bearer.

I changed it back to basic and embedded the key and it works… IT WOOOOOOOOORKS :smiley:

Now folks brace yourself.

I need to capture the workspace, and Assets ID info, token as a variable - a config screen as such… so that is going to be my next challenge.

1 Like

What on earth error is this

Trace ID: 9d832711e9f5f3cc
There was an error invoking the function - Cannot read property 'prop' of undefined

TypeError: Cannot read property 'prop' of undefined
    at index.js:32733:61
    at Reference.value (bootstrap.js:1:9280)

Looking at the code in Visual Studio Code there are no red lines, there are no values that are dimmed out to show they are not referenced correctly.

The code deploys and runs properly (i.e. I can see all the fields), but I get this error.

It is really vague. I thought the 61 was a line but that line is a { and it is correct.

Here is all the code, may not be optimal but it displays a config screen and SHOULD display the app when the config is entered but alas I am stuck at the error.

import ForgeUI, { useState, Form, TextField, Button, DatePicker, UserPicker, Toggle, render, QueuePage, Fragment } from '@forge/ui';
import api from '@forge/api';

const App = () => {
  const [showConfig, setShowConfig] = useState(true);
  const [workspaceId, setWorkspaceId] = useState('');
  const [accessToken, setAccessToken] = useState('');
  const [objectTypeId, setObjectTypeId] = useState('');
  const [leaveStartDate, setleaveStartDate] = useState('');
  const [leaveEndDate, setleaveEndDate] = useState('');
  const [leaveUser, setleaveUser] = useState('');
  const [OutOfOffice, setOutOfOffice] = useState('');
  const [Name, setName] = useState('');

  const onSaveConfig = () => {
    setShowConfig(false);
    
  };

  const createAsset = async (attributeValues) => {
    
    const assetsUrl = `https://api.atlassian.com/jsm/assets/workspace/${workspaceId}/v1`;

    try {
      const response = await api.fetch(`${assetsUrl}/object/create`, {
        method: 'POST',
        headers: {
          'Authorization': `Basic ${accessToken}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          objectTypeId: objectTypeId,
          attributes: [
            {
              objectTypeAttributeId: leaveStartDate,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveStartDate
                }
              ]
            },
            {
              objectTypeAttributeId: leaveEndDate,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveEndDate
                }
              ]
            },
            {
              objectTypeAttributeId: leaveUser,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveUser
                }
              ]
            },
            {
              objectTypeAttributeId: OutOfOffice,
              objectAttributeValues: [
                {
                  value: attributeValues.OutOfOffice
                }
              ]
            },
            {
              objectTypeAttributeId: Name, 
              objectAttributeValues: [
                {
                  value: "OOO"
                }
              ]
            },
            {
              // Add more attribute values as needed
            }
          ]
        })
      });

      if (response.ok) {
        const responseData = await response.json();
        console.log('New asset created in Assets:', responseData);
      } else {
        const errorResponseData = await response.json();
        console.error('Error creating asset in Assets:', errorResponseData);
      }
    } catch (error) {
      console.error('Error creating asset:', error);
    }
  };

  const onSubmit = async (formProps) => {
    const newAssetValues = {
      leaveStartDate: formProps.date,
      leaveEndDate: formProps.date2,
      leaveUser: formProps.User,
      OutOfOffice: formProps.isSectionVisible
      // Add more attribute values as needed
    };

    try {
      await createAsset(newAssetValues);
      console.log('Asset creation successful');
    } catch (error) {
      console.error('Error creating asset:', error);
    }
  };

  return (
    <Form onSubmit={showConfig ? onSaveConfig : onSubmit}>
      {showConfig ? (
        <Fragment>
          <TextField
            label="Workspace ID"
            name="workspaceId"
            value={workspaceId}
            onChange={(value) => setWorkspaceId(value)}
          />
          <TextField
            label="Access Token"
            name="accessToken"
            value={accessToken}
            onChange={(value) => setAccessToken(value)}
          />
          <TextField
            label="Object Type ID"
            name="objectTypeId"
            value={objectTypeId}
            onChange={(value) => setObjectTypeId(value)}
          />
          <TextField
            label="leaveStartDate"
            name="leaveStartDate"
            value={leaveStartDate}
            onChange={(value) => setleaveStartDate(value)}
          />
          <TextField
            label="leaveEndDate"
            name="leaveEndDate"
            value={leaveEndDate}
            onChange={(value) => setleaveEndDate(value)}
          />
          <TextField
            label="leaveUser"
            name="leaveUser"
            value={leaveUser}
            onChange={(value) => setleaveUser(value)}
          />
          <TextField
            label="OutOfOffice"
            name="OutOfOffice"
            value={OutOfOffice}
            onChange={(value) => setOutOfOffice(value)}
          />
          <TextField
            label="Name"
            name="Name"
            value={Name}
            onChange={(value) => setName(value)}
          />
          <Button text="Save Configuration" type="submit" />
        </Fragment>
      ) : (
        <Fragment>
          <DatePicker
            name="date"
            label="Leave Start Date"
            description="First day of your OOO period"
          />
          <DatePicker
            name="date2"
            label="Leave End Date"
            description="Last day of your OOO period"
          />
          <UserPicker
            name="User"
            label="Select User"
          />
          <Toggle
            label="Out of Office already"
            name="isSectionVisible"
          />
          {/* Add more form fields as needed */}
        </Fragment>
      )}
    </Form>
  );
};

export const run = render(
  <QueuePage>
    <App />
  </QueuePage>
);

Looking at my previous post the error SEEMS to indicate something is trying to be called before it is defined. My app deploys fine and the config fields display on screen, it fails when I click the save config button.
I have // out any of my console.log commands just to see if that was it but nope still the same error.

I can almost taste this is close to working (my first app, makes an old guy excited), would love if someone could dissect it for me.

ok it seems that when I click the Save Config button the code just ploughs on through to the const onSubmit also.

When I // the console.log above the Const onSubmit the code still errors but the “Asset Creation Successful” is displayed, which it shouldn’t as after the Configuration Saved is clicked it should just display the form and wait for data entry.

I just can’t see how to change this.

ok I have figured out why there is an issue I just can’t suss out the fix.
The Submit button is on the Configuration screen also. So somehow I think I have the whole config built in the submit function or something?!

I haven’t changed the code from the chunk I posted above, is it apparent to anyone what is in the wrong spot.

Hey Steven

How are you faring now? If you still need help I might be assist.

I’ll have to get reacquainted with the thread as it’s been a while since I’ve looked through it.

Nah I am stuck in a hole. I have the config screen that loads up and accepts the input but when I click Save Configuration it executes the Submit and fails due to nothing being entered in the second screen.

I can see it is wrong as the Save Config and submit are on the same screen and then on the second screen there are two submit buttons.

I am stuck.

I have even just tried this to save the configuration to logs so I can check the values

import ForgeUI, { QueuePage, useState, Form, TextField, Button, render } from '@forge/ui';

const App = () => {
  const [workspaceId, setWorkspaceId] = useState('');
  const [accessToken, setAccessToken] = useState('');
  const [objectTypeId, setObjectTypeId] = useState('');
  const [leaveStartDate, setLeaveStartDate] = useState('');
  const [leaveEndDate, setLeaveEndDate] = useState('');
  const [leaveUser, setLeaveUser] = useState('');
  const [OutOfOffice, setOutOfOffice] = useState('');
  const [Name, setName] = useState('');

  const onSaveConfig = () => {
    const configuration = {
      workspaceId,
      accessToken,
      objectTypeId,
      leaveStartDate,
      leaveEndDate,
      leaveUser,
      OutOfOffice,
      Name
    };

    console.log('Configuration saved:', configuration);
  };

  return (
    <Form onSubmit={onSaveConfig}>
      <TextField
        label="Workspace ID"
        name="workspaceId"
        value={workspaceId}
        onChange={(value) => setWorkspaceId(value)}
      />
      <TextField
        label="Access Token"
        name="accessToken"
        value={accessToken}
        onChange={(value) => setAccessToken(value)}
      />
      <TextField
        label="Object Type ID"
        name="objectTypeId"
        value={objectTypeId}
        onChange={(value) => setObjectTypeId(value)}
      />
      <TextField
        label="leaveStartDate"
        name="leaveStartDate"
        value={leaveStartDate}
        onChange={(value) => setLeaveStartDate(value)}
      />
      <TextField
        label="leaveEndDate"
        name="leaveEndDate"
        value={leaveEndDate}
        onChange={(value) => setLeaveEndDate(value)}
      />
      <TextField
        label="leaveUser"
        name="leaveUser"
        value={leaveUser}
        onChange={(value) => setLeaveUser(value)}
      />
      <TextField
        label="OutOfOffice"
        name="OutOfOffice"
        value={OutOfOffice}
        onChange={(value) => setOutOfOffice(value)}
      />
      <TextField
        label="Name"
        name="Name"
        value={Name}
        onChange={(value) => setName(value)}
      />
      <Button text="Save Configuration" type="submit" />
    </Form>
  );
};

export const run = render(
  <QueuePage>
    <App />
  </QueuePage>
);

I still see this error when I click save config, I cannot escape this error.

Something went wrong
Trace ID: 80631b1a44d60180
There was an error invoking the function - Cannot read property 'prop' of undefined

TypeError: Cannot read property 'prop' of undefined
    at index.js:4278:61
    at Reference.value (bootstrap.js:1:9280)

why is it quoting index.js when that file doesn’t even exist?!

got rid of the error by actually doing the button correctly

return (

Just not saving the configuration values entered. Whenever I check the log, it is blank.

INFO    2023-08-15T03:28:16.329Z 83b95869-3712-4162-aab7-a591405ca84a Configuration saved: {
  workspaceId: '',
  accessToken: '',
  objectTypeId: '',
  leaveStartDate: '',
  leaveEndDate: '',
  leaveUser: '',
  outOfOffice: '',
  userName: ''
}

Okay, cheers for the minimal reproducible example.

The props is referring to the properties of the Button component.

It’s complaining that you’re missing an onClick property on Button.

I’m curious why you have a button though. The UI Kit Form component renders a button anyway that matches with the onSubmit property on the Form.

Let me know if this didn’t help.

yeh I got past that and actually read the doco again :slight_smile:

Now I just can’t actually save the data per my last shot. The configuration values are not saving.

The UI Kit Form component does not have concepts like onChange for the TextField.

Here is an updated version. It no longer uses useState.

import ForgeUI, { AdminPage, Form, TextField, render } from '@forge/ui';

const App = () => {
  const onSaveConfig = (formData) => {
    console.log('Configuration saved:', formData);
  };

  return (
    <Form submitButtonText="Save Configuration" onSubmit={onSaveConfig}>
      <TextField
        label="Workspace ID"
        name="workspaceId"
      />
      <TextField
        label="Access Token"
        name="accessToken"
      />
      <TextField
        label="Object Type ID"
        name="objectTypeId"
      />
      <TextField
        label="leaveStartDate"
        name="leaveStartDate"
      />
      <TextField
        label="leaveEndDate"
        name="leaveEndDate"
      />
      <TextField
        label="leaveUser"
        name="leaveUser"
      />
      <TextField
        label="OutOfOffice"
        name="OutOfOffice"
      />
      <TextField
        label="Name"
        name="Name"
      />
    </Form>
  );
};

export const run = render(
    <AdminPage>
        <App />
    </AdminPage>
);

Let me know if know if you did need useState. I’m unfamiliar with how we’d do that in UI Kit, I would have to talk to the owners about the best way forward.

ok thanks HEAPS, that worked and I can see the configuration has saved in the log. I was looking around forum posts and such and saw that useState being used.
I can see it isn’t needed but now I am not sure how to handle a few things.
I had this set at the top of the code
const [showConfig, setShowConfig] = useState(true);

and then after the save config happened I had this
setShowConfig(false);

I had the two forms setup to work like this (I changed the form part to look like what you sent through).

 return (
    <Form onSubmit={showConfig ? onSaveConfig : onSubmit}>
      {showConfig ? (
        <Fragment>
          <TextField
        label="Workspace ID"
        name="workspaceId"
      />
      <TextField
        label="Access Token"
        name="accessToken"
      />
      <TextField
        label="Object Type ID"
        name="objectTypeId"
      />
      <TextField
        label="leaveStartDate"
        name="leaveStartDate"
      />
      <TextField
        label="leaveEndDate"
        name="leaveEndDate"
      />
      <TextField
        label="leaveUser"
        name="leaveUser"
      />
      <TextField
        label="OutOfOffice"
        name="OutOfOffice"
      />
      <TextField
        label="Name"
        name="Name"
      />
        </Fragment>
      ) : (
        <Fragment>
          <DatePicker
            name="date"
            label="Leave Start Date"
            description="First day of your OOO period"
          />
          <DatePicker
            name="date2"
            label="Leave End Date"
            description="Last day of your OOO period"
          />
          <UserPicker
            name="User"
            label="Select User"
          />
          <Toggle
            label="Out of Office already"
            name="isSectionVisible"
          />
          {/* Add more form fields as needed */}
        </Fragment>
      )}
    </Form>
  );
};

based on the changes I just am not sure how to hang it all together to get my second form displaying and underway now.

This is what I have hacked together

import ForgeUI, { useState, Form, TextField, Button, DatePicker, UserPicker, Toggle, render, QueuePage, Fragment } from '@forge/ui';
import api from '@forge/api';

const App = () => {
  const [showConfig, setShowConfig] = useState(true);
  const [workspaceId, setWorkspaceId] = useState('');
  const [accessToken, setAccessToken] = useState('');
  const [objectTypeId, setObjectTypeId] = useState('');
  const [leaveStartDate, setleaveStartDate] = useState('');
  const [leaveEndDate, setleaveEndDate] = useState('');
  const [leaveUser, setleaveUser] = useState('');
  const [OutOfOffice, setOutOfOffice] = useState('');
  const [Name, setName] = useState('');

  const onSaveConfig = () => {
    setShowConfig(false);
    
  };

  const createAsset = async (attributeValues) => {
    
    const assetsUrl = `https://api.atlassian.com/jsm/assets/workspace/${workspaceId}/v1`;

    try {
      const response = await api.fetch(`${assetsUrl}/object/create`, {
        method: 'POST',
        headers: {
          'Authorization': `Basic ${accessToken}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          objectTypeId: objectTypeId,
          attributes: [
            {
              objectTypeAttributeId: leaveStartDate,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveStartDate
                }
              ]
            },
            {
              objectTypeAttributeId: leaveEndDate,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveEndDate
                }
              ]
            },
            {
              objectTypeAttributeId: leaveUser,
              objectAttributeValues: [
                {
                  value: attributeValues.leaveUser
                }
              ]
            },
            {
              objectTypeAttributeId: OutOfOffice,
              objectAttributeValues: [
                {
                  value: attributeValues.OutOfOffice
                }
              ]
            },
            {
              objectTypeAttributeId: Name, 
              objectAttributeValues: [
                {
                  value: "OOO"
                }
              ]
            },
            {
              // Add more attribute values as needed
            }
          ]
        })
      });

      if (response.ok) {
        const responseData = await response.json();
        console.log('New asset created in Assets:', responseData);
      } else {
        const errorResponseData = await response.json();
        console.error('Error creating asset in Assets:', errorResponseData);
      }
    } catch (error) {
      console.error('Error creating asset:', error);
    }
  };

  const onSubmit = async (formProps) => {
    const newAssetValues = {
      leaveStartDate: formProps.date,
      leaveEndDate: formProps.date2,
      leaveUser: formProps.User,
      OutOfOffice: formProps.isSectionVisible
      // Add more attribute values as needed
    };

    try {
      await createAsset(newAssetValues);
      console.log('Asset creation successful');
    } catch (error) {
      console.error('Error creating asset:', error);
    }
  };

  return (
    <Form onSubmit={showConfig ? onSaveConfig : onSubmit}>
      {showConfig ? (
        <Fragment>
          <TextField
        label="Workspace ID"
        name="workspaceId"
      />
      <TextField
        label="Access Token"
        name="accessToken"
      />
      <TextField
        label="Object Type ID"
        name="objectTypeId"
      />
      <TextField
        label="leaveStartDate"
        name="leaveStartDate"
      />
      <TextField
        label="leaveEndDate"
        name="leaveEndDate"
      />
      <TextField
        label="leaveUser"
        name="leaveUser"
      />
      <TextField
        label="OutOfOffice"
        name="OutOfOffice"
      />
      <TextField
        label="Name"
        name="Name"
      />
        </Fragment>
      ) : (
        <Fragment>
          <DatePicker
            name="date"
            label="Leave Start Date"
            description="First day of your OOO period"
          />
          <DatePicker
            name="date2"
            label="Leave End Date"
            description="Last day of your OOO period"
          />
          <UserPicker
            name="User"
            label="Select User"
          />
          <Toggle
            label="Out of Office already"
            name="isSectionVisible"
          />
          {/* Add more form fields as needed */}
        </Fragment>
      )}
    </Form>
  );
};

export const run = render(
  <QueuePage>
    <App />
  </QueuePage>
);

For your second display to make use of what the “initial form” submitted run the functions

  const onSaveConfig = (formProps) => {
    setShowConfig(false);
    setWorkspaceId(formProps.workspaceId);
  };

Repeat for all the properties you want to carry forward.

ok I have all this working now.

Config values are entered on the first form (Token, Workspace and the assets attribute IDs), then the OOO data is entered and then when the second form is pressed Assets object is created.

I have two issues

1). Both buttons are called “Save Configuration”

I have this which is causing the problem

 <Form submitButtonText="Save Configuration" onSubmit={showConfig ? onSaveConfig : onSubmit}>
    {showConfig ? (
        <Fragment>

What can I do to have one button as Save Configuration and then the second form button to just say Submit.

2). This is the bigger one that makes this whole exercise useless - each time you go into the app (in Dev still) I have to enter all the config information, the config form displays all the time. What do I need to do to save the configuration information so when it is entered you don’t have to enter it again.

Lastly this is just to round it off, is there a way to ‘test’ the configuration before saving it to ensure it can talk to assets correctly?

Thank you.

  1. It’s not ideal but you should be able to make a ternary on the submitButtonText similar to how you’ve done with onSubmit.

I would argue a better idea would be to have two forms and hide them with the ternary. For example

return {showConfig ? <Form text="first form"></Form>
                   : <Form text="second form"></Form>}
  1. There are several places you could store this configuration information.

One such is Forge Storage.

When your app starts it should first try to fetch the configuration from this storage.

  1. That will entirely depend on the assets you’re describing.
    If you try and write to something your not allowed to you’ll usually get some error message at the time of writing. Maybe that will be enough?

Hey,

Where does that return {showConfig… part fit into the equation.

This is what I have for the form side of things

return (
    <Form submitButtonText="Save Configuration" onSubmit={showConfig ? onSaveConfig : onSubmit}>
    {showConfig ? (
        <Fragment>
              {/* Include the fields from the first code snippet */}
              <TextField label="Workspace ID" name="workspaceId" />
              <TextField label="Access Token" name="accessToken" />
              <TextField label="Object Type ID" name="objectTypeId" />
              <TextField label="leaveStartDate" name="leaveStartDate" />
              <TextField label="leaveEndDate" name="leaveEndDate" />
              <TextField label="leaveUser" name="leaveUser" />
              <TextField label="OutOfOffice" name="OutOfOffice" />
              <TextField label="Name" name="Name" />
              </Fragment>
              
    ):(
    
    <Fragment>
      <DatePicker
        name="date"
        label="Leave Start Date"
        description="First day of your OOO period"
      />
      <DatePicker
        name="date2"
        label="Leave End Date"
        description="Last day of your OOO period"
      />
      <UserPicker
        name="User"
        label="Select User"
      />
      <Toggle
        label="Out of Office already"
        name="isSectionVisible"
      />
      {/* Add more form fields as needed */}
      </Fragment>
)}
    </Form>
  );

Which is obviously incorrect as the forms are just one after the other. How do I split them out per your suggestion?

yeh I am desperately trying to figure out how to bring it all together using Forge Storage also as that seems to be the place to be.

Just have to get it all clear in my head.

Will keep at it.

ok I have success, the values are being stored in Storage now and I can refer to them when the script runs.

I have two challenges.

How can I stop the config form from displaying if there are config values stored?

Secondly, I don’t know how to make this better than it is which may lead to the first issue with the form always displaying

  return (
    <Form submitButtonText="Save Configuration" onSubmit={showConfig ? onSaveConfig : onSubmit}>
    {showConfig ? (
        <Fragment>
              {/* Include the fields from the first code snippet */}
              <TextField label="Workspace ID" name="workspaceId" />
              <TextField label="Access Token" name="accessToken" />
              <TextField label="Object Type ID" name="objectTypeId" />
              <TextField label="leaveStartDate" name="leaveStartDate" />
              <TextField label="leaveEndDate" name="leaveEndDate" />
              <TextField label="leaveUser" name="leaveUser" />
              <TextField label="OutOfOffice" name="OutOfOffice" />
              <TextField label="Name" name="Name" />
              </Fragment>
              
    ):(
    
    <Fragment>
      <DatePicker
        name="date"
        label="Leave Start Date"
        description="First day of your OOO period"
      />
      <DatePicker
        name="date2"
        label="Leave End Date"
        description="Last day of your OOO period"
      />
      <UserPicker
        name="User"
        label="Select User"
      />
      <Toggle
        label="Out of Office already"
        name="isSectionVisible"
      />
      {/* Add more form fields as needed */}
      </Fragment>
)}
    </Form>