Skip to main content
Version: 13.x (Current)

File Management

In Back-Kit library upload and management of files related to records is handled by three components that interact together:

These components are designed to interact with Mia Platform's Files Service, particularly the File Service Client operates as a client for the service.

File Fields

In addition to acting as a file storage service, the Files Service manages a collection of the CRUD Service, where metadata related to file storage is stored.\ A typical CRUD Service collection associated with a Files Service would include fields like:

{
"_id": {
"type": "string"
},
"name": {
"type": "string"
},
"file": {
"type": "string"
},
"size": {
"type": "number"
},
"location": {
"type": "string"
}
}

Back-Kit components that handle data from CRUD Service collections and interact with file fields expect values of file fields to be in an object (or an array of objects) following the schema mentioned above.

File properties can be specified in the data schema as:

{
"type": "object",
"format": "file"
}

or

{
"type": "array",
"format": "file"
}

File Upload with a Back-Kit Action

It is possible to upload a file using a Back-Kit Action of type file-upload.

This enables the user to pick a file from the local file system through the native upload dialog of the browser, which is injected in the body of a POST called using XMLHTTPRequest facility.

Any component that implement the Back-Kit Action interface, for instance the Button component, can be configured to perform a file-upload action.

Configuring the file-upload action to call the endpoint of a Files Service is possible.

An example is available in which the Gallery is used in conjunction with the Button to visualize the CRUD Service collection linked to a Files Service instance.

File Upload with form components

Once a file property is specified in the data schema and its form field is modified (e.g., using a Dynamic Form Drawer), the following routine is followed:

  1. The Dynamic Form Drawer notifies that a data item should be created/updated containing file fields (i.e., triggers a create-data-with-file or an update-data-with-file event). The emitted event provides information on which fields include files that should be uploaded.
  2. The File Manager handles the above event and requests the upload of each file to a storage service by firing an upload-file event for each file.
  3. The File Service Client processes the upload-file event by making HTTP calls to the Files Service to request the storage of the files. Upon success, the Files Service provides a response containing storage metadata about the newly uploaded file. The File Service Client then fires an uploaded-file event, containing this metadata.
  4. The File Manager listens for uploaded-file events and maintains a copy of the data item created or updated by the Dynamic Form Drawer in step 1, replacing the values of file fields with the returned storage metadata information.
  5. Once all files have been uploaded and the data item has been appropriately updated, the File Manager proceeds to request data creation/update by emitting a create-data or an update-data event. The payload sent in this event contains the fully edited data items, ensuring that the file fields now include the file storage metadata provided in step 3 instead of the actual file.

The process is exemplified below.

caution

Upon failure while uploading one file, any new file that was being uploaded in the same transaction will be deleted, even if already uploaded, since the final create/update of the record will not be performed

caution

By design, any file that is unlinked from the record when updating an entry, isn't deleted from the file-service

Custom Metadata

File fields may present a data-schema. This is used to describe the fields that are included in the field, and allows to specify custom fields other than the default storage metadata information.

Components like the Form Dynamic Drawer, the Form Dynamic Modal, the File Picker Drawer, the File Picker Modal allow to visualize and edit metadata fields of type string.

{
"type": "object",
"format": "file",
"dataSchema": {
"type": "object",
"properties": {
"ownerId": {
"type": "string"
}
}
}
}
{
"type": "array",
"format": "file",
"items": {
"type": "object",
"properties": {
"ownerId": {
"type": "string"
}
}
}
}

Examples

Example: Upload a file using form components

Assuming a plugin to include the following components:

  • a Dynamic Form Drawer

    {
    "tag": "bk-dynamic-form-drawer",
    "properties": {
    "dataSchema": {
    "type": "object",
    "properties": {
    "name": {
    "type": "string"
    },
    "image": {
    "type": "object",
    "format": "file"
    }
    }
    }
    }
    }
  • a File Manager

    {
    "tag": "bk-file-manager"
    }
  • a File Service Client like

    {
    "tag": "bk-file-client",
    "properties": {
    "basePath": "/files",
    "dataSchema": {
    "type": "object",
    "properties": {
    "name": {
    "type": "string"
    },
    "image": {
    "type": "object",
    "format": "file"
    }
    }
    }
    }
    }
  • a CRUD Client like

    {
    "tag": "bk-crud-client",
    "properties": {
    "basePath": "/v2/customers",
    "dataSchema": {
    "type": "object",
    "properties": {
    "name": {
    "type": "string"
    },
    "image": {
    "type": "object",
    "format": "file"
    }
    }
    }
    }
    }

