Разработка кастомных модулей Directus

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомных модулей Directus
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка кастомных модулей Directus

Module Extension — полноценная Vue 3 страница в admin panel Directus с собственным маршрутом и иконкой в навигации. Используется для кастомных дашбордов, специфичного бизнес-инструментария, интеграций, которые требуют UI.

Структура модуля

npx create-directus-extension@latest
# Type: module
# Name: sales-dashboard
directus-extension-module-sales-dashboard/
├── src/
│   ├── index.ts          # Регистрация модуля
│   └── module.vue        # Основной компонент
├── package.json
└── tsconfig.json

Регистрация модуля

// src/index.ts
import ModuleComponent from './module.vue'

export default {
  id: 'sales-dashboard',        // уникальный ID → маршрут /sales-dashboard
  name: 'Sales Dashboard',
  icon: 'bar_chart',
  routes: [
    {
      path: '',
      component: ModuleComponent,
    },
    {
      path: ':orderId',
      component: () => import('./views/OrderDetail.vue'),
      props: true,
    },
  ],
}

Dashboard компонент

<!-- src/module.vue -->
<template>
  <private-view title="Sales Dashboard">
    <template #headline>Аналитика продаж</template>
    <template #title-outer:prepend>
      <v-button rounded icon secondary @click="refresh">
        <v-icon name="refresh" />
      </v-button>
    </template>
    <template #actions>
      <v-button @click="exportData">
        <v-icon name="download" left />
        Экспорт
      </v-button>
    </template>

    <!-- Основной контент -->
    <div class="dashboard-grid">
      <div class="stat-card" v-for="stat in stats" :key="stat.label">
        <div class="stat-value">{{ stat.value }}</div>
        <div class="stat-label">{{ stat.label }}</div>
        <div class="stat-change" :class="stat.change > 0 ? 'positive' : 'negative'">
          {{ stat.change > 0 ? '+' : '' }}{{ stat.change }}%
        </div>
      </div>
    </div>

    <div class="orders-table">
      <v-table
        :headers="headers"
        :items="orders"
        :loading="loading"
        show-resize
        @click:row="openOrder"
      />
    </div>
  </private-view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useApi, useRouter } from '@directus/extensions-sdk'

const api = useApi()
const router = useRouter()

const loading = ref(true)
const stats = ref<any[]>([])
const orders = ref<any[]>([])

const headers = [
  { text: 'ID', value: 'id', width: 80 },
  { text: 'Клиент', value: 'customer_email' },
  { text: 'Сумма', value: 'total', width: 120 },
  { text: 'Статус', value: 'status', width: 120 },
  { text: 'Дата', value: 'date_created', width: 160 },
]

async function fetchData() {
  loading.value = true
  try {
    const [ordersRes, statsRes] = await Promise.all([
      api.get('/items/orders', {
        params: {
          sort: '-date_created',
          limit: 50,
          fields: ['id', 'customer_email', 'total', 'status', 'date_created'],
        },
      }),
      api.get('/custom/reports/sales'),
    ])

    orders.value = ordersRes.data.data
    stats.value = [
      { label: 'Заказов сегодня', value: statsRes.data.today, change: statsRes.data.todayChange },
      { label: 'Выручка месяц', value: `${statsRes.data.monthRevenue.toLocaleString()} ₽`, change: statsRes.data.revenueChange },
    ]
  } finally {
    loading.value = false
  }
}

function openOrder({ item }: { item: any }) {
  router.push(`/sales-dashboard/${item.id}`)
}

async function exportData() {
  const response = await api.post('/custom/reports/export', {
    collection: 'orders',
    format: 'csv',
  }, { responseType: 'blob' })

  const url = URL.createObjectURL(new Blob([response.data]))
  const a = document.createElement('a')
  a.href = url
  a.download = 'orders.csv'
  a.click()
}

function refresh() { fetchData() }

onMounted(fetchData)
</script>

<style scoped>
.dashboard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; padding: 24px; }
.stat-card { background: var(--background-page); border: 1px solid var(--border-normal); border-radius: 8px; padding: 16px; }
.stat-value { font-size: 28px; font-weight: 700; }
.stat-label { color: var(--foreground-subdued); font-size: 13px; }
.positive { color: var(--success); }
.negative { color: var(--danger); }
.orders-table { padding: 0 24px 24px; }
</style>

Использование Directus API из модуля

// Доступ к стандартным Directus сервисам
const api = useApi()         // HTTP клиент (Axios)
const stores = useStores()   // Pinia stores Directus
const router = useRouter()   // Vue Router

// Создание записи
await api.post('/items/articles', { data: { title: 'New', status: 'draft' } })

// Стандартные компоненты Directus UI
// <v-button>, <v-input>, <v-select>, <v-table>, <v-icon>, <v-dialog>
// <private-view> — обёртка страницы с navigation sidebar

Сроки

Разработка кастомного модуля (дашборд с таблицами и экспортом) — 2–4 дня.