New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

kanbancast-components

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kanbancast-components - npm Package Compare versions

Comparing version

to
1.0.19

15

dist/board-view.d.ts

@@ -22,4 +22,13 @@ import { LitElement } from 'lit';

projectId: number;
newTaskTitle: string;
newTaskDescription: string;
apiKey: string;
selectedTab: string;
showModal: boolean;
theme: string;
static styles: import('lit').CSSResult;
toggleTheme(): void;
connectedCallback(): void;
applyTheme(): void;
fetchStatuses(): Promise<void>;
get tasksForSelectedTab(): {

@@ -34,3 +43,9 @@ status: Status;

}[];
handleTitleChange(e: Event): void;
handleDescriptionChange(e: Event): void;
submitNewTask(): Promise<void>;
render(): import('lit-html').TemplateResult<1>;
updated(changedProperties: {
has: (arg0: string) => any;
}): void;
upvoteTask(task: Task): Promise<void>;

@@ -37,0 +52,0 @@ }

705

dist/board-view.es.js

@@ -1,2 +0,2 @@

import { css as k, LitElement as U, html as $ } from "lit";
import { css as P, LitElement as T, html as m } from "lit";
/**

@@ -7,6 +7,6 @@ * @license

*/
const T = (o) => (t, e) => {
const C = (i) => (t, e) => {
e !== void 0 ? e.addInitializer(() => {
customElements.define(o, t);
}) : customElements.define(o, t);
customElements.define(i, t);
}) : customElements.define(i, t);
};

