From 2074654c18e8c0135c91a67f82841ab67b1c2d6a Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 29 Mar 2026 15:37:05 +0700 Subject: [PATCH] 690329:1537 Fixing bugs uuid by Kimi K2.5 #06 --- ...tagentity_0add73f310116e4ae1b17ce66d2e7b7a | 65 +++++++++++++++++++ ...ntity_0add73f310116e4ae1b17ce66d2e7b7a.map | 1 + ...cac696b99-da39a3ee5e6b4b0d3255bfef95601890 | 2 +- .../src/modules/master/entities/tag.entity.ts | 14 ++-- .../admin/doc-control/reference/tags/page.tsx | 62 +++++++++++++----- 5 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a.map diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a new file mode 100644 index 0000000..cef7d9d --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a @@ -0,0 +1,65 @@ +14540db954a05918780678361189125c +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var _a, _b, _c, _d; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Tag = void 0; +const typeorm_1 = require("typeorm"); +const project_entity_1 = require("../../project/entities/project.entity"); +let Tag = class Tag { +}; +exports.Tag = Tag; +__decorate([ + (0, typeorm_1.PrimaryGeneratedColumn)(), + __metadata("design:type", Number) +], Tag.prototype, "id", void 0); +__decorate([ + (0, typeorm_1.Column)({ name: 'project_id', type: 'int', nullable: true }), + __metadata("design:type", Object) +], Tag.prototype, "projectId", void 0); +__decorate([ + (0, typeorm_1.Column)({ name: 'tag_name', length: 100 }), + __metadata("design:type", String) +], Tag.prototype, "tagName", void 0); +__decorate([ + (0, typeorm_1.Column)({ name: 'color_code', length: 30, default: 'default' }), + __metadata("design:type", String) +], Tag.prototype, "colorCode", void 0); +__decorate([ + (0, typeorm_1.Column)({ type: 'text', nullable: true }), + __metadata("design:type", Object) +], Tag.prototype, "description", void 0); +__decorate([ + (0, typeorm_1.ManyToOne)(() => project_entity_1.Project), + (0, typeorm_1.JoinColumn)({ name: 'project_id' }), + __metadata("design:type", typeof (_a = typeof project_entity_1.Project !== "undefined" && project_entity_1.Project) === "function" ? _a : Object) +], Tag.prototype, "project", void 0); +__decorate([ + (0, typeorm_1.CreateDateColumn)({ name: 'created_at' }), + __metadata("design:type", typeof (_b = typeof Date !== "undefined" && Date) === "function" ? _b : Object) +], Tag.prototype, "createdAt", void 0); +__decorate([ + (0, typeorm_1.UpdateDateColumn)({ name: 'updated_at' }), + __metadata("design:type", typeof (_c = typeof Date !== "undefined" && Date) === "function" ? _c : Object) +], Tag.prototype, "updatedAt", void 0); +__decorate([ + (0, typeorm_1.Column)({ name: 'created_by', type: 'int', nullable: true }), + __metadata("design:type", Object) +], Tag.prototype, "createdBy", void 0); +__decorate([ + (0, typeorm_1.DeleteDateColumn)({ name: 'deleted_at' }), + __metadata("design:type", Object) +], Tag.prototype, "deletedAt", void 0); +exports.Tag = Tag = __decorate([ + (0, typeorm_1.Entity)('tags'), + (0, typeorm_1.Unique)('ux_tag_project', ['projectId', 'tagName']) +], Tag); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJmaWxlIjoiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcbWFzdGVyXFxlbnRpdGllc1xcdGFnLmVudGl0eS50cyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUEscUNBVWlCO0FBQ2pCLDBFQUFnRTtBQUl6RCxJQUFNLEdBQUcsR0FBVCxNQUFNLEdBQUc7Q0FnQ2YsQ0FBQTtBQWhDWSxrQkFBRztBQUVkO0lBREMsSUFBQSxnQ0FBc0IsR0FBRTs7K0JBQ2I7QUFHWjtJQURDLElBQUEsZ0JBQU0sRUFBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7O3NDQUNsQztBQUcxQjtJQURDLElBQUEsZ0JBQU0sRUFBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDOztvQ0FDekI7QUFHakI7SUFEQyxJQUFBLGdCQUFNLEVBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDOztzQ0FDNUM7QUFHbkI7SUFEQyxJQUFBLGdCQUFNLEVBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQzs7d0NBQ2I7QUFLNUI7SUFGQyxJQUFBLG1CQUFTLEVBQUMsR0FBRyxFQUFFLENBQUMsd0JBQU8sQ0FBQztJQUN4QixJQUFBLG9CQUFVLEVBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUM7a0RBQ3pCLHdCQUFPLG9CQUFQLHdCQUFPO29DQUFDO0FBR2xCO0lBREMsSUFBQSwwQkFBZ0IsRUFBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztrREFDN0IsSUFBSSxvQkFBSixJQUFJO3NDQUFDO0FBR2pCO0lBREMsSUFBQSwwQkFBZ0IsRUFBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztrREFDN0IsSUFBSSxvQkFBSixJQUFJO3NDQUFDO0FBR2pCO0lBREMsSUFBQSxnQkFBTSxFQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQzs7c0NBQ2xDO0FBRzFCO0lBREMsSUFBQSwwQkFBZ0IsRUFBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQzs7c0NBQ2pCO2NBL0JiLEdBQUc7SUFGZixJQUFBLGdCQUFNLEVBQUMsTUFBTSxDQUFDO0lBQ2QsSUFBQSxnQkFBTSxFQUFDLGdCQUFnQixFQUFFLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0dBQ3RDLEdBQUcsQ0FnQ2YiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcbWFzdGVyXFxlbnRpdGllc1xcdGFnLmVudGl0eS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEVudGl0eSxcclxuICBDb2x1bW4sXHJcbiAgUHJpbWFyeUdlbmVyYXRlZENvbHVtbixcclxuICBDcmVhdGVEYXRlQ29sdW1uLFxyXG4gIFVwZGF0ZURhdGVDb2x1bW4sXHJcbiAgRGVsZXRlRGF0ZUNvbHVtbixcclxuICBVbmlxdWUsXHJcbiAgTWFueVRvT25lLFxyXG4gIEpvaW5Db2x1bW4sXHJcbn0gZnJvbSAndHlwZW9ybSc7XHJcbmltcG9ydCB7IFByb2plY3QgfSBmcm9tICcuLi8uLi9wcm9qZWN0L2VudGl0aWVzL3Byb2plY3QuZW50aXR5JztcclxuXHJcbkBFbnRpdHkoJ3RhZ3MnKVxyXG5AVW5pcXVlKCd1eF90YWdfcHJvamVjdCcsIFsncHJvamVjdElkJywgJ3RhZ05hbWUnXSlcclxuZXhwb3J0IGNsYXNzIFRhZyB7XHJcbiAgQFByaW1hcnlHZW5lcmF0ZWRDb2x1bW4oKVxyXG4gIGlkITogbnVtYmVyOyAvLyDguYDguJ7guLTguYjguKEgIVxyXG5cclxuICBAQ29sdW1uKHsgbmFtZTogJ3Byb2plY3RfaWQnLCB0eXBlOiAnaW50JywgbnVsbGFibGU6IHRydWUgfSlcclxuICBwcm9qZWN0SWQhOiBudW1iZXIgfCBudWxsOyAvLyDguYDguJ7guLTguYjguKEgIVxyXG5cclxuICBAQ29sdW1uKHsgbmFtZTogJ3RhZ19uYW1lJywgbGVuZ3RoOiAxMDAgfSlcclxuICB0YWdOYW1lITogc3RyaW5nOyAvLyDguYDguJ7guLTguYjguKEgIVxyXG5cclxuICBAQ29sdW1uKHsgbmFtZTogJ2NvbG9yX2NvZGUnLCBsZW5ndGg6IDMwLCBkZWZhdWx0OiAnZGVmYXVsdCcgfSlcclxuICBjb2xvckNvZGUhOiBzdHJpbmc7IC8vIOC5gOC4nuC4tOC5iOC4oSAhXHJcblxyXG4gIEBDb2x1bW4oeyB0eXBlOiAndGV4dCcsIG51bGxhYmxlOiB0cnVlIH0pXHJcbiAgZGVzY3JpcHRpb24hOiBzdHJpbmcgfCBudWxsOyAvLyDguYDguJ7guLTguYjguKEgIVxyXG5cclxuICAvLyBSZWxhdGlvbnNcclxuICBATWFueVRvT25lKCgpID0+IFByb2plY3QpXHJcbiAgQEpvaW5Db2x1bW4oeyBuYW1lOiAncHJvamVjdF9pZCcgfSlcclxuICBwcm9qZWN0PzogUHJvamVjdDtcclxuXHJcbiAgQENyZWF0ZURhdGVDb2x1bW4oeyBuYW1lOiAnY3JlYXRlZF9hdCcgfSlcclxuICBjcmVhdGVkQXQhOiBEYXRlOyAvLyDguYDguJ7guLTguYjguKEgIVxyXG5cclxuICBAVXBkYXRlRGF0ZUNvbHVtbih7IG5hbWU6ICd1cGRhdGVkX2F0JyB9KVxyXG4gIHVwZGF0ZWRBdCE6IERhdGU7IC8vIOC5gOC4nuC4tOC5iOC4oSAhXHJcblxyXG4gIEBDb2x1bW4oeyBuYW1lOiAnY3JlYXRlZF9ieScsIHR5cGU6ICdpbnQnLCBudWxsYWJsZTogdHJ1ZSB9KVxyXG4gIGNyZWF0ZWRCeSE6IG51bWJlciB8IG51bGw7IC8vIOC5gOC4nuC4tOC5iOC4oSAhXHJcblxyXG4gIEBEZWxldGVEYXRlQ29sdW1uKHsgbmFtZTogJ2RlbGV0ZWRfYXQnIH0pXHJcbiAgZGVsZXRlZEF0ITogRGF0ZSB8IG51bGw7IC8vIOC5gOC4nuC4tOC5iOC4oSAhXHJcbn1cclxuIl0sInZlcnNpb24iOjN9 \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a.map b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a.map new file mode 100644 index 0000000..401c012 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/0a/tagentity_0add73f310116e4ae1b17ce66d2e7b7a.map @@ -0,0 +1 @@ +{"file":"E:\\np-dms\\lcbp3\\backend\\src\\modules\\master\\entities\\tag.entity.ts","mappings":";;;;;;;;;;;;;AAAA,qCAUiB;AACjB,0EAAgE;AAIzD,IAAM,GAAG,GAAT,MAAM,GAAG;CAgCf,CAAA;AAhCY,kBAAG;AAEd;IADC,IAAA,gCAAsB,GAAE;;+BACb;AAGZ;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;sCAClC;AAG1B;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;oCACzB;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;;sCAC5C;AAGnB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wCACb;AAK5B;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,wBAAO,CAAC;IACxB,IAAA,oBAAU,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;kDACzB,wBAAO,oBAAP,wBAAO;oCAAC;AAGlB;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;kDAC7B,IAAI,oBAAJ,IAAI;sCAAC;AAGjB;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;kDAC7B,IAAI,oBAAJ,IAAI;sCAAC;AAGjB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;sCAClC;AAG1B;IADC,IAAA,0BAAgB,EAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;;sCACjB;cA/Bb,GAAG;IAFf,IAAA,gBAAM,EAAC,MAAM,CAAC;IACd,IAAA,gBAAM,EAAC,gBAAgB,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;GACtC,GAAG,CAgCf","names":[],"sources":["E:\\np-dms\\lcbp3\\backend\\src\\modules\\master\\entities\\tag.entity.ts"],"sourcesContent":["import {\r\n Entity,\r\n Column,\r\n PrimaryGeneratedColumn,\r\n CreateDateColumn,\r\n UpdateDateColumn,\r\n DeleteDateColumn,\r\n Unique,\r\n ManyToOne,\r\n JoinColumn,\r\n} from 'typeorm';\r\nimport { Project } from '../../project/entities/project.entity';\r\n\r\n@Entity('tags')\r\n@Unique('ux_tag_project', ['projectId', 'tagName'])\r\nexport class Tag {\r\n @PrimaryGeneratedColumn()\r\n id!: number; // เพิ่ม !\r\n\r\n @Column({ name: 'project_id', type: 'int', nullable: true })\r\n projectId!: number | null; // เพิ่ม !\r\n\r\n @Column({ name: 'tag_name', length: 100 })\r\n tagName!: string; // เพิ่ม !\r\n\r\n @Column({ name: 'color_code', length: 30, default: 'default' })\r\n colorCode!: string; // เพิ่ม !\r\n\r\n @Column({ type: 'text', nullable: true })\r\n description!: string | null; // เพิ่ม !\r\n\r\n // Relations\r\n @ManyToOne(() => Project)\r\n @JoinColumn({ name: 'project_id' })\r\n project?: Project;\r\n\r\n @CreateDateColumn({ name: 'created_at' })\r\n createdAt!: Date; // เพิ่ม !\r\n\r\n @UpdateDateColumn({ name: 'updated_at' })\r\n updatedAt!: Date; // เพิ่ม !\r\n\r\n @Column({ name: 'created_by', type: 'int', nullable: true })\r\n createdBy!: number | null; // เพิ่ม !\r\n\r\n @DeleteDateColumn({ name: 'deleted_at' })\r\n deletedAt!: Date | null; // เพิ่ม !\r\n}\r\n"],"version":3} \ No newline at end of file diff --git a/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 b/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 index ee48fe2..ce07ee0 100644 --- a/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 +++ b/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 @@ -1 +1 @@ -{"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\due-date-reminder.service.spec.ts":[1,1723],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts":[1,7645],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.service.spec.ts":[1,1538],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\document-numbering.service.spec.ts":[1,2037],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\casl\\ability.factory.spec.ts":[1,1294],"E:\\np-dms\\lcbp3\\backend\\src\\common\\services\\uuid-resolver.service.spec.ts":[1,5491],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\workflow-engine.service.spec.ts":[1,5639],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\dsl\\parser.service.spec.ts":[1,5818],"E:\\np-dms\\lcbp3\\backend\\src\\common\\pipes\\parse-uuid.pipe.spec.ts":[1,355],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\user\\user.service.spec.ts":[1,1270],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.service.spec.ts":[1,1187],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.controller.spec.ts":[1,8852],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.service.spec.ts":[1,1296],"E:\\np-dms\\lcbp3\\backend\\src\\common\\entities\\uuid-base.entity.spec.ts":[1,430],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.service.spec.ts":[1,1109],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.controller.spec.ts":[1,2191],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\services\\manual-override.service.spec.ts":[1,5256],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.controller.spec.ts":[1,1827],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.controller.spec.ts":[1,6380],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.controller.spec.ts":[1,1482],"E:\\np-dms\\lcbp3\\backend\\src\\app.controller.spec.ts":[1,587],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\json-schema\\json-schema.controller.spec.ts":[1,5062]} \ No newline at end of file +{"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\due-date-reminder.service.spec.ts":[1,1723],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts":[1,11114],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.service.spec.ts":[1,1538],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\document-numbering.service.spec.ts":[1,2037],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\casl\\ability.factory.spec.ts":[1,1294],"E:\\np-dms\\lcbp3\\backend\\src\\common\\services\\uuid-resolver.service.spec.ts":[1,5491],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\workflow-engine.service.spec.ts":[1,5639],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\dsl\\parser.service.spec.ts":[1,5818],"E:\\np-dms\\lcbp3\\backend\\src\\common\\pipes\\parse-uuid.pipe.spec.ts":[1,355],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\user\\user.service.spec.ts":[1,1270],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.service.spec.ts":[1,1187],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.controller.spec.ts":[1,12100],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.service.spec.ts":[1,1296],"E:\\np-dms\\lcbp3\\backend\\src\\common\\entities\\uuid-base.entity.spec.ts":[1,430],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.service.spec.ts":[1,1109],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.controller.spec.ts":[1,2191],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\services\\manual-override.service.spec.ts":[1,5256],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.controller.spec.ts":[1,1827],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.controller.spec.ts":[1,6380],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.controller.spec.ts":[1,1482],"E:\\np-dms\\lcbp3\\backend\\src\\app.controller.spec.ts":[1,587],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\json-schema\\json-schema.controller.spec.ts":[1,5062]} \ No newline at end of file diff --git a/backend/src/modules/master/entities/tag.entity.ts b/backend/src/modules/master/entities/tag.entity.ts index 4741527..ea510c7 100644 --- a/backend/src/modules/master/entities/tag.entity.ts +++ b/backend/src/modules/master/entities/tag.entity.ts @@ -17,13 +17,13 @@ export class Tag { @PrimaryGeneratedColumn() id!: number; // เพิ่ม ! - @Column({ type: 'int', nullable: true }) + @Column({ name: 'project_id', type: 'int', nullable: true }) projectId!: number | null; // เพิ่ม ! - @Column({ length: 100 }) + @Column({ name: 'tag_name', length: 100 }) tagName!: string; // เพิ่ม ! - @Column({ length: 30, default: 'default' }) + @Column({ name: 'color_code', length: 30, default: 'default' }) colorCode!: string; // เพิ่ม ! @Column({ type: 'text', nullable: true }) @@ -34,15 +34,15 @@ export class Tag { @JoinColumn({ name: 'project_id' }) project?: Project; - @CreateDateColumn() + @CreateDateColumn({ name: 'created_at' }) createdAt!: Date; // เพิ่ม ! - @UpdateDateColumn() + @UpdateDateColumn({ name: 'updated_at' }) updatedAt!: Date; // เพิ่ม ! - @Column({ type: 'int', nullable: true }) + @Column({ name: 'created_by', type: 'int', nullable: true }) createdBy!: number | null; // เพิ่ม ! - @DeleteDateColumn() + @DeleteDateColumn({ name: 'deleted_at' }) deletedAt!: Date | null; // เพิ่ม ! } diff --git a/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx b/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx index 3d4f34c..e2cfc24 100644 --- a/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx +++ b/frontend/app/(admin)/admin/doc-control/reference/tags/page.tsx @@ -1,5 +1,6 @@ 'use client'; +import { useState } from 'react'; import { GenericCrudTable } from '@/components/admin/reference/generic-crud-table'; import { masterDataService } from '@/lib/services/master-data.service'; import { projectService } from '@/lib/services/project.service'; @@ -7,30 +8,37 @@ import { CreateTagDto } from '@/types/dto/master/tag.dto'; import { ColumnDef } from '@tanstack/react-table'; import { useQuery } from '@tanstack/react-query'; import { Tag } from '@/types/master-data'; +import { Label } from '@/components/ui/label'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; export default function TagsPage() { + const [selectedProjectId, setSelectedProjectId] = useState('all'); + const { data: projectsData } = useQuery({ queryKey: ['projects'], queryFn: () => projectService.getAll(), }); - const projectOptions = [ - { label: 'Global (All Projects)', value: '__none__' }, - ...(projectsData || []).map((p: { id?: number; publicId?: string; projectName?: string; projectCode?: string }) => ({ - label: (p.projectName || p.projectCode || `Project ${p.publicId || p.id}`) as string, - value: String(p.publicId ?? p.id ?? ''), // ADR-019: publicId is the UUID exposed in API - })), - ]; + const projectItems = (projectsData || []) + .map((p: { publicId?: string; projectName?: string; projectCode?: string }) => ({ + label: (p.projectName || p.projectCode || p.publicId || 'Unknown Project') as string, + value: String(p.publicId || ''), + })) + .filter((option: { label: string; value: string }) => option.value !== ''); + + const projectScopeOptions = [{ label: 'Global (All Projects)', value: '__none__' }, ...projectItems]; const columns: ColumnDef[] = [ { accessorKey: 'projectId', header: 'Project', cell: ({ row }) => { - const item = row.original as Tag & { project?: { id?: number | string; publicId?: string; projectName?: string; projectCode?: string } }; + const item = row.original as Tag & { + project?: { publicId?: string; projectName?: string; projectCode?: string }; + }; const project = item.project; if (!project) return Global; - return (project.projectName || project.projectCode || `Project ${project.publicId || project.id}`) as React.ReactNode; + return (project.projectName || project.projectCode || project.publicId || 'Unknown Project') as React.ReactNode; }, }, { @@ -70,15 +78,21 @@ export default function TagsPage() { title="Tags" description="Manage system tags, multi-tenant capable." entityName="Tag" - queryKey={['tags']} + queryKey={['tags', selectedProjectId]} fetchFn={async () => { - const items = await masterDataService.getTags(); - // ADR-019: Map projectId INT → project UUID for edit mode select matching + const items = await masterDataService.getTags( + selectedProjectId !== 'all' ? { projectId: selectedProjectId } : undefined + ); + return items.map((item) => { - const rec = item as Tag & { project?: { id?: number | string; publicId?: string }; projectId?: number | string }; + const rec = item as Tag & { + project?: { publicId?: string }; + projectId?: number | string | null; + }; + return { ...item, - projectId: rec.project?.publicId || rec.project?.id || (rec.projectId ? String(rec.projectId) : null), + projectId: rec.project?.publicId || (typeof rec.projectId === 'string' ? rec.projectId : null), } as Tag; }); }} @@ -88,12 +102,30 @@ export default function TagsPage() { updateFn={(id, data) => masterDataService.updateTag(id, formatPayload(data))} deleteFn={(id) => masterDataService.deleteTag(id)} columns={columns} + filters={ +
+ + +
+ } fields={[ { name: 'projectId', label: 'Project Scope', type: 'select', - options: projectOptions, + options: projectScopeOptions, required: false, }, {