Skip to content

Commit

Permalink
Merge pull request #474 from appuniversum/chore/more-gts
Browse files Browse the repository at this point in the history
More Glint / TS conversion
  • Loading branch information
Windvis authored Mar 11, 2024
2 parents 47dcdd2 + c03bca1 commit 3595665
Show file tree
Hide file tree
Showing 34 changed files with 885 additions and 416 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
import { AuBadge, AuPill } from '@appuniversum/ember-appuniversum';
import type { TOC } from '@ember/component/template-only';
import { hash } from '@ember/helper';
import Component from '@glimmer/component';
import AuBadge from './au-badge';
import AuPill from './au-pill';

export default class AuFieldset extends Component {
export interface AuFieldsetSignature {
Args: {
alignment?: 'inline';
};
Blocks: {
default: [
{
legend?: typeof Legend;
content?: typeof Content;
},
];
};
Element: HTMLFieldSetElement;
}

export default class AuFieldset extends Component<AuFieldsetSignature> {
get alignment() {
if (this.args.alignment == 'inline') return 'au-c-fieldset--inline';
else return '';
Expand All @@ -16,7 +33,22 @@ export default class AuFieldset extends Component {
</template>
}

class Legend extends Component {
interface LegendSignature {
Args: {
error?: boolean;
inline?: boolean;
required?: boolean;
requiredLabel?: string;
skin?: '1' | '2' | '3' | '4' | '5' | '6' | 'functional';
warning?: boolean;
};
Blocks: {
default: [];
};
Element: HTMLDivElement;
}

class Legend extends Component<LegendSignature> {
get skin() {
if (this.args.skin == '1') return 'au-u-h1';
if (this.args.skin == '2') return 'au-u-h2';
Expand Down Expand Up @@ -86,7 +118,13 @@ class Legend extends Component {
</template>
}

const Content = <template>
interface ContentSignature {
Blocks: {
default: [];
};
Element: HTMLDivElement;
}
const Content: TOC<ContentSignature> = <template>
{{#if (has-block)}}
<div class="au-c-fieldset__content" ...attributes>
{{yield}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { AuHeading, AuIcon } from '@appuniversum/ember-appuniversum';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import AuHeading from './au-heading';
import AuIcon from './au-icon';

export default class AuFileCard extends Component {
export interface AuFileCardSignature {
Args: {
filename: string;
fileSize?: string;
downloadLink?: string;
onDelete?: () => void;
};
Element: HTMLElement;
}

export default class AuFileCard extends Component<AuFileCardSignature> {
get isRemovable() {
return typeof this.args.onDelete === 'function';
}
Expand All @@ -16,9 +27,9 @@ export default class AuFileCard extends Component {
}

@action
delete(event) {
delete(event: Event) {
event.preventDefault();
this.args.onDelete();
this.args.onDelete?.();
}

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,51 @@
import { AuAlert, AuHelpText, AuIcon } from '@appuniversum/ember-appuniversum';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import { inject as service } from '@ember/service';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';
import perform from 'ember-concurrency/helpers/perform';
import FileDropzone from 'ember-file-upload/components/file-dropzone';
import fileQueue from 'ember-file-upload/helpers/file-queue';
import type { FileQueueService, UploadFile } from 'ember-file-upload';
import AuAlert from './au-alert';
import AuHelpText from './au-help-text';
import AuIcon from './au-icon';

export interface AuFileUploadSignature {
Args: {
accept?: string;
endPoint?: string;
helpTextDragDrop?: string;
helpTextFileNotSupported?: string;
maxFileSizeMB?: number;
multiple?: boolean;
onFinishUpload?: (uploadedFile: number, queueInfo: QueueInfo) => void;
onQueueUpdate?: (queueInfo: QueueInfo) => void;
title?: string;
};
// ember-file-upload doesn't seem to expose the signature of the FileDropzone component
// We just hardcode what they have defined in the addon for now.
Element: HTMLElement;
}

export type QueueInfo = {
isQueueEmpty: boolean;
};

// A simpler version of the File and UploadFile types
type BasicFile = {
name: string;
type: string;
};

type UploadError = {
filename: string;
error?: string;
};

export default class AuFileUpload extends Component {
@service fileQueue;
@tracked uploadErrorData = [];
export default class AuFileUpload extends Component<AuFileUploadSignature> {
@service declare fileQueue: FileQueueService;
@tracked uploadErrorData: UploadError[] = [];

get uploadingMsg() {
return `Bezig met het opladen van ${this.queue.files.length} bestand(en). (${this.queue.progress}%)`;
Expand Down Expand Up @@ -55,37 +89,43 @@ export default class AuFileUpload extends Component {
return this.uploadErrorData.length > 0;
}

@task
*upload(file) {
@action
upload(file: UploadFile): void | undefined {
this.uploadTask.perform(file);
}

uploadTask = task(async (file: UploadFile) => {
this.resetErrors();
let uploadedFile = yield this.uploadFileTask.perform(file);
const uploadedFile = await this.uploadFileTask.perform(file);

this.notifyQueueUpdate();

if (uploadedFile && this.args.onFinishUpload)
this.args.onFinishUpload(uploadedFile, this.calculateQueueInfo());
}
});

@task({ enqueue: true, maxConcurrency: 3 })
*uploadFileTask(file) {
this.notifyQueueUpdate();
try {
const response = yield file.upload(this.endPoint, {
'Content-Type': 'multipart/form-data',
});
const body = yield response.json();
const fileId = body?.data?.id;
return fileId;
} catch (e) {
this.addError(file);
this.removeFileFromQueue(file);
return null;
}
}
uploadFileTask = task(
{ enqueue: true, maxConcurrency: 3 },
async (file: UploadFile): Promise<number | null> => {
this.notifyQueueUpdate();
try {
const response = await file.upload(this.endPoint, {
contentType: 'multipart/form-data',
});
const body = await response.json();
const fileId = body?.data?.id;
return fileId;
} catch (e) {
this.addError(file);
this.removeFileFromQueue(file);
return null;
}
},
);

@action
filter(file, files, index) {
let isFirstFile = index === 0;
filter(file: File, files: File[], index: number) {
const isFirstFile = index === 0;

if (isFirstFile) {
this.resetErrors();
Expand Down Expand Up @@ -115,14 +155,14 @@ export default class AuFileUpload extends Component {
}
}

calculateQueueInfo() {
calculateQueueInfo(): QueueInfo {
const filesQueueInfo = {
isQueueEmpty: this.uploadFileTask.isIdle,
};
return filesQueueInfo;
}

addError(file, errorMessage) {
addError(file: BasicFile, errorMessage?: string) {
this.uploadErrorData = [
...this.uploadErrorData,
{
Expand All @@ -136,13 +176,13 @@ export default class AuFileUpload extends Component {
this.uploadErrorData = [];
}

removeFileFromQueue(file) {
removeFileFromQueue(file: UploadFile) {
this.queue.remove(file);
}

<template>
{{#let
(fileQueue name=this.queueName onFileAdded=(perform this.upload))
(fileQueue name=this.queueName onFileAdded=this.uploadTask.perform)
as |queue|
}}
<FileDropzone
Expand Down Expand Up @@ -212,39 +252,39 @@ export default class AuFileUpload extends Component {
}

// Private util that is exported for testing purposes
export function isValidFileType(file, accept) {
export function isValidFileType(file: Partial<BasicFile>, accept?: string) {
if (!accept) {
return true;
}

let tokens = accept.split(',').map(function (token) {
const tokens = accept.split(',').map(function (token) {
return token.trim().toLowerCase();
});

let validMimeTypes = tokens.filter(function (token) {
const validMimeTypes = tokens.filter(function (token) {
return !token.startsWith('.');
});
let type = file.type?.toLowerCase();
const type = file.type?.toLowerCase();

let validExtensions = tokens.filter(function (token) {
const validExtensions = tokens.filter(function (token) {
return token.startsWith('.');
});

let extension = null;
if (file.name && /(\.[^.]+)$/.test(file.name)) {
extension = file.name.toLowerCase().match(/(\.[^.]+)$/)[1];
extension = file.name.toLowerCase().match(/(\.[^.]+)$/)?.[1];
}

return (
isValidMimeType(type, validMimeTypes) ||
isValidExtension(extension, validExtensions)
(!!type && isValidMimeType(type, validMimeTypes)) ||
(!!extension && isValidExtension(extension, validExtensions))
);
}

function isValidMimeType(type, validMimeTypes = []) {
function isValidMimeType(type: string, validMimeTypes: string[] = []) {
return validMimeTypes.some(function (validType) {
if (['audio/*', 'video/*', 'image/*'].includes(validType)) {
let genericType = validType.split('/')[0];
const genericType = validType.split('/')[0] as string;

return type.startsWith(genericType);
} else {
Expand All @@ -253,10 +293,13 @@ function isValidMimeType(type, validMimeTypes = []) {
});
}

function isValidExtension(extension, validExtensions = []) {
function isValidExtension(
extension: string,
validExtensions: string[] = [],
): boolean {
return validExtensions.includes(extension);
}

function isValidFileSize(fileSize, maximumSize) {
function isValidFileSize(fileSize: number, maximumSize: number): boolean {
return fileSize < maximumSize * Math.pow(1024, 2);
}
19 changes: 17 additions & 2 deletions addon/components/au-label.gjs → addon/components/au-label.gts
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import Component from '@glimmer/component';
import { AuBadge, AuPill } from '@appuniversum/ember-appuniversum';
import AuBadge from './au-badge';
import AuPill from './au-pill';

export default class AuLabel extends Component {
export interface AuLabelSignature {
Args: {
error?: boolean;
inline?: boolean;
required?: boolean;
requiredLabel?: string;
warning?: boolean;
};
Blocks: {
default: [];
};
Element: HTMLLabelElement;
}

export default class AuLabel extends Component<AuLabelSignature> {
get inline() {
if (this.args.inline) return 'au-c-label--inline';
else return '';
Expand Down
Loading

0 comments on commit 3595665

Please sign in to comment.