@nextsparkjs/theme-productivity 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -0
- package/about.md +123 -0
- package/components/CardDetailModal.tsx +318 -0
- package/components/KanbanBoard.tsx +612 -0
- package/components/KanbanCard.tsx +218 -0
- package/components/KanbanColumn.tsx +264 -0
- package/components/SortableList.tsx +46 -0
- package/components/index.ts +4 -0
- package/config/app.config.ts +172 -0
- package/config/billing.config.ts +187 -0
- package/config/dashboard.config.ts +357 -0
- package/config/dev.config.ts +55 -0
- package/config/features.config.ts +256 -0
- package/config/flows.config.ts +484 -0
- package/config/permissions.config.ts +167 -0
- package/config/theme.config.ts +106 -0
- package/entities/boards/boards.config.ts +61 -0
- package/entities/boards/boards.fields.ts +154 -0
- package/entities/boards/boards.service.ts +256 -0
- package/entities/boards/boards.types.ts +57 -0
- package/entities/boards/messages/en.json +80 -0
- package/entities/boards/messages/es.json +80 -0
- package/entities/boards/migrations/001_boards_table.sql +83 -0
- package/entities/cards/cards.config.ts +61 -0
- package/entities/cards/cards.fields.ts +242 -0
- package/entities/cards/cards.service.ts +336 -0
- package/entities/cards/cards.types.ts +79 -0
- package/entities/cards/messages/en.json +114 -0
- package/entities/cards/messages/es.json +114 -0
- package/entities/cards/migrations/020_cards_table.sql +92 -0
- package/entities/lists/lists.config.ts +61 -0
- package/entities/lists/lists.fields.ts +105 -0
- package/entities/lists/lists.service.ts +252 -0
- package/entities/lists/lists.types.ts +55 -0
- package/entities/lists/messages/en.json +60 -0
- package/entities/lists/messages/es.json +60 -0
- package/entities/lists/migrations/010_lists_table.sql +79 -0
- package/lib/selectors.ts +206 -0
- package/messages/en.json +79 -0
- package/messages/es.json +79 -0
- package/migrations/999_theme_sample_data.sql +922 -0
- package/migrations/999a_initial_sample_data.sql +377 -0
- package/migrations/999b_abundant_sample_data.sql +346 -0
- package/package.json +17 -0
- package/permissions-matrix.md +122 -0
- package/styles/components.css +460 -0
- package/styles/globals.css +560 -0
- package/templates/dashboard/(main)/boards/[id]/[cardId]/page.tsx +238 -0
- package/templates/dashboard/(main)/boards/[id]/edit/page.tsx +390 -0
- package/templates/dashboard/(main)/boards/[id]/page.tsx +236 -0
- package/templates/dashboard/(main)/boards/create/page.tsx +236 -0
- package/templates/dashboard/(main)/boards/page.tsx +335 -0
- package/templates/dashboard/(main)/layout.tsx +32 -0
- package/templates/dashboard/(main)/page.tsx +592 -0
- package/templates/shared/ProductivityMobileNav.tsx +410 -0
- package/templates/shared/ProductivitySidebar.tsx +538 -0
- package/templates/shared/ProductivityTopBar.tsx +317 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Tableros",
|
|
3
|
+
"singular": "Tablero",
|
|
4
|
+
"plural": "Tableros",
|
|
5
|
+
"description": "Organiza tu trabajo en tableros",
|
|
6
|
+
|
|
7
|
+
"fields": {
|
|
8
|
+
"name": {
|
|
9
|
+
"label": "Nombre",
|
|
10
|
+
"placeholder": "Ingresa el nombre del tablero...",
|
|
11
|
+
"description": "Nombre del tablero"
|
|
12
|
+
},
|
|
13
|
+
"description": {
|
|
14
|
+
"label": "Descripción",
|
|
15
|
+
"placeholder": "Describe para qué es este tablero...",
|
|
16
|
+
"description": "Descripción opcional del tablero"
|
|
17
|
+
},
|
|
18
|
+
"color": {
|
|
19
|
+
"label": "Color",
|
|
20
|
+
"placeholder": "Seleccionar color...",
|
|
21
|
+
"description": "Color de fondo del tablero",
|
|
22
|
+
"options": {
|
|
23
|
+
"blue": "Azul",
|
|
24
|
+
"green": "Verde",
|
|
25
|
+
"purple": "Morado",
|
|
26
|
+
"orange": "Naranja",
|
|
27
|
+
"red": "Rojo",
|
|
28
|
+
"pink": "Rosa",
|
|
29
|
+
"gray": "Gris"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"archived": {
|
|
33
|
+
"label": "Archivado",
|
|
34
|
+
"description": "Archivar este tablero"
|
|
35
|
+
},
|
|
36
|
+
"position": {
|
|
37
|
+
"label": "Posición",
|
|
38
|
+
"description": "Orden de visualización"
|
|
39
|
+
},
|
|
40
|
+
"createdAt": {
|
|
41
|
+
"label": "Creado",
|
|
42
|
+
"description": "Cuándo se creó el tablero"
|
|
43
|
+
},
|
|
44
|
+
"updatedAt": {
|
|
45
|
+
"label": "Actualizado",
|
|
46
|
+
"description": "Cuándo se modificó por última vez"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
"actions": {
|
|
51
|
+
"create": "Nuevo Tablero",
|
|
52
|
+
"edit": "Editar Tablero",
|
|
53
|
+
"delete": "Eliminar Tablero",
|
|
54
|
+
"archive": "Archivar Tablero",
|
|
55
|
+
"unarchive": "Desarchivar Tablero",
|
|
56
|
+
"duplicate": "Duplicar Tablero"
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
"messages": {
|
|
60
|
+
"created": "Tablero creado exitosamente",
|
|
61
|
+
"updated": "Tablero actualizado exitosamente",
|
|
62
|
+
"deleted": "Tablero eliminado exitosamente",
|
|
63
|
+
"archived": "Tablero archivado",
|
|
64
|
+
"unarchived": "Tablero desarchivado",
|
|
65
|
+
"confirmDelete": "¿Estás seguro de que quieres eliminar este tablero? Todas las listas y tarjetas serán eliminadas permanentemente."
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
"empty": {
|
|
69
|
+
"title": "Aún no hay tableros",
|
|
70
|
+
"description": "Crea tu primer tablero para comenzar a organizar tu trabajo.",
|
|
71
|
+
"action": "Crear tu primer tablero"
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"filters": {
|
|
75
|
+
"all": "Todos los Tableros",
|
|
76
|
+
"active": "Activos",
|
|
77
|
+
"archived": "Archivados"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- Boards Table Migration
|
|
3
|
+
-- Productivity theme: Trello-style boards
|
|
4
|
+
-- ============================================================================
|
|
5
|
+
|
|
6
|
+
CREATE TABLE IF NOT EXISTS "boards" (
|
|
7
|
+
"id" TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
8
|
+
"name" VARCHAR(255) NOT NULL,
|
|
9
|
+
"description" TEXT,
|
|
10
|
+
"color" VARCHAR(20) DEFAULT 'blue',
|
|
11
|
+
"archived" BOOLEAN DEFAULT FALSE,
|
|
12
|
+
"position" INTEGER DEFAULT 0,
|
|
13
|
+
"userId" TEXT NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
|
|
14
|
+
"teamId" TEXT NOT NULL REFERENCES "teams"("id") ON DELETE CASCADE,
|
|
15
|
+
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
16
|
+
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
-- Indexes
|
|
20
|
+
CREATE INDEX IF NOT EXISTS "boards_teamId_idx" ON "boards" ("teamId");
|
|
21
|
+
CREATE INDEX IF NOT EXISTS "boards_userId_idx" ON "boards" ("userId");
|
|
22
|
+
CREATE INDEX IF NOT EXISTS "boards_archived_idx" ON "boards" ("archived") WHERE "archived" = FALSE;
|
|
23
|
+
CREATE INDEX IF NOT EXISTS "boards_position_idx" ON "boards" ("teamId", "position");
|
|
24
|
+
|
|
25
|
+
-- Enable RLS
|
|
26
|
+
ALTER TABLE "boards" ENABLE ROW LEVEL SECURITY;
|
|
27
|
+
|
|
28
|
+
-- Drop existing policies
|
|
29
|
+
DROP POLICY IF EXISTS "boards_select_policy" ON "boards";
|
|
30
|
+
DROP POLICY IF EXISTS "boards_insert_policy" ON "boards";
|
|
31
|
+
DROP POLICY IF EXISTS "boards_update_policy" ON "boards";
|
|
32
|
+
DROP POLICY IF EXISTS "boards_delete_policy" ON "boards";
|
|
33
|
+
|
|
34
|
+
-- Policy: Team members can view boards
|
|
35
|
+
CREATE POLICY "boards_select_policy" ON "boards"
|
|
36
|
+
FOR SELECT TO authenticated
|
|
37
|
+
USING (
|
|
38
|
+
"teamId" = ANY(public.get_user_team_ids())
|
|
39
|
+
OR public.is_superadmin()
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
-- Policy: Team members can create boards (owner only at app level)
|
|
43
|
+
CREATE POLICY "boards_insert_policy" ON "boards"
|
|
44
|
+
FOR INSERT TO authenticated
|
|
45
|
+
WITH CHECK (
|
|
46
|
+
"teamId" = ANY(public.get_user_team_ids())
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
-- Policy: Team members can update boards (owner only at app level)
|
|
50
|
+
CREATE POLICY "boards_update_policy" ON "boards"
|
|
51
|
+
FOR UPDATE TO authenticated
|
|
52
|
+
USING (
|
|
53
|
+
"teamId" = ANY(public.get_user_team_ids())
|
|
54
|
+
OR public.is_superadmin()
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
-- Policy: Team members can delete boards (owner only at app level)
|
|
58
|
+
CREATE POLICY "boards_delete_policy" ON "boards"
|
|
59
|
+
FOR DELETE TO authenticated
|
|
60
|
+
USING (
|
|
61
|
+
"teamId" = ANY(public.get_user_team_ids())
|
|
62
|
+
OR public.is_superadmin()
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
-- Trigger for updatedAt
|
|
66
|
+
CREATE OR REPLACE FUNCTION update_boards_updated_at()
|
|
67
|
+
RETURNS TRIGGER AS $$
|
|
68
|
+
BEGIN
|
|
69
|
+
NEW."updatedAt" = NOW();
|
|
70
|
+
RETURN NEW;
|
|
71
|
+
END;
|
|
72
|
+
$$ LANGUAGE plpgsql;
|
|
73
|
+
|
|
74
|
+
DROP TRIGGER IF EXISTS boards_updated_at_trigger ON "boards";
|
|
75
|
+
CREATE TRIGGER boards_updated_at_trigger
|
|
76
|
+
BEFORE UPDATE ON "boards"
|
|
77
|
+
FOR EACH ROW
|
|
78
|
+
EXECUTE FUNCTION update_boards_updated_at();
|
|
79
|
+
|
|
80
|
+
-- Comments
|
|
81
|
+
COMMENT ON TABLE "boards" IS 'Trello-style boards for organizing lists and cards';
|
|
82
|
+
COMMENT ON COLUMN "boards"."color" IS 'Board background color theme';
|
|
83
|
+
COMMENT ON COLUMN "boards"."position" IS 'Display order for boards';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cards Entity Configuration
|
|
3
|
+
*
|
|
4
|
+
* Task cards within lists (the main work items).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CreditCard } from 'lucide-react'
|
|
8
|
+
import type { EntityConfig } from '@nextsparkjs/core/lib/entities/types'
|
|
9
|
+
import { cardFields } from './cards.fields'
|
|
10
|
+
|
|
11
|
+
export const cardEntityConfig: EntityConfig = {
|
|
12
|
+
// ==========================================
|
|
13
|
+
// 1. BASIC IDENTIFICATION
|
|
14
|
+
// ==========================================
|
|
15
|
+
slug: 'cards',
|
|
16
|
+
enabled: true,
|
|
17
|
+
names: {
|
|
18
|
+
singular: 'card',
|
|
19
|
+
plural: 'Cards'
|
|
20
|
+
},
|
|
21
|
+
icon: CreditCard,
|
|
22
|
+
|
|
23
|
+
// ==========================================
|
|
24
|
+
// 2. ACCESS AND SCOPE CONFIGURATION
|
|
25
|
+
// ==========================================
|
|
26
|
+
access: {
|
|
27
|
+
public: false,
|
|
28
|
+
api: true,
|
|
29
|
+
metadata: false,
|
|
30
|
+
shared: true
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// ==========================================
|
|
34
|
+
// 3. UI/UX FEATURES
|
|
35
|
+
// ==========================================
|
|
36
|
+
ui: {
|
|
37
|
+
dashboard: {
|
|
38
|
+
showInMenu: true, // Show "My Cards" in menu
|
|
39
|
+
showInTopbar: true
|
|
40
|
+
},
|
|
41
|
+
public: {
|
|
42
|
+
hasArchivePage: false,
|
|
43
|
+
hasSinglePage: false
|
|
44
|
+
},
|
|
45
|
+
features: {
|
|
46
|
+
searchable: true,
|
|
47
|
+
sortable: true,
|
|
48
|
+
filterable: true,
|
|
49
|
+
bulkOperations: true,
|
|
50
|
+
importExport: false
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// ==========================================
|
|
55
|
+
// FIELDS
|
|
56
|
+
// ==========================================
|
|
57
|
+
fields: cardFields,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default cardEntityConfig
|
|
61
|
+
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cards Entity Fields Configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { EntityField } from '@nextsparkjs/core/lib/entities/types'
|
|
6
|
+
|
|
7
|
+
export const cardFields: EntityField[] = [
|
|
8
|
+
{
|
|
9
|
+
name: 'title',
|
|
10
|
+
type: 'text',
|
|
11
|
+
required: true,
|
|
12
|
+
display: {
|
|
13
|
+
label: 'Title',
|
|
14
|
+
description: 'Card title',
|
|
15
|
+
placeholder: 'Enter card title...',
|
|
16
|
+
showInList: true,
|
|
17
|
+
showInDetail: true,
|
|
18
|
+
showInForm: true,
|
|
19
|
+
order: 1,
|
|
20
|
+
columnWidth: 12,
|
|
21
|
+
},
|
|
22
|
+
api: {
|
|
23
|
+
readOnly: false,
|
|
24
|
+
searchable: true,
|
|
25
|
+
sortable: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'description',
|
|
30
|
+
type: 'textarea',
|
|
31
|
+
required: false,
|
|
32
|
+
display: {
|
|
33
|
+
label: 'Description',
|
|
34
|
+
description: 'Detailed description of the task',
|
|
35
|
+
placeholder: 'Add a more detailed description...',
|
|
36
|
+
showInList: false,
|
|
37
|
+
showInDetail: true,
|
|
38
|
+
showInForm: true,
|
|
39
|
+
order: 2,
|
|
40
|
+
columnWidth: 12,
|
|
41
|
+
},
|
|
42
|
+
api: {
|
|
43
|
+
readOnly: false,
|
|
44
|
+
searchable: true,
|
|
45
|
+
sortable: false,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'position',
|
|
50
|
+
type: 'number',
|
|
51
|
+
required: false,
|
|
52
|
+
defaultValue: 0,
|
|
53
|
+
display: {
|
|
54
|
+
label: 'Position',
|
|
55
|
+
description: 'Display order within list',
|
|
56
|
+
showInList: false,
|
|
57
|
+
showInDetail: false,
|
|
58
|
+
showInForm: false,
|
|
59
|
+
order: 3,
|
|
60
|
+
},
|
|
61
|
+
api: {
|
|
62
|
+
readOnly: false,
|
|
63
|
+
searchable: false,
|
|
64
|
+
sortable: true,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'dueDate',
|
|
69
|
+
type: 'date',
|
|
70
|
+
required: false,
|
|
71
|
+
display: {
|
|
72
|
+
label: 'Due Date',
|
|
73
|
+
description: 'When this task is due',
|
|
74
|
+
placeholder: 'Select due date...',
|
|
75
|
+
showInList: true,
|
|
76
|
+
showInDetail: true,
|
|
77
|
+
showInForm: true,
|
|
78
|
+
order: 4,
|
|
79
|
+
columnWidth: 6,
|
|
80
|
+
},
|
|
81
|
+
api: {
|
|
82
|
+
readOnly: false,
|
|
83
|
+
searchable: false,
|
|
84
|
+
sortable: true,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'priority',
|
|
89
|
+
type: 'select',
|
|
90
|
+
required: false,
|
|
91
|
+
options: [
|
|
92
|
+
{ value: 'low', label: 'Low' },
|
|
93
|
+
{ value: 'medium', label: 'Medium' },
|
|
94
|
+
{ value: 'high', label: 'High' },
|
|
95
|
+
{ value: 'urgent', label: 'Urgent' },
|
|
96
|
+
],
|
|
97
|
+
display: {
|
|
98
|
+
label: 'Priority',
|
|
99
|
+
description: 'Task priority level',
|
|
100
|
+
placeholder: 'Select priority...',
|
|
101
|
+
showInList: true,
|
|
102
|
+
showInDetail: true,
|
|
103
|
+
showInForm: true,
|
|
104
|
+
order: 5,
|
|
105
|
+
columnWidth: 6,
|
|
106
|
+
},
|
|
107
|
+
api: {
|
|
108
|
+
readOnly: false,
|
|
109
|
+
searchable: false,
|
|
110
|
+
sortable: true,
|
|
111
|
+
filterable: true,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'labels',
|
|
116
|
+
type: 'multiselect',
|
|
117
|
+
required: false,
|
|
118
|
+
options: [
|
|
119
|
+
{ value: 'urgent', label: 'Urgent' },
|
|
120
|
+
{ value: 'important', label: 'Important' },
|
|
121
|
+
{ value: 'bug', label: 'Bug' },
|
|
122
|
+
{ value: 'feature', label: 'Feature' },
|
|
123
|
+
{ value: 'enhancement', label: 'Enhancement' },
|
|
124
|
+
{ value: 'documentation', label: 'Documentation' },
|
|
125
|
+
],
|
|
126
|
+
display: {
|
|
127
|
+
label: 'Labels',
|
|
128
|
+
description: 'Tags to categorize this card',
|
|
129
|
+
placeholder: 'Select labels...',
|
|
130
|
+
showInList: true,
|
|
131
|
+
showInDetail: true,
|
|
132
|
+
showInForm: true,
|
|
133
|
+
order: 5,
|
|
134
|
+
columnWidth: 6,
|
|
135
|
+
},
|
|
136
|
+
api: {
|
|
137
|
+
readOnly: false,
|
|
138
|
+
searchable: false,
|
|
139
|
+
sortable: false,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'assigneeId',
|
|
144
|
+
type: 'reference',
|
|
145
|
+
required: false,
|
|
146
|
+
referenceEntity: 'users',
|
|
147
|
+
display: {
|
|
148
|
+
label: 'Assignee',
|
|
149
|
+
description: 'Team member assigned to this card',
|
|
150
|
+
placeholder: 'Assign to...',
|
|
151
|
+
showInList: true,
|
|
152
|
+
showInDetail: true,
|
|
153
|
+
showInForm: true,
|
|
154
|
+
order: 6,
|
|
155
|
+
columnWidth: 6,
|
|
156
|
+
},
|
|
157
|
+
api: {
|
|
158
|
+
readOnly: false,
|
|
159
|
+
searchable: false,
|
|
160
|
+
sortable: false,
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'listId',
|
|
165
|
+
type: 'reference',
|
|
166
|
+
required: true,
|
|
167
|
+
referenceEntity: 'lists',
|
|
168
|
+
display: {
|
|
169
|
+
label: 'List',
|
|
170
|
+
description: 'Parent list',
|
|
171
|
+
placeholder: 'Select list...',
|
|
172
|
+
showInList: true,
|
|
173
|
+
showInDetail: true,
|
|
174
|
+
showInForm: true,
|
|
175
|
+
order: 7,
|
|
176
|
+
columnWidth: 6,
|
|
177
|
+
},
|
|
178
|
+
api: {
|
|
179
|
+
readOnly: false,
|
|
180
|
+
searchable: false,
|
|
181
|
+
sortable: false,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'boardId',
|
|
186
|
+
type: 'reference',
|
|
187
|
+
required: true,
|
|
188
|
+
referenceEntity: 'boards',
|
|
189
|
+
display: {
|
|
190
|
+
label: 'Board',
|
|
191
|
+
description: 'Parent board',
|
|
192
|
+
placeholder: 'Select board...',
|
|
193
|
+
showInList: false,
|
|
194
|
+
showInDetail: true,
|
|
195
|
+
showInForm: true,
|
|
196
|
+
order: 8,
|
|
197
|
+
columnWidth: 12,
|
|
198
|
+
},
|
|
199
|
+
api: {
|
|
200
|
+
readOnly: false,
|
|
201
|
+
searchable: false,
|
|
202
|
+
sortable: false,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'createdAt',
|
|
207
|
+
type: 'datetime',
|
|
208
|
+
required: false,
|
|
209
|
+
display: {
|
|
210
|
+
label: 'Created At',
|
|
211
|
+
description: 'When the card was created',
|
|
212
|
+
showInList: false,
|
|
213
|
+
showInDetail: true,
|
|
214
|
+
showInForm: false,
|
|
215
|
+
order: 98,
|
|
216
|
+
},
|
|
217
|
+
api: {
|
|
218
|
+
readOnly: true,
|
|
219
|
+
searchable: false,
|
|
220
|
+
sortable: true,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: 'updatedAt',
|
|
225
|
+
type: 'datetime',
|
|
226
|
+
required: false,
|
|
227
|
+
display: {
|
|
228
|
+
label: 'Updated At',
|
|
229
|
+
description: 'When the card was last modified',
|
|
230
|
+
showInList: false,
|
|
231
|
+
showInDetail: true,
|
|
232
|
+
showInForm: false,
|
|
233
|
+
order: 99,
|
|
234
|
+
},
|
|
235
|
+
api: {
|
|
236
|
+
readOnly: true,
|
|
237
|
+
searchable: false,
|
|
238
|
+
sortable: true,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
]
|
|
242
|
+
|