Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Llad 2 #141

Merged
merged 3 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/src/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import axios from "axios";
import AuthHelper from "./components/util/AuthHelper";
import { AssetTagFramework, Book, ConductorBaseResponse, Homework, Project, ProjectFile, User } from "./types";
import { AssetTagFramework, AssetTagFrameworkWithKeys, Book, ConductorBaseResponse, Homework, Project, ProjectFile, User } from "./types";
import { ProjectFileWProjectID } from "./types/Project";

/**
Expand Down Expand Up @@ -40,7 +40,7 @@ class API {
const res = await axios.get<{
err: boolean;
errMsg?: string;
framework: AssetTagFramework;
framework: AssetTagFrameworkWithKeys
}>(`/assettagframeworks/${id}`);
return res;
}
Expand Down
50 changes: 39 additions & 11 deletions client/src/components/FilesManager/EditFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import SelectFramework from "./SelectFramework";
import api from "../../api";
import { getInitValueFromTemplate } from "../../utils/assetHelpers";
import { RenderTagInput } from "./RenderTagInput";
import { AssetTagTemplate, AssetTagValue } from "../../types/AssetTagging";
import { isAssetTagFramework } from "../../utils/typeHelpers";
import { AssetTagTemplate, AssetTagValue, AssetTagWithKey } from "../../types/AssetTagging";
import { isAssetTagFramework, isAssetTagKeyObject } from "../../utils/typeHelpers";

interface EditFileModalProps extends ModalProps {
show: boolean;
Expand Down Expand Up @@ -95,7 +95,18 @@ const EditFile: React.FC<EditFileModalProps> = ({
}

const fileData = res.data.files[res.data.files.length - 1]; // Target file should be last in array
reset(fileData);
const parsedExistingTags: AssetTag[] = fileData.tags?.map(
(t: AssetTagWithKey) => {
return {
...t,
key: t.key.title,
};
}
);
reset({
...fileData,
tags: parsedExistingTags,
});
setIsFolder(fileData.storageType !== "file");
} catch (err) {
handleGlobalError(err);
Expand Down Expand Up @@ -145,7 +156,19 @@ const EditFile: React.FC<EditFileModalProps> = ({
throw new Error(res.data.errMsg);
}

setSelectedFramework(res.data.framework);
const parsed: AssetTagTemplate[] = res.data.framework.templates.map(
(t) => {
return {
...t,
key: t.key.title,
};
}
);

setSelectedFramework({
...res.data.framework,
templates: parsed,
});
genTagsFromFramework();
} catch (err) {
handleGlobalError(err);
Expand All @@ -164,35 +187,40 @@ const EditFile: React.FC<EditFileModalProps> = ({

if (existingTags && existingTags.length > 0) {
filtered = selectedFramework.templates.filter(
(t) => !existingTags.find((tag) => tag.title === t.title)
(t) => !existingTags.find((tag) => {
if(isAssetTagKeyObject(tag.key)){
return tag.key.title === t.key
}
return tag.key === t.key
})
);
} else {
filtered = selectedFramework.templates;
}

filtered.forEach((t) => {
addTag({
title: t.title,
key: t.key,
value: getInitValueFromTemplate(t),
framework: selectedFramework,
});
});
}

function addTag({
title,
key,
value,
framework,
}: {
title?: string;
key?: string;
value?: AssetTagValue;
framework?: AssetTagFramework;
}) {
if (isFolder) return; // No asset tags for folders
append(
{
uuid: crypto.randomUUID(), // Random UUID for new tags, will be replaced with real UUID server-side on save
title: title ?? "",
key: key ?? "",
value: value ?? "",
framework: framework ?? undefined,
isDeleted: false,
Expand Down Expand Up @@ -254,7 +282,7 @@ const EditFile: React.FC<EditFileModalProps> = ({
<Table.Cell>
{tag.framework ? (
<div className="flex flex-col">
<p>{tag.title}</p>
<p>{isAssetTagKeyObject(tag.key) ? tag.key.title : tag.key}</p>
{/* {isAssetTagFramework(tag.framework) && (
<div className="mt-1">
<Label size="mini">
Expand All @@ -265,7 +293,7 @@ const EditFile: React.FC<EditFileModalProps> = ({
</div>
) : (
<CtlTextInput
name={`tags.${index}.title`}
name={`tags.${index}.key`}
control={control}
fluid
/>
Expand Down
44 changes: 29 additions & 15 deletions client/src/components/FilesManager/RenderAssetTags.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
import { Label } from "semantic-ui-react";
import { AssetTag, ProjectFile } from "../../types";
import { truncateString } from "../util/HelperFunctions";
import { SemanticCOLORSArray } from "../../utils/misc";
import { isAssetTagKeyObject } from "../../utils/typeHelpers";

const RenderAssetTags: React.FC<{ file: ProjectFile }> = ({ file }) => {
const sortedTags = file.tags?.sort((a, b) => {
if (isAssetTagKeyObject(a.key) && isAssetTagKeyObject(b.key)) {
return a.key.title.localeCompare(b.key.title);
}
return 0;
});

function getLabelValue(tag: AssetTag) {
const text = tag.title + ": " + tag.value.toString();
const title = isAssetTagKeyObject(tag.key) ? tag.key.title : tag.key;
const text = title + ": " + tag.value.toString();
const truncated = truncateString(text, 20);
return truncated;
}

// Get a random color from SemanticCOLORSArray
function getLabelColor() {
// Remove grey from the array, reserve it for the "more" truncation label
const colors = SemanticCOLORSArray.filter((color) => color !== "grey");
const randomElement =
colors[
Math.floor(Math.random() * colors.length)
];
return randomElement;
function getLabelColor(tag: AssetTag) {
if(tag.key && isAssetTagKeyObject(tag.key)) {
return tag.key.hex;
}
return "grey";
}

return (
<div className="asset-tag-container">
{file.tags?.slice(0, 5).map((tag) => (
<Label color={getLabelColor()} size="tiny" key={tag.uuid}>
{!sortedTags ||
(sortedTags.length === 0 && (
<span className="muted-text italic">No associated tags</span>
))}
{sortedTags?.slice(0, 5).map((tag) => (
<Label style={
{
backgroundColor: getLabelColor(tag).toString(),
borderColor: getLabelColor(tag).toString(),
color: "white"
}
} size="tiny" key={tag.uuid}>
{getLabelValue(tag)}
</Label>
))}
{file.tags && file.tags?.length > 5 ? (
{sortedTags && sortedTags?.length > 5 ? (
<Label color="grey" size="tiny">
+{file.tags?.length - 5} more
+{sortedTags?.length - 5} more
</Label>
) : (
<></>
Expand Down
9 changes: 7 additions & 2 deletions client/src/components/FilesManager/RenderTagInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
ProjectFile,
} from "../../types";
import CtlTextInput from "../ControlledInputs/CtlTextInput";
import { isAssetTagFramework } from "../../utils/typeHelpers";
import {
isAssetTagFramework,
isAssetTagKeyObject,
} from "../../utils/typeHelpers";
import { Dropdown } from "semantic-ui-react";

interface RenderTagInputProps {
Expand Down Expand Up @@ -63,7 +66,9 @@ export const RenderTagInput: React.FC<RenderTagInputProps> = ({
}

const templateInFramework = tag.framework.templates.find(
(template) => template.title === tag.title
(template) =>
template.title ===
(isAssetTagKeyObject(tag.key) ? tag.key.title : tag.key)
);

if (templateInFramework) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import {
Button,
Dropdown,
Icon,
Input,
Modal,
ModalProps,
Select,
Table,
} from "semantic-ui-react";
import {
AssetTagTemplate,
AssetTagFramework,
AssetTagTemplate,
AssetTagTemplateValueTypeOptions,
} from "../../../types";
import CtlCheckbox from "../../ControlledInputs/CtlCheckbox";
import CtlTextInput from "../../ControlledInputs/CtlTextInput";
import "../../../styles/global.css";
import { isAssetTagTemplate } from "../../../utils/typeHelpers";
import {
isAssetTagKeyObject,
isAssetTagTemplate,
} from "../../../utils/typeHelpers";
import { useEffect, useState } from "react";
import CtlDropdown from "../../ControlledInputs/CtlDropdown";
import useGlobalError from "../../error/ErrorHooks";
import api from "../../../api";
import LoadingSpinner from "../../LoadingSpinner";
Expand Down Expand Up @@ -76,7 +76,22 @@ const ManageFrameworkModal: React.FC<ManageFrameworkModalProps> = ({
const res = await api.getFramework(id);
if (!res.data.framework) throw new Error("No framework found");

reset(res.data.framework);
const parsed: AssetTagTemplate[] = res.data.framework.templates.map(
(t) => {
return {
key: t.key.title,
valueType: t.valueType,
defaultValue: t.defaultValue,
options: t.options,
isDeleted: false,
};
}
);

reset({
...res.data.framework,
templates: parsed,
});
} catch (err) {
handleGlobalError(err);
} finally {
Expand Down Expand Up @@ -211,7 +226,7 @@ const ManageFrameworkModal: React.FC<ManageFrameworkModalProps> = ({
<Table.Cell>
<CtlTextInput
control={control}
name={`templates.${index}.title`}
name={`templates.${index}.key`}
fluid
/>
</Table.Cell>
Expand Down Expand Up @@ -270,7 +285,7 @@ const ManageFrameworkModal: React.FC<ManageFrameworkModalProps> = ({
onClick={() =>
append(
{
title: "",
key: "",
valueType: "text",
defaultValue: "",
isDeleted: false,
Expand Down
Loading
Loading