@@ -18,6 +18,6 @@ /**

*/
const p = globalThis, m = p.ShadowRoot && (p.ShadyCSS === void 0 || p.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, P = Symbol(), _ = /* @__PURE__ */ new WeakMap();
let x = class {
const f = globalThis, v = f.ShadowRoot && (f.ShadyCSS === void 0 || f.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, _ = Symbol(), S = /* @__PURE__ */ new WeakMap();
let U = class {
constructor(t, e, s) {
if (this._$cssResult$ = !0, s !== P)
if (this._$cssResult$ = !0, s !== _)
throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");

@@ -29,5 +29,5 @@ this.cssText = t, this.t = e;

const e = this.t;
if (m && t === void 0) {
if (v && t === void 0) {
const s = e !== void 0 && e.length === 1;
s && (t = _.get(e)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), s && _.set(e, t));
s && (t = S.get(e)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), s && S.set(e, t));
}

@@ -40,16 +40,16 @@ return t;

};
const O = (o) => new x(typeof o == "string" ? o : o + "", void 0, P), A = (o, t) => {
if (m)
o.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet);
const A = (i) => new U(typeof i == "string" ? i : i + "", void 0, _), O = (i, t) => {
if (v)
i.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet);
else
for (const e of t) {
const s = document.createElement("style"), i = p.litNonce;
i !== void 0 && s.setAttribute("nonce", i), s.textContent = e.cssText, o.appendChild(s);
const s = document.createElement("style"), o = f.litNonce;
o !== void 0 && s.setAttribute("nonce", o), s.textContent = e.cssText, i.appendChild(s);
}
}, S = m ? (o) => o : (o) => o instanceof CSSStyleSheet ? ((t) => {
}, k = v ? (i) => i : (i) => i instanceof CSSStyleSheet ? ((t) => {
let e = "";
for (const s of t.cssRules)
e += s.cssText;
return O(e);
})(o) : o;
return A(e);
})(i) : i;
/**

@@ -60,20 +60,20 @@ * @license

*/
const { is: C, defineProperty: j, getOwnPropertyDescriptor: R, getOwnPropertyNames: D, getOwnPropertySymbols: M, getPrototypeOf: z } = Object, c = globalThis, E = c.trustedTypes, I = E ? E.emptyScript : "", b = c.reactiveElementPolyfillSupport, h = (o, t) => o, u = { toAttribute(o, t) {
const { is: j, defineProperty: D, getOwnPropertyDescriptor: M, getOwnPropertyNames: z, getOwnPropertySymbols: R, getPrototypeOf: I } = Object, h = globalThis, x = h.trustedTypes, L = x ? x.emptyScript : "", y = h.reactiveElementPolyfillSupport, u = (i, t) => i, g = { toAttribute(i, t) {
switch (t) {
case Boolean:
o = o ? I : null;
i = i ? L : null;
break;
case Object:
case Array:
o = o == null ? o : JSON.stringify(o);
i = i == null ? i : JSON.stringify(i);
}
return o;
}, fromAttribute(o, t) {
let e = o;
return i;
}, fromAttribute(i, t) {
let e = i;
switch (t) {
case Boolean:
e = o !== null;
e = i !== null;
break;
case Number:
e = o === null ? null : Number(o);
e = i === null ? null : Number(i);
break;

@@ -83,3 +83,3 @@ case Object:

try {
e = JSON.parse(o);
e = JSON.parse(i);
} catch {

@@ -90,5 +90,5 @@ e = null;

return e;
} }, g = (o, t) => !C(o, t), w = { attribute: !0, type: String, converter: u, reflect: !1, hasChanged: g };
Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), c.litPropertyMetadata ?? (c.litPropertyMetadata = /* @__PURE__ */ new WeakMap());
class d extends HTMLElement {
} }, w = (i, t) => !j(i, t), E = { attribute: !0, type: String, converter: g, reflect: !1, hasChanged: w };
Symbol.metadata ?? (Symbol.metadata = Symbol("metadata")), h.litPropertyMetadata ?? (h.litPropertyMetadata = /* @__PURE__ */ new WeakMap());
class p extends HTMLElement {
static addInitializer(t) {

@@ -100,10 +100,10 @@ this._$Ei(), (this.l ?? (this.l = [])).push(t);

}
static createProperty(t, e = w) {
static createProperty(t, e = E) {
if (e.state && (e.attribute = !1), this._$Ei(), this.elementProperties.set(t, e), !e.noAccessor) {
const s = Symbol(), i = this.getPropertyDescriptor(t, s, e);
i !== void 0 && j(this.prototype, t, i);
const s = Symbol(), o = this.getPropertyDescriptor(t, s, e);
o !== void 0 && D(this.prototype, t, o);
}
}
static getPropertyDescriptor(t, e, s) {
const { get: i, set: n } = R(this.prototype, t) ?? { get() {
const { get: o, set: n } = M(this.prototype, t) ?? { get() {
return this[e];

@@ -114,24 +114,24 @@ }, set(r) {

return { get() {
return i == null ? void 0 : i.call(this);
return o == null ? void 0 : o.call(this);
}, set(r) {
const a = i == null ? void 0 : i.call(this);
n.call(this, r), this.requestUpdate(t, a, s);
const c = o == null ? void 0 : o.call(this);
n.call(this, r), this.requestUpdate(t, c, s);
}, configurable: !0, enumerable: !0 };
}
static getPropertyOptions(t) {
return this.elementProperties.get(t) ?? w;
return this.elementProperties.get(t) ?? E;
}
static _$Ei() {
if (this.hasOwnProperty(h("elementProperties")))
if (this.hasOwnProperty(u("elementProperties")))
return;
const t = z(this);
const t = I(this);
t.finalize(), t.l !== void 0 && (this.l = [...t.l]), this.elementProperties = new Map(t.elementProperties);
}
static finalize() {
if (this.hasOwnProperty(h("finalized")))
if (this.hasOwnProperty(u("finalized")))
return;
if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(h("properties"))) {
const e = this.properties, s = [...D(e), ...M(e)];
for (const i of s)
this.createProperty(i, e[i]);
if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(u("properties"))) {
const e = this.properties, s = [...z(e), ...R(e)];
for (const o of s)
this.createProperty(o, e[o]);
}

@@ -142,9 +142,9 @@ const t = this[Symbol.metadata];

if (e !== void 0)
for (const [s, i] of e)
this.elementProperties.set(s, i);
for (const [s, o] of e)
this.elementProperties.set(s, o);
}
this._$Eh = /* @__PURE__ */ new Map();
for (const [e, s] of this.elementProperties) {
const i = this._$Eu(e, s);
i !== void 0 && this._$Eh.set(i, e);
const o = this._$Eu(e, s);
o !== void 0 && this._$Eh.set(o, e);
}

@@ -157,6 +157,6 @@ this.elementStyles = this.finalizeStyles(this.styles);

const s = new Set(t.flat(1 / 0).reverse());
for (const i of s)
e.unshift(S(i));
for (const o of s)
e.unshift(k(o));
} else
t !== void 0 && e.push(S(t));
t !== void 0 && e.push(k(t));
return e;

@@ -191,3 +191,3 @@ }

const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
return A(t, this.constructor.elementStyles), t;
return O(t, this.constructor.elementStyles), t;
}

@@ -215,6 +215,6 @@ connectedCallback() {

var n;
const s = this.constructor.elementProperties.get(t), i = this.constructor._$Eu(t, s);
if (i !== void 0 && s.reflect === !0) {
const r = (((n = s.converter) == null ? void 0 : n.toAttribute) !== void 0 ? s.converter : u).toAttribute(e, s.type);
this._$Em = t, r == null ? this.removeAttribute(i) : this.setAttribute(i, r), this._$Em = null;
const s = this.constructor.elementProperties.get(t), o = this.constructor._$Eu(t, s);
if (o !== void 0 && s.reflect === !0) {
const r = (((n = s.converter) == null ? void 0 : n.toAttribute) !== void 0 ? s.converter : g).toAttribute(e, s.type);
this._$Em = t, r == null ? this.removeAttribute(o) : this.setAttribute(o, r), this._$Em = null;
}

@@ -224,6 +224,6 @@ }

var n;
const s = this.constructor, i = s._$Eh.get(t);
if (i !== void 0 && this._$Em !== i) {
const r = s.getPropertyOptions(i), a = typeof r.converter == "function" ? { fromAttribute: r.converter } : ((n = r.converter) == null ? void 0 : n.fromAttribute) !== void 0 ? r.converter : u;
this._$Em = i, this[i] = a.fromAttribute(e, r.type), this._$Em = null;
const s = this.constructor, o = s._$Eh.get(t);
if (o !== void 0 && this._$Em !== o) {
const r = s.getPropertyOptions(o), c = typeof r.converter == "function" ? { fromAttribute: r.converter } : ((n = r.converter) == null ? void 0 : n.fromAttribute) !== void 0 ? r.converter : g;
this._$Em = o, this[o] = c.fromAttribute(e, r.type), this._$Em = null;
}

@@ -233,3 +233,3 @@ }

if (t !== void 0) {
if (s ?? (s = this.constructor.getPropertyOptions(t)), !(s.hasChanged ?? g)(this[t], e))
if (s ?? (s = this.constructor.getPropertyOptions(t)), !(s.hasChanged ?? w)(this[t], e))
return;

@@ -266,5 +266,5 @@ this.P(t, e, s);

}
const i = this.constructor.elementProperties;
if (i.size > 0)
for (const [n, r] of i)
const o = this.constructor.elementProperties;
if (o.size > 0)
for (const [n, r] of o)
r.wrapped !== !0 || this._$AL.has(n) || this[n] === void 0 || this.P(n, this[n], r);

@@ -275,8 +275,8 @@ }

try {
t = this.shouldUpdate(e), t ? (this.willUpdate(e), (s = this._$EO) == null || s.forEach((i) => {
t = this.shouldUpdate(e), t ? (this.willUpdate(e), (s = this._$EO) == null || s.forEach((o) => {
var n;
return (n = i.hostUpdate) == null ? void 0 : n.call(i);
return (n = o.hostUpdate) == null ? void 0 : n.call(o);
}), this.update(e)) : this._$EU();
} catch (i) {
throw t = !1, this._$EU(), i;
} catch (o) {
throw t = !1, this._$EU(), o;
}

@@ -290,4 +290,4 @@ t && this._$AE(e);

(e = this._$EO) == null || e.forEach((s) => {
var i;
return (i = s.hostUpdated) == null ? void 0 : i.call(s);
var o;
return (o = s.hostUpdated) == null ? void 0 : o.call(s);
}), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);

@@ -315,3 +315,3 @@ }

}
d.elementStyles = [], d.shadowRootOptions = { mode: "open" }, d[h("elementProperties")] = /* @__PURE__ */ new Map(), d[h("finalized")] = /* @__PURE__ */ new Map(), b == null || b({ ReactiveElement: d }), (c.reactiveElementVersions ?? (c.reactiveElementVersions = [])).push("2.0.4");
p.elementStyles = [], p.shadowRootOptions = { mode: "open" }, p[u("elementProperties")] = /* @__PURE__ */ new Map(), p[u("finalized")] = /* @__PURE__ */ new Map(), y == null || y({ ReactiveElement: p }), (h.reactiveElementVersions ?? (h.reactiveElementVersions = [])).push("2.0.4");
/**

@@ -322,12 +322,12 @@ * @license

*/
const L = { attribute: !0, type: String, converter: u, reflect: !1, hasChanged: g }, N = (o = L, t, e) => {
const { kind: s, metadata: i } = e;
let n = globalThis.litPropertyMetadata.get(i);
if (n === void 0 && globalThis.litPropertyMetadata.set(i, n = /* @__PURE__ */ new Map()), n.set(e.name, o), s === "accessor") {
const N = { attribute: !0, type: String, converter: g, reflect: !1, hasChanged: w }, F = (i = N, t, e) => {
const { kind: s, metadata: o } = e;
let n = globalThis.litPropertyMetadata.get(o);
if (n === void 0 && globalThis.litPropertyMetadata.set(o, n = /* @__PURE__ */ new Map()), n.set(e.name, i), s === "accessor") {
const { name: r } = e;
return { set(a) {
const y = t.get.call(this);
t.set.call(this, a), this.requestUpdate(r, y, o);
}, init(a) {
return a !== void 0 && this.P(r, void 0, o), a;
return { set(c) {
const b = t.get.call(this);
t.set.call(this, c), this.requestUpdate(r, b, i);
}, init(c) {
return c !== void 0 && this.P(r, void 0, i), c;
} };

@@ -337,5 +337,5 @@ }

const { name: r } = e;
return function(a) {
const y = this[r];
t.call(this, a), this.requestUpdate(r, y, o);
return function(c) {
const b = this[r];
t.call(this, c), this.requestUpdate(r, b, i);
};

@@ -345,127 +345,164 @@ }

};
function v(o) {
return (t, e) => typeof e == "object" ? N(o, t, e) : ((s, i, n) => {
const r = i.hasOwnProperty(n);
return i.constructor.createProperty(n, r ? { ...s, wrapped: !0 } : s), r ? Object.getOwnPropertyDescriptor(i, n) : void 0;
})(o, t, e);
function d(i) {
return (t, e) => typeof e == "object" ? F(i, t, e) : ((s, o, n) => {
const r = o.hasOwnProperty(n);
return o.constructor.createProperty(n, r ? { ...s, wrapped: !0 } : s), r ? Object.getOwnPropertyDescriptor(o, n) : void 0;
})(i, t, e);
}
var q = Object.defineProperty, B = Object.getOwnPropertyDescriptor, f = (o, t, e, s) => {
for (var i = s > 1 ? void 0 : s ? B(t, e) : t, n = o.length - 1, r; n >= 0; n--)
(r = o[n]) && (i = (s ? r(t, e, i) : r(i)) || i);
return s && i && q(t, e, i), i;
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
function $(i) {
return d({ ...i, state: !0, attribute: !1 });
}
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
function q(i, t, e) {
return i ? t(i) : e == null ? void 0 : e(i);
}
var K = Object.defineProperty, B = Object.getOwnPropertyDescriptor, l = (i, t, e, s) => {
for (var o = s > 1 ? void 0 : s ? B(t, e) : t, n = i.length - 1, r; n >= 0; n--)
(r = i[n]) && (o = (s ? r(t, e, o) : r(o)) || o);
return s && o && K(t, e, o), o;
};
let l = class extends U {
let a = class extends T {
constructor() {
super(...arguments), this.statuses = [
{
id: 1,
title: "Pending",
slug: "pending",
order: 3,
tasks: []
},
{
id: 2,
title: "To Do",
slug: "to-do",
order: 1,
tasks: [
{
id: 1,
title: "Task 1",
description: "Description of Task 1",
order: 1,
votes: 1,
status_id: 1
},
{
id: 2,
title: "Task 2",
description: "Description of Task 2",
order: 2,
votes: 1,
status_id: 1
/* Your existing statuses */
], this.projectId = 2, this.newTaskTitle = "", this.newTaskDescription = "", this.apiKey = "y01Z2px2j71o", this.selectedTab = "Active", this.showModal = !1, this.theme = "light";
}
toggleTheme() {
this.theme = this.theme === "light" ? "dark" : "light", this.requestUpdate();
}
connectedCallback() {
this.fetchStatuses(), super.connectedCallback();
}
applyTheme() {
var i;
(i = this.shadowRoot) == null || i.host.classList.toggle("dark-theme", this.theme === "dark");
}
async fetchStatuses() {
try {
const i = await fetch(
`https://kanbancast.com/public/projects/${this.projectId}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
"x-api-key": `${this.apiKey}`
}
]
},
{
id: 3,
title: "In Progress",
slug: "in-progress",
order: 2,
tasks: [
{
id: 3,
title: "Task 3",
description: "Description of Task 3",
order: 1,
votes: 1,
status_id: 2
}
]
},
{
id: 4,
title: "Review",
slug: "review",
order: 3,
tasks: []
},
{
id: 5,
title: "Done",
slug: "done",
order: 4,
tasks: []
},
{
id: 6,
title: "Published",
slug: "published",
order: 4,
tasks: []
}
], this.projectId = 0, this.selectedTab = "Active";
}
);
if (i.ok) {
const t = await i.json();
console.log(t), this.statuses = t.statuses, console.log("Statuses fetched successfully");
} else
console.error("Failed to fetch statuses");
} catch (i) {
console.error("Error fetching statuses:", i);
}
}
get tasksForSelectedTab() {
const o = ["To Do", "In Progress", "Pending", "Review"], t = ["Done", "Published"], e = this.selectedTab === "Active" ? o : t;
return (this.statuses || []).filter((s) => e.includes(s.title)).flatMap((s) => s.tasks.map((i) => ({ ...i, status: s })));
const i = ["To Do", "In Progress", "Pending", "Review"], t = ["Done", "Published"], e = this.selectedTab === "Active" ? i : t;
return (this.statuses || []).filter((s) => e.includes(s.title)).flatMap((s) => s.tasks.map((o) => ({ ...o, status: s })));
}
handleTitleChange(i) {
this.newTaskTitle = i.target.value;
}
handleDescriptionChange(i) {
this.newTaskDescription = i.target.value;
}
async submitNewTask() {
const i = {
title: this.newTaskTitle,
description: this.newTaskDescription,
status_id: 1
// Assuming new tasks go to "Pending" status
};
try {
const t = await fetch(`https://kanbancast.com/api/projects/${this.projectId}/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.apiKey}`
},
body: JSON.stringify(i)
});
if (t.ok) {
const e = await t.json(), s = this.statuses.find((o) => o.slug === "pending");
s == null || s.tasks.push(e), this.showModal = !1;
} else
console.error("Failed to submit new task");
} catch (t) {
console.error("Error submitting new task:", t);
}
}
render() {
return $`
<div class="container">
<div class="header">
<div class="tabs">
<button
@click=${() => this.selectedTab = "Active"}
class="tab ${this.selectedTab === "Active" ? "active-tab" : ""}"
>
Active
</button>
<button
@click=${() => this.selectedTab = "Done"}
class="tab ${this.selectedTab === "Done" ? "active-tab" : ""}"
>
Done
</button>
</div>
</div>
return m`
<div class="container">
<div class="header">
<div class="tabs">
<button
@click=${() => this.selectedTab = "Active"}
class="tab ${this.selectedTab === "Active" ? "active-tab" : ""}"
>
Active
</button>
<button
@click=${() => this.selectedTab = "Done"}
class="tab ${this.selectedTab === "Done" ? "active-tab" : ""}"
>
Done
</button>
<div class="tasks-list">
${this.tasksForSelectedTab.map((o) => $`
<li class="task-item">
<button @click=${() => this.upvoteTask(o)} class="upvote-button">
<span class="votes-count">${o.votes ?? 1}</span>
</button>
<div class="task-details">
<p class="task-title">${o.title}</p>
<p class="task-description">${o.description}</p>
</div>
</li>
`)}
</div>
</div>
`;
</div>
<button @click=${() => this.showModal = !0} class="suggest-feature-button">Suggest a Feature
</button>
</div>
<div class="tasks-list">
${this.tasksForSelectedTab.map((i) => m`
<li class="task-item">
<button @click=${() => this.upvoteTask(i)} class="upvote-button">
<span class="votes-count">${i.votes ?? 1}</span>
</button>
<div class="task-details">
<p class="task-title">${i.title}</p>
<p class="task-description">${i.description}</p>
</div>
</li>
`)}
</div>
${q(this.showModal, () => m`
<div>
<div class="dialog">
<div class="overlay" @click="${() => this.showModal = !1}">
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="m4.12 6.137 1.521-1.52 7 7-1.52 1.52z"/>
<path d="m4.12 11.61 7.001-7 1.52 1.52-7 7z"/>
</svg>
</div>
<h1>Suggest a New Feature</h1>
<input type="text" .value="${this.newTaskTitle}" @input="${this.handleTitleChange}"
placeholder="Enter task title">
<input type="text" .value="${this.newTaskDescription}"
@input="${this.handleDescriptionChange}" placeholder="Enter task description">
<button @click="${this.submitNewTask}">Submit</button>
</div>
</div>`)}
</div>
`;
}
async upvoteTask(o) {
updated(i) {
i.has("theme") && this.applyTheme();
}
async upvoteTask(i) {
try {

@@ -475,7 +512,7 @@ const t = await fetch("/api/tasks/upvote", {

headers: { "Content-Type": "application/json" },
body: JSON.stringify({ taskId: o.id, projectId: this.projectId })
body: JSON.stringify({ taskId: i.id, projectId: this.projectId })
});
if (t.ok) {
const e = await t.json();
o.votes = e.votes, console.log("Vote incremented successfully");
i.votes = e.votes, console.log("Vote incremented successfully");
} else

@@ -488,87 +525,189 @@ console.error("Failed to increment votes");

};
l.styles = k`
.container {
background-color: #5a67d8;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
}
.header {
display: flex;
justify-content: space-between;
margin-left: 16px;
}
.tabs {
display: flex;
justify-content: start;
}
.tab {
padding: 8px 16px;
margin-right: 8px;
border-radius: 8px;
border: none;
background: transparent;
cursor: pointer;
}
.active-tab {
background-color: white;
}
.tasks-list {
list-style-type: none;
}
.task-item {
display: flex;
align-items: center;
background-color: white;
border-radius: 8px;
padding: 16px;
margin-top:16px;
gap:8px;
margin-bottom: 16px;
}
.upvote-button {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
border: 2px solid #cbd5e0;
background-color: white;
border-radius: 8px;
}
.votes-count {
font-size: small;
}
.task-details {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
}
.task-title {
font-size: large;
font-weight: 600;
padding-bottom: 0;
margin-bottom: 0;
}
.task-description {
margin-top:0;
padding-top: 0;
font-size: small;
}
`;
f([
v({ type: Array })
], l.prototype, "statuses", 2);
f([
v({ type: Number })
], l.prototype, "projectId", 2);
f([
v({ type: String })
], l.prototype, "selectedTab", 2);
l = f([
T("board-view")
], l);
a.styles = P`
/* Your existing styles */
:root {
--background-color: #ffffff; /* Light theme background */
--text-color: #333333; /* Light theme text */
--button-background: #4CAF50;
--button-text: white;
}
.dark-theme {
--background-color: #333333; /* Dark theme background */
--text-color: #ffffff; /* Dark theme text */
--button-background: #888888;
--button-text: black;
}
.dialog {
background: #ffffff;
border-radius: 13px;
max-width: 400px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center; /* Center align items horizontally */
text-align: center; /* Center align text */
}
.dialog h1 {
margin-bottom: 20px;
}
.dialog input {
width: 90%;
padding: 8px;
margin-bottom: 10px;
margin-top: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.dialog button {
width: 100%;
padding: 10px;
margin-top: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.container {
background-color: #5a67d8;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
}
.header {
display: flex;
justify-content: space-between;
margin-left: 16px;
}
.tabs {
display: flex;
justify-content: start;
}
.tab {
padding: 8px 16px;
margin-right: 8px;
border-radius: 8px;
border: none;
background: transparent;
cursor: pointer;
}
.active-tab {
background-color: white;
}
.tasks-list {
list-style-type: none;
}
.task-item {
display: flex;
align-items: center;
background-color: white;
border-radius: 8px;
padding: 16px;
margin-top:16px;
gap:8px;
margin-bottom: 16px;
}
.upvote-button {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
border: 2px solid #cbd5e0;
background-color: white;
border-radius: 8px;
}
.votes-count {
font-size: small;
}
.task-details {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
}
.task-title {
font-size: large;
font-weight: 600;
padding-bottom: 0;
margin-bottom: 0;
}
.task-description {
margin-top:0;
padding-top: 0;
font-size: small;
}
.suggest-feature-button {
background-color: rgb(17 24 39);
color: white;
border: none;
padding: 10px 20px;
border-radius: 20px; /* Rounded corners for a modern look */
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
transition: background-color 0.3s;
}
.suggest-feature-button:hover {
background-color: rgb(3 7 18);
}
.overlay {
position: absolute;
top: 20px; /* Increase margin from the top */
right: 20px; /* Increase margin from the right */
cursor: pointer;
width: 24px; /* Increase size */
height: 24px; /* Increase size */
}
svg {
fill: currentColor; /* To easily control the color via CSS */
width: 100%; /* Fit to container */
height: 100%; /* Fit to container */
}
`;
l([
d({ type: Array })
], a.prototype, "statuses", 2);
l([
d({ type: Number })
], a.prototype, "projectId", 2);
l([
d({ type: String })
], a.prototype, "newTaskTitle", 2);
l([
d({ type: String })
], a.prototype, "newTaskDescription", 2);
l([
d({ type: String })
], a.prototype, "apiKey", 2);
l([
$()
], a.prototype, "selectedTab", 2);
l([
$()
], a.prototype, "showModal", 2);
l([
$()
], a.prototype, "theme", 2);
a = l([
C("board-view")
], a);
export {
l as BoardView
a as BoardView
};
{
"name": "kanbancast-components",
"private": false,
"version": "1.0.18",
"version": "1.0.19",
"type": "module",

@@ -6,0 +6,0 @@ "types": "dist/board-view.d.ts",

// src/BoardView.ts
import { LitElement, html, css } from 'lit';
import { property, customElement } from 'lit/decorators.js';
import { property, customElement, state } from 'lit/decorators.js';
// import {classMap} from 'lit/directives/class-map.js';
import { when } from 'lit/directives/when.js';

@@ -26,146 +28,211 @@

export class BoardView extends LitElement {
@property({ type: Array }) statuses: Status[] = [
{
id: 1,
title: "Pending",
slug: "pending",
order: 3,
tasks: [],
},
{
id: 2,
title: "To Do",
slug: "to-do",
order: 1,
tasks: [
{
id: 1,
title: "Task 1",
description: "Description of Task 1",
order: 1,
votes: 1,
status_id: 1,
},
{
id: 2,
title: "Task 2",
description: "Description of Task 2",
order: 2,
votes: 1,
status_id: 1,
},
],
},
{
id: 3,
title: "In Progress",
slug: "in-progress",
order: 2,
tasks: [
{
id: 3,
title: "Task 3",
description: "Description of Task 3",
order: 1,
votes: 1,
status_id: 2,
},
],
},
{
id: 4,
title: "Review",
slug: "review",
order: 3,
tasks: [],
},
{
id: 5,
title: "Done",
slug: "done",
order: 4,
tasks: [],
},
{
id: 6,
title: "Published",
slug: "published",
order: 4,
tasks: [],
},
];
@property({ type: Number }) projectId: number = 0;
@property({ type: String }) selectedTab: string = 'Active';
@property({ type: Array }) statuses: Status[] = [/* Your existing statuses */];
@property({ type: Number }) projectId: number = 2;
@property({ type: String }) newTaskTitle: string = '';
@property({ type: String }) newTaskDescription: string = '';
@property({type: String}) apiKey:string='y01Z2px2j71o';
@state() selectedTab: string = 'Active';
@state() showModal:boolean = false;
@state() theme: string = 'light'; // D
static styles = css`
.container {
background-color: #5a67d8;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
/* Your existing styles */
:root {
--background-color: #ffffff; /* Light theme background */
--text-color: #333333; /* Light theme text */
--button-background: #4CAF50;
--button-text: white;
}
.dark-theme {
--background-color: #333333; /* Dark theme background */
--text-color: #ffffff; /* Dark theme text */
--button-background: #888888;
--button-text: black;
}
.dialog {
background: #ffffff;
border-radius: 13px;
max-width: 400px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center; /* Center align items horizontally */
text-align: center; /* Center align text */
}
.dialog h1 {
margin-bottom: 20px;
}
.dialog input {
width: 90%;
padding: 8px;
margin-bottom: 10px;
margin-top: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.dialog button {
width: 100%;
padding: 10px;
margin-top: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.container {
background-color: #5a67d8;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
}
.header {
display: flex;
justify-content: space-between;
margin-left: 16px;
}
.tabs {
display: flex;
justify-content: start;
}
.tab {
padding: 8px 16px;
margin-right: 8px;
border-radius: 8px;
border: none;
background: transparent;
cursor: pointer;
}
.active-tab {
background-color: white;
}
.tasks-list {
list-style-type: none;
}
.task-item {
display: flex;
align-items: center;
background-color: white;
border-radius: 8px;
padding: 16px;
margin-top:16px;
gap:8px;
margin-bottom: 16px;
}
.upvote-button {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
border: 2px solid #cbd5e0;
background-color: white;
border-radius: 8px;
}
.votes-count {
font-size: small;
}
.task-details {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
}
.task-title {
font-size: large;
font-weight: 600;
padding-bottom: 0;
margin-bottom: 0;
}
.task-description {
margin-top:0;
padding-top: 0;
font-size: small;
}
.suggest-feature-button {
background-color: rgb(17 24 39);
color: white;
border: none;
padding: 10px 20px;
border-radius: 20px; /* Rounded corners for a modern look */
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
transition: background-color 0.3s;
}
.suggest-feature-button:hover {
background-color: rgb(3 7 18);
}
.overlay {
position: absolute;
top: 20px; /* Increase margin from the top */
right: 20px; /* Increase margin from the right */
cursor: pointer;
width: 24px; /* Increase size */
height: 24px; /* Increase size */
}
svg {
fill: currentColor; /* To easily control the color via CSS */
width: 100%; /* Fit to container */
height: 100%; /* Fit to container */
}
`;
toggleTheme() {
this.theme = this.theme === 'light' ? 'dark' : 'light';
this.requestUpdate();
}
.header {
display: flex;
justify-content: space-between;
margin-left: 16px;
connectedCallback()
{
this.fetchStatuses();
super.connectedCallback();
}
.tabs {
display: flex;
justify-content: start;
applyTheme() {
this.shadowRoot?.host.classList.toggle('dark-theme', this.theme === 'dark');
}
.tab {
padding: 8px 16px;
margin-right: 8px;
border-radius: 8px;
border: none;
background: transparent;
cursor: pointer;
async fetchStatuses() {
try {
const response = await fetch(`https://kanbancast.com/public/projects/${this.projectId}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'x-api-key': `${this.apiKey}`
}
});
if (response.ok) {
const data = await response.json();
console.log(data)
this.statuses = data.statuses;
console.log('Statuses fetched successfully');
} else {
console.error('Failed to fetch statuses');
}
} catch (error) {
console.error('Error fetching statuses:', error);
}
}
.active-tab {
background-color: white;
}
.tasks-list {
list-style-type: none;
}
.task-item {
display: flex;
align-items: center;
background-color: white;
border-radius: 8px;
padding: 16px;
margin-top:16px;
gap:8px;
margin-bottom: 16px;
}
.upvote-button {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
border: 2px solid #cbd5e0;
background-color: white;
border-radius: 8px;
}
.votes-count {
font-size: small;
}
.task-details {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
}
.task-title {
font-size: large;
font-weight: 600;
padding-bottom: 0;
margin-bottom: 0;
}
.task-description {
margin-top:0;
padding-top: 0;
font-size: small;
}
`;
get tasksForSelectedTab() {

@@ -181,39 +248,106 @@ const activeStatuses = ['To Do', 'In Progress', 'Pending', 'Review'];

handleTitleChange(e: Event) {
this.newTaskTitle = (e.target as HTMLInputElement).value;
}
handleDescriptionChange(e: Event) {
this.newTaskDescription = (e.target as HTMLInputElement).value;
}
async submitNewTask() {
const newTask = {
title: this.newTaskTitle,
description: this.newTaskDescription,
status_id: 1 // Assuming new tasks go to "Pending" status
};
try {
const response = await fetch(`https://kanbancast.com/api/projects/${this.projectId}/tasks`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify(newTask)
});
if (response.ok) {
const data = await response.json();
const pendingStatus = this.statuses.find(status => status.slug === 'pending');
pendingStatus?.tasks.push(data);
this.showModal=false;
} else {
console.error('Failed to submit new task');
}
} catch (error) {
console.error('Error submitting new task:', error);
}
}
render() {
return html`
<div class="container">
<div class="header">
<div class="tabs">
<button
@click=${() => this.selectedTab = 'Active'}
class="tab ${this.selectedTab === 'Active' ? 'active-tab' : ''}"
>
Active
</button>
<button
@click=${() => this.selectedTab = 'Done'}
class="tab ${this.selectedTab === 'Done' ? 'active-tab' : ''}"
>
Done
</button>
</div>
</div>
<div class="container">
<div class="header">
<div class="tabs">
<button
@click=${() => this.selectedTab = 'Active'}
class="tab ${this.selectedTab === 'Active' ? 'active-tab' : ''}"
>
Active
</button>
<button
@click=${() => this.selectedTab = 'Done'}
class="tab ${this.selectedTab === 'Done' ? 'active-tab' : ''}"
>
Done
</button>
<div class="tasks-list">
${this.tasksForSelectedTab.map(task => html`
<li class="task-item">
<button @click=${() => this.upvoteTask(task)} class="upvote-button">
<span class="votes-count">${task.votes ?? 1}</span>
</button>
<div class="task-details">
<p class="task-title">${task.title}</p>
<p class="task-description">${task.description}</p>
</div>
</li>
`)}
</div>
</div>
`;
</div>
<button @click=${() => this.showModal = true} class="suggest-feature-button">Suggest a Feature
</button>
</div>
<div class="tasks-list">
${this.tasksForSelectedTab.map(task => html`
<li class="task-item">
<button @click=${() => this.upvoteTask(task)} class="upvote-button">
<span class="votes-count">${task.votes ?? 1}</span>
</button>
<div class="task-details">
<p class="task-title">${task.title}</p>
<p class="task-description">${task.description}</p>
</div>
</li>
`)}
</div>
${when(this.showModal, () => html`
<div>
<div class="dialog">
<div class="overlay" @click="${() => this.showModal = false}">
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="m4.12 6.137 1.521-1.52 7 7-1.52 1.52z"/>
<path d="m4.12 11.61 7.001-7 1.52 1.52-7 7z"/>
</svg>
</div>
<h1>Suggest a New Feature</h1>
<input type="text" .value="${this.newTaskTitle}" @input="${this.handleTitleChange}"
placeholder="Enter task title">
<input type="text" .value="${this.newTaskDescription}"
@input="${this.handleDescriptionChange}" placeholder="Enter task description">
<button @click="${this.submitNewTask}">Submit</button>
</div>
</div>`)}
</div>
`;
}
updated(changedProperties: { has: (arg0: string) => any; }) {
if (changedProperties.has('theme')) {
this.applyTheme();
}
}
async upvoteTask(task: Task) {

@@ -239,6 +373,7 @@ try {

}
declare global {
interface HTMLElementTagNameMap {
'board-view': BoardView
'board-view': BoardView;
}
}
}

@@ -1,7 +0,15 @@

// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path';
import { resolve }from 'path';
import dts from 'vite-plugin-dts'
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://kanbancast.com',
changeOrigin: true, // Needed for virtual hosted sites
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {

@@ -24,2 +32,2 @@ lib: {

plugins: [dts()]
});
});

Sorry, the diff of this file is not supported yet