Basic
CARE comes with a range of easy-to-use and function rich base components that you can find under
frontend/src/basic. Using these components ensures a consistent design throughout the application
and makes your live as a developer much easier.
In this brief chapter we outline the toolbox of basic components in a high-level fashion. For the details of each base component, please refer to the documentation within each of them.
Code Structure Overview
Below are the folders you’ll find first under frontend/src/basic.
Each entry links to its detailed documentation. Further down on this page, you’ll find the single-file base components.
This structure mirrors the actual code layout.
Form
Renders a dynamic form from a fields description and two-way binds data via v-model.
Includes per-field validation, default values, and specialized inputs (switch, slider, select, checkbox, editor/html, textarea, table, choice, password, file, default).
<BasicForm
ref="form"
v-model="data"
:fields="fields"
@update:config-status="handleConfigStatusChange"
/>
import BasicForm from "@/basic/Form.vue";
export default {
components: { BasicForm },
data: () => ({ data: {}, fields: [] }),
methods: {
handleConfigStatusChange(s) { console.log("config:", s); },
save() { if (this.$refs.form.validate()) {/* submit */} }
}
};
Prop |
Description |
Default |
Type |
Required |
|---|---|---|---|---|
|
Two-way bound data object |
None |
Object |
True |
|
Array of field descriptors (type, key, defaults, etc.) |
None |
Object/Array |
True |
Name |
Type |
Description |
|---|---|---|
|
event |
Emits when internal data changes |
|
event |
Emits config state (e.g., |
|
method (via |
Returns |
Supported field types: switch, slider, datetime, select, checkbox, editor/html, textarea, table, choice, password, file, and a default HTML input fallback.
Note
The form auto-applies default values from fields and preserves id if present.
For detailed field options and type-specific properties, see the full Form.
Icon
All icons are based on Bootstrap icons.
The icons are included as SVGs through the Icon.vue component. Simply add the component to your template to load the respective icon. During actual loading of the icon, a loading symbol shows to ensure proper spacing and usability.
<BasicIcon iconName="<bootstrap_icon_name>" size="<size in px>"/>
import BasicIcon from '@/basic/Icon.vue'
export default {
components: {
BasicIcon
}
}
Prop |
Description |
Default |
Type |
Required |
|---|---|---|---|---|
iconName |
The name of the icon |
“IconQuestionCircle” |
String |
False |
size |
The size of the icon |
16 |
Number |
False |
color |
The color of the icon |
null |
String |
False |
Tip
Use ‘loading’ as the icon name to show a loading spinner.
Note
The list of icons can also be found in /node_modules/bootstrap-icons/icons.
For details on the underlying components (IconAsset, IconBootstrap, IconLoading) and when to use them directly, see the dedicated Icon page.
Loading
If you need to fetch resources from the server or do computations that need more than a few milliseconds, you should
provide visual feedback to the user. The Loading component offers an easy-to-use standardized way of doing this.
Simply add it to your component template, usually within an if clause conditioned on the data to be loaded.
<Loading text="<loading_text>"></Loading>
import { Loading } from '@/basic/Loading.vue';
export default {
components: {
Loading,
},
};
Prop |
Description |
Default |
Type |
Required |
|---|---|---|---|---|
text |
The text to display |
“Loading…” |
String |
False |
loading |
Whether the loading should be displayed |
True |
Boolean |
False |
Modal
Import this component if you need a modal prompted to the user. You can customize the header, body and footer.
Tip
Opening and closing of modals triggers statistics events. Additional data can be passed to the event by adding a
props attribute to the modal. This data will be passed to the event.
<BasicModal
name="Example"
:props="{ 'example': 'data' }"
@show="show"
@hide="hide">
<template #body>
<p>Example body</p>
</template>
<template #footer>
<button class="btn btn-primary" data-bs-dismiss="modal">Close</button>
</template>
</BasicModal>
import BasicModal from '@/basic/Modal.vue';
export default {
name: 'ModalExample',
components: {
BasicModal,
},
methods: {
show() {
console.log('show modal');
},
hide() {
console.log('hide modal');
},
},
};
Prop |
Description |
Default |
Type |
Required |
|---|---|---|---|---|
name |
The name of the modal |
None |
String |
True |
props |
The props to pass for the statistics event |
{} |
Object |
False |
autoOpen |
Whether the modal should be opened automatically |
False |
Boolean |
False |
removeClose |
Whether the close button should be removed, | modal is only closable by keyboard |
False |
Boolean |
False |
disableKeyboard |
Disable the keyboard for closing the modal |
False |
Boolean |
False |
lg |
Whether the modal should be large |
False |
Boolean |
False |
xl |
Whether the modal should be extra large |
False |
Boolean |
False |
Table
The table component renders data using a declarative columns description and flexible options (sorting, filtering, search, selection, pagination). Use it for consistent, feature-rich data grids.
<BasicTable
:columns="columns"
:data="rows"
:options="options"
:buttons="buttons"
@action="onAction"
/>
import BasicTable from '@/basic/Table.vue';
export default {
components: { BasicTable },
data() {
return {
options: { striped: true, hover: true, pagination: 10, search: true },
columns: [
{ name: 'Title', key: 'name', sortable: true },
{ name: 'Created', key: 'createdAt', type: 'datetime' },
{ name: 'Manage', key: 'manage', type: 'button-group' },
],
rows: [],
buttons: [
{ title: 'Edit', action: 'edit', icon: 'pencil' },
{ title: 'Delete', action: 'delete', icon: 'trash' },
],
};
},
methods: {
onAction(payload) { console.log(payload.action, payload.params); },
}
};
Prop |
Description |
Default |
Type |
|---|---|---|---|
|
Column config (name, key, type, sortable, filter, …) |
None |
Array (required) |
|
Row data |
|
Array |
|
Behavior/styling (striped, hover, pagination, search, selectableRows, singleSelect, sort, …) |
|
Object |
|
Extra per-row actions shown in a rightmost column |
|
Array |
|
Selected rows (when |
|
Object |
|
External count (for server-side pagination) |
|
Number |
Event |
Payload |
Description |
|---|---|---|
|
|
Emitted by buttons/toggles/icon selectors |
|
Selected rows |
Emitted when selection changes |
|
|
For server-side pagination |
For the full API (types, filters, client/server pagination), see Table.
Timer
This module provides timing utilities for countdowns. Provides emit events and supports different granularity.
<BasicTimer autostart show :resolution="1*1000" @timeStep="doSmth()" />
import BasicTimer from '@/basic/Timer.vue'
export default {
components: {
BasicTimer
},
methods: {
doSmth() {
console.log('do something');
},
},
}
Prop |
Description |
Default |
Type |
Required |
|---|---|---|---|---|
autostart |
Whether the timer should start automatically |
False |
Boolean |
False |
show |
Whether the timer should be shown |
False |
Boolean |
False |
resolution |
The resolution of the timer in milliseconds |
60 * 1000 |
Number |
False |
Toast
To provide users feedback to their actions, consider using the toast messaging functionality integrated in CARE. A toast message is a simple message prompted in the viewport of the user without obstructing their view and workflow.
Toasting in the Frontend
To create such a prompt from anywhere in the application, you simply put a toast message on the eventbus of the
application:
this.eventBus.emit('toast', {title: "title", message: "Message", variant: "warning", delay: 3000});
This produces a toast with the title ‘title’ and showing the short message ‘Message’ for 3000ms before disappearing
again. By providing the variant attribute as either of the boostrap badge color
keywords, you can define the color of the prompt. For consistency, you should use the badge types consistently to their
semantics; e.g. use the “danger” keyword for errors.
Toasting from the Backend
In case you want to provide direct feedback from the backend to the user, e.g. in case of a server error upon a given
request, you can also use the Socket class’ sendToast method:
this.sendToast("Example Error Title", "Example Error Message", "danger");