mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 14:21:46 +00:00
feat: collab sub-feature toggles and provider icons
- Add admin toggles for individual collab sections (Chat, Notes, Polls, What's Next) stored in app_settings - CollabPanel adapts layout dynamically: chat always fixed 380px, remaining panels share space equally - Mobile: disabled tabs are hidden - Add Immich and Synology Photos SVG icons to photo provider toggles - Add Luggage icon to bag tracking sub-toggle - API: GET/PUT /admin/collab-features endpoints - i18n: all 15 languages updated Closes #604
This commit is contained in:
@@ -45,6 +45,7 @@ import publicConfigRoutes from './routes/publicConfig';
|
||||
import { mcpHandler } from './mcp';
|
||||
import { Addon } from './types';
|
||||
import { getPhotoProviderConfig } from './services/memories/helpersService';
|
||||
import { getCollabFeatures } from './services/adminService';
|
||||
|
||||
export function createApp(): express.Application {
|
||||
const app = express();
|
||||
@@ -236,6 +237,7 @@ export function createApp(): express.Application {
|
||||
}
|
||||
|
||||
res.json({
|
||||
collabFeatures: getCollabFeatures(),
|
||||
addons: [
|
||||
...addons.map(a => ({ ...a, enabled: !!a.enabled })),
|
||||
...providers.map(p => ({
|
||||
|
||||
@@ -200,6 +200,24 @@ router.put('/bag-tracking', (req: Request, res: Response) => {
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
// ── Collab Features ───────────────────────────────────────────────────────
|
||||
|
||||
router.get('/collab-features', (_req: Request, res: Response) => {
|
||||
res.json(svc.getCollabFeatures());
|
||||
});
|
||||
|
||||
router.put('/collab-features', (req: Request, res: Response) => {
|
||||
const result = svc.updateCollabFeatures(req.body);
|
||||
const authReq = req as AuthRequest;
|
||||
writeAudit({
|
||||
userId: authReq.user.id,
|
||||
action: 'admin.collab_features',
|
||||
ip: getClientIp(req),
|
||||
details: result,
|
||||
});
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
// ── Packing Templates ──────────────────────────────────────────────────────
|
||||
|
||||
router.get('/packing-templates', (_req: Request, res: Response) => {
|
||||
|
||||
@@ -459,6 +459,31 @@ export function updateBagTracking(enabled: boolean) {
|
||||
return { enabled: !!enabled };
|
||||
}
|
||||
|
||||
// ── Collab Features ───────────────────────────────────────────────────────
|
||||
|
||||
const COLLAB_FEATURE_KEYS = ['collab_chat_enabled', 'collab_notes_enabled', 'collab_polls_enabled', 'collab_whatsnext_enabled'] as const;
|
||||
|
||||
export function getCollabFeatures() {
|
||||
const rows = db.prepare("SELECT key, value FROM app_settings WHERE key IN ('collab_chat_enabled', 'collab_notes_enabled', 'collab_polls_enabled', 'collab_whatsnext_enabled')").all() as { key: string; value: string }[];
|
||||
const map: Record<string, string> = {};
|
||||
for (const r of rows) map[r.key] = r.value;
|
||||
return {
|
||||
chat: map['collab_chat_enabled'] !== 'false',
|
||||
notes: map['collab_notes_enabled'] !== 'false',
|
||||
polls: map['collab_polls_enabled'] !== 'false',
|
||||
whatsnext: map['collab_whatsnext_enabled'] !== 'false',
|
||||
};
|
||||
}
|
||||
|
||||
export function updateCollabFeatures(features: { chat?: boolean; notes?: boolean; polls?: boolean; whatsnext?: boolean }) {
|
||||
const mapping: Record<string, string> = { chat: 'collab_chat_enabled', notes: 'collab_notes_enabled', polls: 'collab_polls_enabled', whatsnext: 'collab_whatsnext_enabled' };
|
||||
const stmt = db.prepare("INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)");
|
||||
for (const [feat, key] of Object.entries(mapping)) {
|
||||
if (features[feat] !== undefined) stmt.run(key, features[feat] ? 'true' : 'false');
|
||||
}
|
||||
return getCollabFeatures();
|
||||
}
|
||||
|
||||
// ── Packing Templates ──────────────────────────────────────────────────────
|
||||
|
||||
export function listPackingTemplates() {
|
||||
|
||||
Reference in New Issue
Block a user