Skip to content

Commit

Permalink
WIP: Timeline component improvements, added <FileIcon /> component
Browse files Browse the repository at this point in the history
  • Loading branch information
roncodes committed Dec 19, 2023
1 parent 5c18bb0 commit 789244f
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 223 deletions.
10 changes: 9 additions & 1 deletion addon/components/file-icon.hbs
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
{{yield}}
<div class="file-icon file-icon-{{this.extension}}">
<FaIcon @icon={{this.icon}} class={{@iconClass}} @size={{@iconSize}} />
<span class="file-extension truncate">
{{this.extension}}
</span>
<div>
{{yield}}
</div>
</div>
59 changes: 58 additions & 1 deletion addon/components/file-icon.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';

export default class FileIconComponent extends Component {}
export default class FileIconComponent extends Component {
@tracked file;
@tracked extension;
@tracked icon;

constructor(owner, { file }) {
super(...arguments);

this.file = file;
this.extension = this.getExtension(file);
this.icon = this.getIcon(file);
}

getExtension(file) {
return getWithDefault(
{
'application/vnd.ms-excel': 'xls',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xls',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xls',
'vnd.ms-excel': 'xls',
'text/csv': 'csv',
'text/tsv': 'tsv',
xlsx: 'xls',
xls: 'xls',
xlsb: 'xls',
xlsm: 'xls',
docx: 'doc',
docm: 'doc',
},
getWithDefault(file, 'extension', 'xls'),
'xls'
);
}

getIcon(file) {
const extension = this.getExtension(file);

return getWithDefault(
{
xlsx: 'file-excel',
xls: 'file-excel',
xlsb: 'file-excel',
xlsm: 'file-excel',
csv: 'file-spreadsheet',
tsv: 'file-spreadsheet',
docx: 'file-word',
docm: 'file-word',
pdf: 'file-pdf',
ppt: 'file-powerpoint',
pptx: 'file-powerpoint',
},
extension,
'file-alt'
);
}
}
12 changes: 11 additions & 1 deletion addon/components/modal/layouts/option-prompt.hbs
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}></Modal::Default>
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="p-4 space-y-4">
{{#each @options.promptOptions as |option index|}}
<div class="flex flex-row items-center bg-gray-100 border-gray-200 px-4 py-2 dark:bg-gray-800 dark:border-gray-700 rounded-lg">
<RadioButton @radioClass="focus:ring-blue-500 mr-3" @radioId={{concat "option_" index}} @value={{option}} @groupValue={{@options.selected}} @name="option" @changed={{fn (mut @options.selected)}}>
<span class="dark:text-white font-semibold">{{humanize option}}</span>
</RadioButton>
</div>
{{/each}}
</div>
</Modal::Default>
16 changes: 11 additions & 5 deletions addon/components/timeline.hbs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<div class="timeline timeline-activity-{{@activity.length}}" {{did-insert this.setupComponent}} ...attributes>
<div class="timeline-controls {{@controlsClass}}">
<button class="timeline-arrow-left {{@arrowClass}} {{@arrowLeftClass}}" disabled={{eq this.startIndex 0}} type="button" {{on "click" this.previous}}>&larr;</button>
<div class="timeline-controls-button-wrapper">
<button class="timeline-arrow-left {{@arrowClass}} {{@arrowLeftClass}}" disabled={{eq this.startIndex 0}} type="button" {{on "click" this.previous}}>&larr;</button>
</div>
</div>

<div class="timeline-wrapper {{@wrapperClass}}">
{{#each this.visibleTimelineData as |activity|}}
{{yield (component "timeline/item" activity=activity context=this.context)}}
{{/each}}
<div class="timeline-items-container {{@itemsContainerClass}}">
{{#each this.visibleActivities as |activity|}}
{{yield (component "timeline/item" activity=activity context=this.context)}}
{{/each}}
</div>
</div>

<div class="timeline-controls {{@controlsClass}}">
<button class="timeline-arrow-right {{@arrowClass}} {{@arrowRightClass}}" disabled={{eq this.endIndex (sub @activity.length 1)}} type="button" {{on "click" this.next}}>&rarr;</button>
<div class="timeline-controls-button-wrapper">
<button class="timeline-arrow-right {{@arrowClass}} {{@arrowRightClass}}" disabled={{eq this.endIndex (sub @activity.length 1)}} type="button" {{on "click" this.next}}>&rarr;</button>
</div>
</div>
</div>
53 changes: 15 additions & 38 deletions addon/components/timeline.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,38 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action, computed, set } from '@ember/object';
import { isArray } from '@ember/array';
import { action } from '@ember/object';
import { htmlSafe } from '@ember/template';

export default class TimelineComponent extends Component {
@tracked startIndex = 0;
@tracked endIndex = Math.min(2, this.args.activity.length - 1);
@tracked timelineNode;
@tracked timelineWrapperNode;
@tracked timelineItemWidth;

context = {
previous: this.previous,
next: this.next,
data: this.visibleTimelineData,
};

@computed('args.activity.length', 'endIndex', 'startIndex') get timelineActivity() {
if (isArray(this.args.activity)) {
return this.args.activity.map((activity, index) => {
if (index === this.args.activity.length - 1) {
set(activity, 'isActive', true);
}

return activity;
});
}
return [];
}

@computed('[email protected]', 'startIndex', 'endIndex') get visibleTimelineData() {
return this.timelineActivity.slice(this.startIndex, this.endIndex + 1);
}

@computed('startIndex', 'timelineItemWidth') get wrapperStyle() {
const translateX = `calc(-${this.startIndex} * ${this.timelineItemWidth}px)`;
return htmlSafe(`transform: translateX(${translateX});`);
}
@tracked visibleActivities = this.args.activity.slice(this.startIndex, this.endIndex + 1);

@action setupComponent(timelineNode) {
this.timelineNode = timelineNode;
this.timelineWrapperNode = timelineNode.querySelector('.timeline-wrapper');
this.timelineItemWidth = this.timelineWrapperNode?.firstElementChild?.offsetWidth;
this.timelineItemsContainerNode = this.timelineWrapperNode.firstElementChild;
}

@action previous() {
if (this.startIndex > 0) {
this.startIndex--;
this.endIndex--;
this.startIndex -= 1;
this.endIndex -= 1;
this.updateTimelinePosition();
}
}

@action next() {
if (this.endIndex < this.args.activity.length - 1) {
this.startIndex++;
this.endIndex++;
this.startIndex += 1;
this.endIndex += 1;
this.updateTimelinePosition();
}
}

updateTimelinePosition() {
const translateX = `calc(-${this.startIndex * (100 / 3)}%)`; // Assuming each item takes up 33.33% of the width
this.timelineItemsContainerNode.style.transform = `translateX(${translateX})`;
this.visibleActivities = this.args.activity.slice(this.startIndex, this.endIndex + 1);
}
}
2 changes: 1 addition & 1 deletion addon/components/timeline/item.hbs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="timeline-item {{if @activity.isActive 'active animate-pulse'}}" ...attributes>{{yield @activity @context}}</div>
<div class="timeline-item {{if this.isActive 'active animate-pulse'}}" ...attributes>{{yield @activity @context}}</div>
14 changes: 13 additions & 1 deletion addon/components/timeline/item.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class TimelineItemComponent extends Component {}
export default class TimelineItemComponent extends Component {
@tracked isActive = false;

constructor(owner, { activeStatus, activity }) {
super(...arguments);

this.isActive = typeof activeStatus === 'string' && typeof activity.code === 'string' && activeStatus.toLowerCase() === activity.code.toLowerCase();
if (typeof activity.isActive === 'boolean') {
this.isActive = activity.isActive;
}
}
}
1 change: 1 addition & 0 deletions addon/services/modals-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export default class ModalsManagerService extends Service {
resolve(selected);
},
decline: () => {
this.done();
resolve(null);
},
...modalOptions,
Expand Down
56 changes: 45 additions & 11 deletions addon/styles/components/timeline.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.timeline {
display: flex;
display: grid;
grid-template-columns: repeat(14, 1fr);
align-items: center;
width: 100%;
max-width: 600px;
position: relative;
margin: 0 auto;
box-sizing: border-box;
Expand All @@ -17,9 +17,31 @@

.timeline-controls {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
grid-column: span 2;
margin-top: -20px;
cursor: default;
}

.timeline-controls button,
.timeline-controls a {
cursor: default;
}

.timeline-controls > .timeline-controls-button-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 0 1rem;
}

.timeline > .timeline-controls:first-child {
justify-content: flex-end;
}

.timeline > .timeline-controls:last-child {
justify-content: flex-start;
}

.timeline-arrow-left,
Expand All @@ -40,25 +62,37 @@
}

.timeline-wrapper {
display: flex;
flex-direction: row;
align-items: center;
position: relative;
width: 100%;
max-height: 400px;
flex: 1;
display: grid;
grid-template-columns: 1fr;
grid-column: span 10;
transition: transform 0.5s ease;
max-height: 400px;
overflow: hidden;
}

.timeline-items-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: .5rem;
position: relative;
overflow: visible;
margin-bottom: 10px;
border-bottom: 3px rgb(243, 244, 246) solid;
padding-bottom: 20px;
border-bottom: 3px rgb(243, 244, 246) solid;
}

.timeline-item {
display: flex;
flex-direction: column;
will-change: transform, opacity;
overflow: visible;
font-size: 0.875rem;
line-height: 1.25rem;
box-sizing: border-box;
}

.timeline-item * {
box-sizing: border-box;
}

.timeline-item.active::after {
Expand Down
1 change: 1 addition & 0 deletions addon/styles/layout/utilities.css
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ body[data-theme='dark'] .dimensions-box:before {
height: 19.53rem;
}

.w-99pr,
.w-almost-full {
width: 99%;
}
Expand Down
2 changes: 1 addition & 1 deletion addon/utils/format-currency.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import getCurrency from './get-currency';
import formatMoney from 'accounting/format-money';
import formatMoney from '@fleetbase/ember-accounting/utils/format-money';

export default function formatCurrency(amount = 0, currencyCode = 'USD') {
let currency = getCurrency(currencyCode);
Expand Down
Empty file removed lib/.gitkeep
Empty file.
1 change: 0 additions & 1 deletion lib/ember-cli-accounting
Submodule ember-cli-accounting deleted from 7864f8
Loading

0 comments on commit 789244f

Please sign in to comment.