aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/calendarBox/CalendarBox.scss9
-rw-r--r--src/client/views/nodes/calendarBox/CalendarBox.tsx77
-rw-r--r--src/server/apis/google/GoogleTasksHandler.ts54
3 files changed, 131 insertions, 9 deletions
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.scss b/src/client/views/nodes/calendarBox/CalendarBox.scss
index 891db9d90..89dc294a5 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.scss
+++ b/src/client/views/nodes/calendarBox/CalendarBox.scss
@@ -50,3 +50,12 @@
pointer-events: unset;
}
}
+
+.custom-drag-mirror {
+ transition: none !important;
+ transform: none !important;
+}
+
+.fc-event-dragging {
+ opacity: 0 !important;
+}
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 92b3224e9..a4183a11a 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -298,15 +298,74 @@ export class CalendarBox extends CollectionSubView() {
ev.preventDefault();
});
}}
+
+ // for dragging and dropping (mirror)
+
+ eventDragStart={(arg) => {
+ const mirror = arg.el.cloneNode(true) as HTMLElement;
+ const rect = arg.el.getBoundingClientRect();
+
+ mirror.style.position = 'fixed';
+ mirror.style.pointerEvents = 'none';
+ mirror.style.opacity = '0.8';
+ mirror.style.zIndex = '10000';
+ mirror.classList.add('custom-drag-mirror');
+ mirror.style.width = `${rect.width}px`;
+ mirror.style.height = `${rect.height}px`;
+
+ document.body.appendChild(mirror);
+
+ const moveListener = (ev: MouseEvent) => {
+ mirror.style.left = `${ev.clientX}px`;
+ mirror.style.top = `${ev.clientY}px`;
+ };
+
+ window.addEventListener('mousemove', moveListener);
+
+ // hide the actual box
+ arg.el.style.visibility = 'hidden';
+ arg.el.style.opacity = '0';
+
+ (arg.el as any)._mirrorElement = mirror;
+ (arg.el as any)._moveListener = moveListener;
+ }}
+
+ eventDragStop={(arg) => {
+ const el = arg.el as any;
+ const mirror = el._mirrorElement;
+ const moveListener = el._moveListener;
+
+ // show the actual box
+ el.style.visibility = 'visible';
+ el.style.opacity = '1';
+
+ if (mirror) document.body.removeChild(mirror);
+ if (moveListener) window.removeEventListener('mousemove', moveListener);
+ }}
+
/>
);
}
render() {
+ const scale = this._props.ScreenToLocalTransform().Scale;
+ const scaledWidth = this._props.PanelWidth();
+ const scaledHeight = this._props.PanelHeight();
+
return (
<div
key={this.calendarViewType}
className={`calendarBox${this._props.isContentActive() ? '-interactive' : ''}`}
+ style={{
+ width: scaledWidth,
+ height: scaledHeight,
+ overflow: 'hidden',
+ position: 'relative',
+ }}
+ ref={r => {
+ this.createDashEventsTarget(r);
+ this.fixWheelEvents(r, this._props.isContentActive);
+ }}
onPointerDown={e => {
setTimeout(
action(() => {
@@ -317,17 +376,17 @@ export class CalendarBox extends CollectionSubView() {
if (cname.includes('timeGridDay')) this.dataDoc[this.calTypeFieldKey] = 'timeGridDay';
})
);
- }}
- style={{
- width: this._props.PanelWidth() / this._props.ScreenToLocalTransform().Scale,
- height: this._props.PanelHeight() / this._props.ScreenToLocalTransform().Scale,
- transform: `scale(${this._props.ScreenToLocalTransform().Scale})`,
- }}
- ref={r => {
- this.createDashEventsTarget(r);
- this.fixWheelEvents(r, this._props.isContentActive);
}}>
+ <div
+ style={{
+ transform: `scale(${scale})`,
+ transformOrigin: 'top left',
+ width: scaledWidth / scale,
+ height: scaledHeight / scale,
+ }}
+ >
{this.renderCalendar}
+ </div>
</div>
);
}
diff --git a/src/server/apis/google/GoogleTasksHandler.ts b/src/server/apis/google/GoogleTasksHandler.ts
new file mode 100644
index 000000000..a8af86fe2
--- /dev/null
+++ b/src/server/apis/google/GoogleTasksHandler.ts
@@ -0,0 +1,54 @@
+import express from 'express';
+import { google } from 'googleapis';
+import { GoogleCredentialsLoader } from './CredentialsLoader';
+import User from '../../authentication/DashUserModel';
+import { DashUserModel } from '../../authentication/DashUserModel';
+
+
+const router = express.Router();
+
+router.post('/tasks/create', async (req, res) => {
+ try {
+ const { title, notes, due } = req.body;
+
+ // Make sure user is authenticated
+ if (!req.user) {
+ return res.status(401).json({ error: 'User not authenticated' });
+ }
+
+ // Assuming access token is stored in user model
+ const user = req.user as typeof User; // replace with your actual User type if needed
+ const accessToken = user.googleAccessToken; // <-- change this based on where you store it
+
+ if (!accessToken) {
+ return res.status(400).json({ error: 'Google access token not found for user' });
+ }
+
+ const credentials = GoogleCredentialsLoader.ProjectCredentials;
+ const auth = new google.auth.OAuth2(
+ credentials.client_id,
+ credentials.client_secret,
+ credentials.redirect_uris[0]
+ );
+
+ auth.setCredentials({ access_token: accessToken });
+
+ const tasks = google.tasks({ version: 'v1', auth });
+
+ const result = await tasks.tasks.insert({
+ tasklist: '@default',
+ requestBody: {
+ title,
+ notes,
+ due,
+ },
+ });
+
+ res.status(200).json(result.data);
+ } catch (err) {
+ console.error('Error creating Google Task:', err);
+ res.status(500).json({ error: 'Failed to create task' });
+ }
+});
+
+export default router;