Skip to content

Commit

Permalink
Merge pull request #97 from chomosuke/shangzhel/tag-controller
Browse files Browse the repository at this point in the history
Implement app tag controllers
  • Loading branch information
waltervan00 committed Sep 20, 2021
2 parents 62d1157 + 1b4069d commit d898a22
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 8 deletions.
101 changes: 96 additions & 5 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import {
ICardData,
ICardProperties,
cardDataDefaults,
fromRaw,
fromRaw as cardsFromRaw,
implement,
} from './controllers/Card';
import { ITag, ITagData, fromRaw as tagFromRaw } from './controllers/Tag';
import { ResponseStatus } from './ResponseStatus';
import { Home } from './views/Home';
import { Login } from './views/Login';
Expand Down Expand Up @@ -65,6 +66,7 @@ interface IUserStatic {
readonly username: string;
readonly settings: ISettings;
readonly cards: readonly ICardData[];
readonly tags: readonly ITagData[];
}

type GetMeResult = {
Expand All @@ -90,14 +92,16 @@ async function getMe(): Promise<GetMeResult> {
const body = ensureObject(await res.json());
const username = ensureType(body.username, 'string');
const settings = ensureObject(body.settings);
const cards = ensureArray(body.cards).map(fromRaw);
const cards = ensureArray(body.cards).map(cardsFromRaw);
const tags = ensureArray(body.tags).map(tagFromRaw);

return {
status: new ResponseStatus(res),
user: {
username,
settings,
cards,
tags,
},
};
} catch {
Expand Down Expand Up @@ -216,7 +220,7 @@ function implementCardOverride(
});
if (res.ok) {
const raw = await res.json();
const updated = fromRaw(raw);
const updated = cardsFromRaw(raw);
if (put) {
setUser({
...userState,
Expand Down Expand Up @@ -257,6 +261,62 @@ function implementCardOverride(
return implement(cardData, cardMethods, fieldMethodsFactory);
}

function implementTag(
tag: ITagData,
user: IUserStatic,
setUser: Dispatch<SetStateAction<IUserStatic | null | undefined>>,
): ITag {
return {
...tag,
async commit({ label, color }) {
const res = await fetch('/api/tag', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: tag.id,
label,
color,
}),
});

if (res.ok) {
const newTag = tagFromRaw(await res.json());

setUser({
...user,
tags: user.tags.map((existing) => (existing.id === newTag.id
? newTag
: existing)),
});
}

return new ResponseStatus(res);
},
async delete() {
const res = await fetch('/api/tag', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: tag.id,
}),
});

if (res.ok) {
setUser({
...user,
tags: user.tags.filter((existing) => (existing.id !== tag.id)),
});
}

return new ResponseStatus(res);
},
};
}

const AppComponent: React.VoidFunctionComponent = () => {
const [userState, setUserState] = useState<IUserStatic | null>();
const [detail, setDetail] = useState<ICardOverrideData | null>(null);
Expand Down Expand Up @@ -303,7 +363,7 @@ const AppComponent: React.VoidFunctionComponent = () => {
username: userState.username,
settings: userState.settings,
cards: userState.cards.map((card) => implementCard(card, userState, setUser)),
tags: [],
tags: userState.tags.map((tag) => implementTag(tag, userState, setUser)),
};

const context: IAppContext = {
Expand Down Expand Up @@ -331,7 +391,38 @@ const AppComponent: React.VoidFunctionComponent = () => {
overrides: {},
});
},
newTag() { throw notImplemented(); },
async newTag(tagProps) {
if (userState == null) {
throw new Error('userState is nullish');
}

let label = tagProps?.label;
let color = tagProps?.color;
if (label == null) label = '';
if (color == null) color = 'white';

const res = await fetch('/api/tag', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
label,
color,
}),
});

if (res.ok) {
const newTag = tagFromRaw(await res.json());

setUser({
...userState,
tags: [...userState.tags, newTag],
});
}

return new ResponseStatus(res);
},
login(username, password, register) {
return (async function loginAsync() {
const body = {
Expand Down
18 changes: 15 additions & 3 deletions web/src/controllers/Tag.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { ObjectId } from '@porkbellypro/crm-shared';
import { ObjectId, ensureObject, ensureType } from '@porkbellypro/crm-shared';
import { ResponseStatus } from '../ResponseStatus';

export interface ITagProperties {
label: string;
color: string;
}

export interface ITag extends Readonly<ITagProperties> {
readonly id: ObjectId;
export interface ITagData extends ITagProperties {
id: ObjectId;
}

export interface ITag extends Readonly<ITagData> {
commit(props: Partial<ITagProperties>): Promise<ResponseStatus>;
delete(): Promise<ResponseStatus>;
}

export function fromRaw(raw: unknown): ITagData {
const { id, label, color } = ensureObject(raw);
return {
id: ensureType(id, 'string'),
label: ensureType(label, 'string'),
color: ensureType(color, 'string'),
};
}

0 comments on commit d898a22

Please sign in to comment.