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.


Button

The button component provides a consistent wrapper around the native <button> element with support for labels, optional icons (see Bootstrap Icons), and integrated statistics events (see User Statistics ). Use it in modals, forms, or dashboards to keep actions consistent across CARE.

<BasicButton
    class="btn btn-primary"
    title="Confirm"
    icon="check2"
    @click="submit"
/>
import BasicButton from '@/basic/Button.vue';

export default {
    name: 'ButtonExample',
    components: {
        BasicButton,
    },
    methods: {
        submit() {
            console.log('confirmed');
        }
    }
};
Button properties

Prop

Description

Default

Type

title

Button tooltip and fallback label

None

String

text

Visible button label (if not set, title is used)

None

String

icon

Optional icon name (see Icon)

None

String

props

Extra payload for statistics events

None

Object

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 */} }
  }
};
Form properties

Prop

Description

Default

Type

Required

modelValue

Two-way bound data object

None

Object

True

fields

Array of field descriptors (type, key, defaults, etc.)

None

Object/Array

True

Form events & methods

Name

Type

Description

@update:modelValue

event

Emits when internal data changes

@update:config-status

event

Emits config state (e.g., { hasIncompleteConfig, incompleteSteps })

validate()

method (via ref)

Returns true if all visible fields validate

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
    }
}
Icon properties

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,
    },
};
Loading properties

Prop

Description

Default

Type

Required

text

The text to display

“Loading…”

String

False

loading

Whether the loading should be displayed

True

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); },
  }
};
Table properties

Prop

Description

Default

Type

columns

Column config (name, key, type, sortable, filter, …)

None

Array (required)

data

Row data

[]

Array

options

Behavior/styling (striped, hover, pagination, search, selectableRows, singleSelect, sort, …)

{}

Object

buttons

Extra per-row actions shown in a rightmost column

[]

Array

modelValue

Selected rows (when selectableRows is enabled)

{}

Object

count

External count (for server-side pagination)

0

Number

Events

Event

Payload

Description

@action

{ action, params, stats? }

Emitted by buttons/toggles/icon selectors

@update:modelValue

Selected rows

Emitted when selection changes

@paginationUpdate

{ page, limit, order, filter }

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');
        },
    },
}
Timer properties

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");