This commit is contained in:
parent
0dd928b8f4
commit
d5af04c317
@ -243,7 +243,7 @@
|
||||
@apply
|
||||
z-80
|
||||
w-full
|
||||
min-h-[100px]
|
||||
min-h-fit
|
||||
max-h-72
|
||||
p-1.5
|
||||
space-y-0.5
|
||||
|
@ -177,17 +177,23 @@ const columnDefs: ConfigColumnDefs[] = [
|
||||
},
|
||||
{
|
||||
target: 5,
|
||||
data: "message_style",
|
||||
orderable: false, // both should be true, but message_style doesnt exist yet
|
||||
data: null, // "message_style_id"
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
className: "size-px whitespace-nowrap",
|
||||
render: (data: string) => { return `
|
||||
<div class="px-6 py-4">
|
||||
<span class="cj-table-text">
|
||||
${data}
|
||||
</span>
|
||||
</div>
|
||||
`}
|
||||
render: (_data: unknown, type: string, row: any) => {
|
||||
if (!row.message_style || type !== "display") return null;
|
||||
|
||||
const wrapper = $("<div>").addClass("flex px-6 py-4");
|
||||
const badge = $("<span>").addClass("inline-flex items-center whitespace-nowrap border rounded-md bg-white dark:bg-neutral-800 border-gray-200 dark:border-neutral-700 overflow-hidden");
|
||||
const colour = $("<span>").addClass("size-6 shrink-0").css("background-color", row.message_style.colour);
|
||||
const label = $("<span>").addClass("py-1 px-2.5 text-xs text-gray-800 dark:text-neutral-200");
|
||||
label.text(row.message_style.name);
|
||||
|
||||
badge.append(colour).append(label);
|
||||
wrapper.append(badge);
|
||||
return wrapper.get(0);
|
||||
}
|
||||
},
|
||||
{
|
||||
target: 6,
|
||||
@ -381,6 +387,7 @@ const clearEditModalData = () => {
|
||||
$("#formActive").prop("checked", true);
|
||||
channelSelect.setValue([]);
|
||||
filterSelect.setValue([]);
|
||||
styleSelect.setValue("");
|
||||
};
|
||||
|
||||
const loadEditModalData = async (id: number) => {
|
||||
@ -397,6 +404,7 @@ const loadEditModalData = async (id: number) => {
|
||||
|
||||
channelSelect.setValue(feed.channels.map(channel => channel.channel_id));
|
||||
filterSelect.setValue(feed.filters.map(filter => `${filter.id}`));
|
||||
styleSelect.setValue(`${feed.message_style_id}`);
|
||||
}
|
||||
|
||||
const openEditModal = async (id: number | undefined) => {
|
||||
@ -525,6 +533,45 @@ const filterSelect = new HSSelect(
|
||||
filterSelectOptions
|
||||
);
|
||||
|
||||
const styleSelectOptions: ISelectOptions = {
|
||||
placeholder: "Select option...",
|
||||
|
||||
toggleTag: '<button type="button" aria-expanded="false"><span data-title></span></button>',
|
||||
optionTemplate: `
|
||||
<div class="flex justify-between items-center w-full">
|
||||
<span data-title></span>
|
||||
<span class="hidden hs-selected:block">
|
||||
<svg class="shrink-0 size-3.5 text-blue-600 dark:text-blue-500" xmlns="http:.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
</span>
|
||||
</div>`,
|
||||
toggleClasses: "cj-select-toggle select-input",
|
||||
optionClasses: "cj-select-option",
|
||||
dropdownClasses: "cj-select-dropdown",
|
||||
wrapperClasses: "peer",
|
||||
dropdownSpace: 10,
|
||||
dropdownScope: "parent",
|
||||
dropdownPlacement: "top",
|
||||
dropdownVerticalFixedPlacement: null,
|
||||
|
||||
apiUrl: `/guild/${guildId}/styles/api/select`,
|
||||
// apiQuery: "limit=15",
|
||||
apiFieldsMap: {
|
||||
id: "id",
|
||||
val: "id",
|
||||
title: "name",
|
||||
description: "value",
|
||||
name: "title"
|
||||
},
|
||||
apiSearchQueryKey: "search",
|
||||
hasSearch: false,
|
||||
optionAllowEmptyOption: true
|
||||
};
|
||||
|
||||
const styleSelect = new HSSelect(
|
||||
$("#formMessageStyle").get(0),
|
||||
styleSelectOptions
|
||||
);
|
||||
|
||||
$("#editForm").on("submit", async event => {
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
<span class="sr-only">Checkbox</span>
|
||||
</label>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="name" class="cj-table-header">
|
||||
<th scope="col" class="cj-table-header">
|
||||
<div class="cj-table-header-content cursor-pointer">
|
||||
<span>Name</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@ -59,7 +59,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="url" class="cj-table-header">
|
||||
<th scope="col" class="cj-table-header">
|
||||
<div class="cj-table-header-content cursor-pointer">
|
||||
<span>URL</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@ -67,25 +67,22 @@
|
||||
</svg>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="channels" class="cj-table-header --exclude-from-ordering">
|
||||
<th scope="col" class="cj-table-header --exclude-from-ordering">
|
||||
<div class="cj-table-header-content">
|
||||
<span>Channels</span>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="filters" class="cj-table-header --exclude-from-ordering">
|
||||
<th scope="col" class="cj-table-header --exclude-from-ordering">
|
||||
<div class="cj-table-header-content">
|
||||
<span>Filters</span>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="style" class="cj-table-header">
|
||||
<th scope="col" class="cj-table-header --exclude-from-ordering">
|
||||
<div class="cj-table-header-content cursor-pointer">
|
||||
<span>Style</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m7 15 5 5 5-5"></path><path d="m7 9 5-5 5 5"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="created_at" class="cj-table-header">
|
||||
<th scope="col" class="cj-table-header">
|
||||
<div class="cj-table-header-content cursor-pointer">
|
||||
<span>Created at</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@ -93,7 +90,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
</th>
|
||||
<th scope="col" data-dt-column="active" class="cj-table-header">
|
||||
<th scope="col" class="cj-table-header">
|
||||
<div class="cj-table-header-content cursor-pointer">
|
||||
<span>Status</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@ -210,8 +207,18 @@
|
||||
Filter out unwanted content from this feed.
|
||||
</p>
|
||||
</div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div class="relative">
|
||||
<label for="formMessageStyle" class="text-input-label">Message Style</label>
|
||||
<select name="message_style" id="formMessageStyle" class="--prevent-on-load-init">
|
||||
<option value="">None</option>
|
||||
</select>
|
||||
<p class="text-input-help">
|
||||
placeholder.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
placeholder for publish threshold
|
||||
</div>
|
||||
<div>
|
||||
<label for="formActive" class="flex gap-4">
|
||||
<input type="checkbox" id="formActive" name="active" class="form-radio relative w-[3.25rem] h-7 p-px bg-gray-100 border-transparent text-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:ring-blue-600 disabled:opacity-50 disabled:pointer-events-none checked:bg-none checked:text-blue-600 checked:border-blue-600 focus:checked:border-blue-600 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-600 before:inline-block before:size-6 before:bg-white checked:before:bg-blue-200 before:translate-x-0 checked:before:translate-x-full before:rounded-full before:shadow-sm before:transform before:ring-0 before:transition before:ease-in-out before:duration-200 dark:before:bg-neutral-400 dark:checked:before:bg-blue-200">
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Request, Response } from "express";
|
||||
import prisma, { Prisma } from "@server/prisma";
|
||||
import { datatableRequest } from "@server/controllers/guild/api/dt.module";
|
||||
import { logger } from "@server/../log";
|
||||
|
||||
export const get = async (request: Request, response: Response) => {
|
||||
if (!request.query.id) {
|
||||
@ -23,7 +24,9 @@ export const get = async (request: Request, response: Response) => {
|
||||
|
||||
export const post = async (request: Request, response: Response) => {
|
||||
const guildId = request.params.guildId;
|
||||
const { name, url, active, channels, filters } = request.body;
|
||||
const { name, url, active, channels, filters, message_style } = request.body;
|
||||
|
||||
logger.debug("Post Feed", request.body);
|
||||
|
||||
// channels comes through as either String[] or String
|
||||
let formattedChannels = undefined;
|
||||
@ -50,7 +53,8 @@ export const post = async (request: Request, response: Response) => {
|
||||
guild_id: guildId,
|
||||
active: active === "on",
|
||||
channels: { create: formattedChannels },
|
||||
filters: { connect: formattedFilters }
|
||||
filters: { connect: formattedFilters },
|
||||
message_style_id: message_style === "" ? null : Number(message_style)
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -67,7 +71,9 @@ export const post = async (request: Request, response: Response) => {
|
||||
|
||||
export const patch = async (request: Request, response: Response) => {
|
||||
const guildId = request.params.guildId;
|
||||
const { id, name, url, active, channels, filters } = request.body;
|
||||
const { id, name, url, active, channels, filters, message_style } = request.body;
|
||||
|
||||
logger.info("Patch Feed", request.body);
|
||||
|
||||
// channels comes through as either String[] or String
|
||||
let formattedChannels = undefined;
|
||||
@ -101,7 +107,11 @@ export const patch = async (request: Request, response: Response) => {
|
||||
filters: {
|
||||
set: [],
|
||||
connect: formattedFilters
|
||||
}
|
||||
},
|
||||
message_style_id:
|
||||
message_style === ""
|
||||
? null
|
||||
: Number(message_style)
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -150,7 +160,7 @@ export const datatable = async (request: Request, response: Response) => {
|
||||
response,
|
||||
prisma.feed,
|
||||
[{ updated_at: "desc" }, { id: "asc" }],
|
||||
{ channels: true, filters: true },
|
||||
{ channels: true, filters: true, message_style: true },
|
||||
{ guild_id: request.params.guildId } // TODO: verify authenticated user can access this guild
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Request, Response } from "express";
|
||||
import prisma, { Prisma } from "@server/prisma";
|
||||
import { datatableRequest } from "@server/controllers/guild/api/dt.module";
|
||||
import { logger } from "@server/../log";
|
||||
|
||||
export const get = async (request: Request, response: Response) => {
|
||||
if (!request.query.id) {
|
||||
@ -34,6 +35,8 @@ export const post = async (request: Request, response: Response) => {
|
||||
description_mutator
|
||||
} = request.body;
|
||||
|
||||
logger.debug("Style Post", request.body);
|
||||
|
||||
let style;
|
||||
|
||||
try {
|
||||
@ -147,4 +150,27 @@ export const datatable = async (request: Request, response: Response) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default { get, post, patch, del, datatable };
|
||||
export const select = async (request: Request, response: Response) => {
|
||||
const guildId = request.params.guildId;
|
||||
const { search } = request.query;
|
||||
|
||||
const data = await prisma.messageStyle.findMany({
|
||||
where: {
|
||||
guild_id: guildId,
|
||||
name: { contains: `${search}` }
|
||||
}
|
||||
});
|
||||
|
||||
// Preline Bug: https://github.com/htmlstreamofficial/preline/issues/567
|
||||
// The returned data must have a "title" key, otherwise the advanced
|
||||
// select component with 'tags' mode will have no title, regardless of
|
||||
// mapping.
|
||||
const modifiedResults = data.map(filter => ({
|
||||
...filter,
|
||||
title: filter.name
|
||||
}));
|
||||
|
||||
response.json(modifiedResults);
|
||||
};
|
||||
|
||||
export default { get, post, patch, del, datatable, select };
|
@ -40,6 +40,7 @@ router.patch("/:guildId/filters/api", filterApiController.patch);
|
||||
router.delete("/:guildId/filters/api", filterApiController.del);
|
||||
|
||||
router.post("/:guildId/styles/api/datatable", styleApiController.datatable);
|
||||
router.get("/:guildId/styles/api/select", styleApiController.select);
|
||||
router.get("/:guildId/styles/api", styleApiController.get);
|
||||
router.post("/:guildId/styles/api", styleApiController.post);
|
||||
router.patch("/:guildId/styles/api", styleApiController.patch);
|
||||
|
Loading…
x
Reference in New Issue
Block a user