@tanglemedia/directus-collection-testimonial 0.0.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.
@@ -0,0 +1,39 @@
1
+ const COLLECTION_NAME = "tngl_testimonial";
2
+
3
+ export async function up(knex) {
4
+ // if table exists, do not proceed with migration
5
+ if (await knex.schema.hasTable(COLLECTION_NAME)) {
6
+ return;
7
+ }
8
+
9
+ // create table
10
+ await knex.schema.createTable(COLLECTION_NAME, (table) => {
11
+ table.increments("id").unsigned().notNullable();
12
+
13
+ // default fields
14
+ table.integer("sort").nullable();
15
+ table.string("status", 255).notNullable().defaultTo("draft");
16
+
17
+ // accountability fields
18
+ table.specificType("user_created", "char(36)").nullable();
19
+ table.specificType("user_updated", "char(36)").nullable();
20
+ table.timestamp("date_created").nullable();
21
+ table.timestamp("date_updated").nullable();
22
+
23
+ // custom fields
24
+ table.string("author", 255).nullable();
25
+ table.text("comment").nullable();
26
+ table.date("comment_date").nullable();
27
+
28
+ table.primary(["id"]);
29
+
30
+ // relationships
31
+ table.foreign("user_created").references("id").inTable("directus_users");
32
+ table.foreign("user_updated").references("id").inTable("directus_users");
33
+ });
34
+ }
35
+
36
+ export async function down(knex) {
37
+ // drop table
38
+ await knex.schema.dropTableIfExists(COLLECTION_NAME);
39
+ }
@@ -0,0 +1,128 @@
1
+ import { getBasicCollectionFields } from "./helpers/fields.mjs";
2
+
3
+ const COLLECTION_NAME = "tngl_testimonial";
4
+
5
+ const COLLECTION_INSERTS = [
6
+ {
7
+ accountability: "all",
8
+ archive_app_filter: true,
9
+ archive_field: "status",
10
+ archive_value: "archived",
11
+ collapse: "open",
12
+ collection: COLLECTION_NAME,
13
+ color: null,
14
+ display_template: "{{status}} {{comment}}",
15
+ group: null,
16
+ hidden: false,
17
+ icon: "comment",
18
+ item_duplication_fields: null,
19
+ note: null,
20
+ preview_url: null,
21
+ singleton: false,
22
+ sort: null,
23
+ sort_field: "sort",
24
+ unarchive_value: "draft",
25
+ versioning: false,
26
+ translations: JSON.stringify([
27
+ {
28
+ language: "en-US",
29
+ translation: "Testimonials",
30
+ },
31
+ {
32
+ language: "en-CA",
33
+ translation: "Testimonials",
34
+ },
35
+ ]),
36
+ },
37
+ ];
38
+ const FIELD_INSERTS = [
39
+ ...getBasicCollectionFields(COLLECTION_NAME),
40
+ {
41
+ collection: COLLECTION_NAME,
42
+ conditions: null,
43
+ display: null,
44
+ display_options: null,
45
+ field: "author",
46
+ group: null,
47
+ hidden: false,
48
+ interface: "input",
49
+ note: null,
50
+ options: null,
51
+ readonly: false,
52
+ required: false,
53
+ sort: 8,
54
+ special: null,
55
+ translations: null,
56
+ validation: null,
57
+ validation_message: null,
58
+ width: "full",
59
+ },
60
+ {
61
+ collection: COLLECTION_NAME,
62
+ conditions: null,
63
+ display: null,
64
+ display_options: null,
65
+ field: "comment",
66
+ group: null,
67
+ hidden: false,
68
+ interface: "input-multiline",
69
+ note: null,
70
+ options: null,
71
+ readonly: false,
72
+ required: false,
73
+ sort: 9,
74
+ special: null,
75
+ translations: null,
76
+ validation: null,
77
+ validation_message: null,
78
+ width: "full",
79
+ },
80
+ {
81
+ collection: COLLECTION_NAME,
82
+ conditions: null,
83
+ display: "datetime",
84
+ display_options: JSON.stringify({}),
85
+ field: "comment_date",
86
+ group: null,
87
+ hidden: false,
88
+ interface: "datetime",
89
+ note: null,
90
+ options: JSON.stringify({
91
+ use24: false,
92
+ }),
93
+ readonly: false,
94
+ required: false,
95
+ sort: 10,
96
+ special: null,
97
+ translations: null,
98
+ validation: null,
99
+ validation_message: null,
100
+ width: "full",
101
+ },
102
+ ];
103
+
104
+ export async function up(knex) {
105
+ // if row exists in directus_collections table, do not proceed with migration
106
+ const collectionExists = await knex("directus_collections")
107
+ .select("collection")
108
+ .where("collection", COLLECTION_NAME)
109
+ .first();
110
+
111
+ // register table into `directus_collections` table
112
+ // for full list of directus_collections properties, refer to: https://docs.directus.io/reference/system/collections.html
113
+ if (!collectionExists) {
114
+ await knex("directus_collections").insert(COLLECTION_INSERTS);
115
+ }
116
+
117
+ // register fields into `directus_fields` table
118
+ // for full list of directus_fields properties, refer to: https://docs.directus.io/reference/system/fields.html
119
+ await knex("directus_fields").insert(FIELD_INSERTS);
120
+ }
121
+
122
+ export async function down(knex) {
123
+ // remove associated data from directus_fields table
124
+ await knex("directus_fields").where("collection", COLLECTION_NAME).del();
125
+
126
+ // remove associated data from directus_collections table
127
+ await knex("directus_collections").where("collection", COLLECTION_NAME).del();
128
+ }
@@ -0,0 +1,10 @@
1
+ import { createPermission } from "./helpers/permission.mjs";
2
+
3
+ export async function up(knex) {
4
+ await createPermission(knex, "tngl_testimonial", "Website", ["read"]);
5
+ await createPermission(knex, "tngl_testimonial", "Staff", ["create", "read", "update", "delete"]);
6
+ }
7
+
8
+ export async function down(knex) {
9
+ // No rollback needed
10
+ }
@@ -0,0 +1,47 @@
1
+ const COLLECTION_NAME = "tngl_testimonial";
2
+
3
+ // preset that applies to any user or role
4
+ const PRESETS = [
5
+ {
6
+ bookmark: null,
7
+ collection: "tngl_testimonial",
8
+ color: null,
9
+ filter: null,
10
+ icon: "bookmark",
11
+ layout: null,
12
+ layout_options: JSON.stringify({
13
+ tabular: {
14
+ widths: {
15
+ author: 192.6171875,
16
+ status: 107.09375,
17
+ comment: 492.5572509765625,
18
+ comment_date: 209.22393798828125,
19
+ },
20
+ },
21
+ }),
22
+ layout_query: JSON.stringify({
23
+ tabular: {
24
+ page: 1,
25
+ fields: ["status", "comment_date", "author", "comment"],
26
+ },
27
+ }),
28
+ refresh_interval: null,
29
+ role: null,
30
+ search: null,
31
+ },
32
+ ];
33
+
34
+ export async function up(knex) {
35
+ await knex("directus_presets").insert(PRESETS);
36
+ }
37
+
38
+ export async function down(knex) {
39
+ await knex("directus_presets")
40
+ .where({
41
+ user: null,
42
+ role: null,
43
+ bookmark: null,
44
+ collection: COLLECTION_NAME,
45
+ })
46
+ .del();
47
+ }
@@ -0,0 +1,33 @@
1
+ export async function up(knex) {
2
+ await knex("tngl_testimonial").insert([
3
+ {
4
+ sort: 1,
5
+ status: "published",
6
+ date_created: knex.fn.now(3),
7
+ date_updated: knex.fn.now(3),
8
+ author: "John Smith",
9
+ comment: "We had a great experience from beginning to end. Communication was clear, deadlines were met, and the attention to detail really stood out. It’s rare to find a team that combines professionalism with such a genuine commitment to delivering great results. We would gladly work with them again.",
10
+ comment_date: knex.fn.now(3),
11
+ },
12
+ {
13
+ sort: 2,
14
+ status: "published",
15
+ date_created: knex.fn.now(3),
16
+ date_updated: knex.fn.now(3),
17
+ author: "Jane Smith",
18
+ comment: "Working with this team was a fantastic experience. They were professional, responsive, and truly understood what we needed. The final result exceeded our expectations, and the entire process was smooth from start to finish. I would absolutely recommend their services to anyone looking for quality work and reliable support.",
19
+ comment_date: knex.fn.now(3),
20
+ },
21
+ ]);
22
+ }
23
+
24
+ export async function down(knex) {
25
+ await knex("directus_presets")
26
+ .where({
27
+ user: null,
28
+ role: null,
29
+ bookmark: null,
30
+ collection: COLLECTION_NAME,
31
+ })
32
+ .del();
33
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@tanglemedia/directus-collection-testimonial",
3
+ "description": "Installs the Testimonial Collection to your Directus project.",
4
+ "author": {
5
+ "name": "Tangle Media, Inc."
6
+ },
7
+ "license": "MIT",
8
+ "icon": "extension",
9
+ "version": "0.0.1",
10
+ "keywords": [
11
+ "directus",
12
+ "directus-extension",
13
+ "directus-extension-hook",
14
+ "testimonial-collection",
15
+ "directus-collection",
16
+ "collection"
17
+ ],
18
+ "files": [
19
+ "dist",
20
+ "src",
21
+ "migrations",
22
+ "scripts",
23
+ "docs"
24
+ ],
25
+ "directus:extension": {
26
+ "type": "hook",
27
+ "path": "dist/index.js",
28
+ "source": "src/index.js",
29
+ "host": "^10.10.1 || ^11.0.0",
30
+ "sandbox": {
31
+ "enabled": false,
32
+ "requestedScopes": {
33
+ "log": {}
34
+ }
35
+ }
36
+ },
37
+ "devDependencies": {
38
+ "@directus/extensions-sdk": "13.0.0",
39
+ "@types/node": "^22.13.0",
40
+ "typescript": "^5.7.3"
41
+ },
42
+ "scripts": {
43
+ "build": "directus-extension build",
44
+ "dev": "directus-extension build -w --no-minify",
45
+ "link": "directus-extension link"
46
+ }
47
+ }
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ const { defineHook } = require("@directus/extensions-sdk");
2
+ const moveMigrationScripts = require("./shared/utility/migrations");
3
+
4
+ module.exports = defineHook(
5
+ async ({ action, init }, { services, database, getSchema, logger }) => {
6
+ await moveMigrationScripts(logger);
7
+ },
8
+ );
@@ -0,0 +1,30 @@
1
+ const { exec } = require("child_process");
2
+ const { promisify } = require("util");
3
+ const path = require("node:path");
4
+ const execPromise = promisify(exec);
5
+
6
+ const moveMigrationScripts = async (logger) => {
7
+ const ROOT = process.cwd();
8
+ const EXTENSION_PATH = __dirname;
9
+
10
+ let migrationSrcPath = EXTENSION_PATH.split("/");
11
+ migrationSrcPath.pop();
12
+ migrationSrcPath.push("migrations");
13
+ migrationSrcPath = path.join("/", ...migrationSrcPath);
14
+
15
+ let migrationDestPath = ROOT.split("/");
16
+ migrationDestPath.push("migrations");
17
+ migrationDestPath = path.join("/", ...migrationDestPath);
18
+
19
+ // create destination folder
20
+ let { stdout, stderr } = await execPromise(`mkdir -p ${migrationDestPath}`);
21
+ if (stderr) return;
22
+
23
+ // copy files
24
+ ({ stdout, stderr } = await execPromise(
25
+ `cp -r ${migrationSrcPath}/* ${migrationDestPath}`,
26
+ ));
27
+ if (stderr) return;
28
+ };
29
+
30
+ module.exports = moveMigrationScripts;