The Dynamic Form Drawer allows the user to request the creation of a new data item, specifying values for fields "name" and "image". Upon submission, it emits an create-data-with-file event.\ The payload of such event could look like:

{
"name": "Alexander",
"image": ... // profile.jpg
}

Field "image" stores the a File object uploaded by the user.

The meta of the event:

{
"property": "image"
}

indicating what property within the event payload includes the file to upload to a storage service.

The File Manager listens to the event, retrieves the file to upload using the event payload and meta, and fires an upload-file event with payload like:

{
"file": ... // profile.jpg
}

signaling the need to upload the file to a storage service.

The File Service Client handles upload-file events, and consequently performs HTTP requests to a backend instance of Mia Platform's Files Service.

Following up on the example, the File Service Client emits a POST call to the endpoint "/files" (as specified in the basePath property) with a multipart body that includes the file to upload, like:

------WebKitFormBoundary5gRZNaxFPGnBKUaI
Content-Disposition: form-data; name="file"; filename="profile.jpg"
Content-Type: image/jpg


------WebKitFormBoundary5gRZNaxFPGnBKUaI--

Assuming the POST to be successful and the Files Service to respond with the storage metadata of the uploaded file, then the File Service Client notifies the correct upload of the file by emitting an uploaded-file event, injecting the received response in its payload, like:

{
"_id": "fileId7212704772008143",
"file": "profile.jpg",
"location": "/v2/files/download/profile.jpg",
"name": "profile.jpg",
"size": 3992
}

The File Manager listens to the uploaded-file event, using its payload to update the content of the received data from the initial create-data-with-file event.\ The resulting object is injected in the payload of an create-data event, like:

{
"name": "Alexander",
"image": {
"_id": "fileId7212704772008143",
"file": "profile.jpg",
"location": "/v2/files/download/profile.jpg",
"name": "profile.jpg",
"size": 3992
}
}

The CRUD Client listens to such an event, triggering a POST call to be performed to the CRUD Service, requesting the creation of the data item.

Example: Visualize Files

It is possible to visualize the CRUD Service collection of image files linked to a Files Service instance using a Gallery, a CRUD Client, and a Button.

Assuming the Files Service to be reachable at "/files" and the CRUD Service collection to be:

{
"_id": {
"type": "string"
},
"name": {
"type": "string"
},
"file": {
"type": "string"
},
"size": {
"type": "number"
},
"location": {
"type": "string"
}
}

And the components to be configured like:

  • Gallery:

    {
    "tag": "bk-gallery",
    "properties": {
    "thumbnailSource": "location",
    "titleSource": "name",
    "subTitleSource": "file"
    }
    }
  • CRUD Client:

    {
    "tag": "bk-crud-client",
    "properties": {
    "basePath": "/files",
    "dataSchema": {
    "type": "object",
    "properties": {
    "_id": {
    "type": "string"
    },
    "name": {
    "type": "string"
    },
    "file": {
    "type": "string"
    },
    "size": {
    "type": "number"
    },
    "location": {
    "type": "string"
    }
    }
    }
    }
    }
  • Button:

    {
    "tag": "bk-button",
    "properties": {
    "content": "Upload File",
    "iconId": "UploadOutlined",
    "action": {
    "type": "file-upload",
    "config": {
    "url": "/files/"
    }
    }
    }
    }

The Gallery renders an item for each entry of the collection, retrieving the image source form the "location" field, and displaying the fields "name" and "file" in the footer.

The Button allows to perform a file upload operation towards "/files/". Doing so, the Files Service stores the file to a storage service, while adding a new entry to the CRUD Service collection.

The CRUD Client is included to fetch the items of the collection to visualize.

info

In order to automatically reload the plugin after uploading the file, an onSuccess hook can be used to chain a page refresh upon successful file upload.

{
"tag": "bk-button",
"properties": {
"content": "Upload File",
"iconId": "UploadOutlined",
"action": {
"type": "file-upload",
"config": {
"url": "/files"
},
"hooks": {
"onSuccess": {
"type": "event",
"config": {
"events": "change-query"
}
}
}
}
}
}

Emitting an empty change-query event is equivalent to refreshing the page if the CRUD Client is included in the configuration.

info

To ensure that only image files can be uploaded by the user through the file-upload action, field accept is available. Property accept follows the syntax that is used by the input html-element.

{
"tag": "bk-button",
"properties": {
"content": "Upload File",
"iconId": "UploadOutlined",
"action": {
"type": "file-upload",
"config": {
"url": "/files",
"accept": "image/png, image/jpeg"
}
}
}
}