added 260907 version of worker toolkit

This commit is contained in:
2026-09-08 20:30:51 -04:00
parent cbd3f0f8ca
commit 97aca37663
1283 changed files with 142951 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
import Ember from 'ember';
import ENV from 'flaredown/config/environment';
const {
get,
computed,
Mixin,
} = Ember;
export default Mixin.create({
staticUrl: ENV.staticUrl,
currentUrl: computed('staticUrl', 'router.url', function() {
return `${get(this, 'staticUrl')}${get(this, 'router.url')}`;
}),
afterModel: function(model) {
this.setHeadTags(model);
this._super(...arguments);
},
});

View File

@@ -0,0 +1,45 @@
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Mixin.create(AuthenticatedRouteMixin, {
init() {
this._super(...arguments);
if(this.get('session.fullStoryInitialized') === false) {
this.setFullStoryUser();
}
},
setFullStoryUser() {
let currentUser = this.get('session.currentUser');
if (Ember.isPresent(currentUser)) {
currentUser.then( user => {
if (Ember.isPresent(window.FS)) {
window.FS.identify(user.get('id'));
this.set('session.fullStoryInitialized', true);
}
});
}
},
notifyPageChange() {
Ember.run.scheduleOnce('afterRender', this, () => {
this.androidPageChange();
});
},
androidPageChange() {
if (Ember.isPresent(window.AndroidInterface)) {
window.AndroidInterface.pageChanged(document.location.href);
}
},
actions: {
didTransition() {
this.notifyPageChange();
this._super();
}
}
});

View File

@@ -0,0 +1,23 @@
import Ember from 'ember';
const {
get,
Mixin,
inject: {
service,
},
} = Ember;
export default Mixin.create({
routeHistory: service(),
actions: {
navigateBack() {
const previous = get(this, 'routeHistory').popEntry();
if (previous) {
this.transitionToRoute(...previous);
}
},
},
});

View File

@@ -0,0 +1,19 @@
import Ember from 'ember';
const {
get,
Mixin,
computed,
String: {
htmlSafe,
},
} = Ember;
export default Mixin.create({
bodyWithBr: computed('body', function() {
const phrase = "@[A-Z][A-z0-9]+\\b";
const changedBody = (get(this, 'body') || []).replace(new RegExp(phrase, 'g'), (item) => { return `<b>${item}</b>`; });
return htmlSafe((changedBody || '').replace(/\n/g, "<br>") );
}),
});

View File

@@ -0,0 +1,51 @@
import Ember from 'ember';
import moment from 'moment';
const {
get,
computed,
Mixin,
setProperties,
inject: {
service,
},
computed: {
alias,
},
} = Ember;
export default Mixin.create({
chartsVisibilityService: service('charts-visibility'),
patternIncludes : alias('chartsVisibilityService.patternIncludes'),
checkins: [],
trackables: [],
isChartEnablerDisabled: computed('patternIncludes.length', function() {
return get(this, 'patternIncludes.length') === 0;
}),
setChartsData() {
const tags = this.store.peekAll('tag').toArray();
const foods = this.store.peekAll('food').toArray();
const checkins = this.peekSortedCheckins();
const symptoms = this.store.peekAll('symptom').toArray();
const conditions = this.store.peekAll('condition').toArray();
const treatments = this.store.peekAll('treatment').toArray();
const harveyBradshawIndices = this.store.peekAll('harveyBradshawIndex').toArray();
const trackables = [...conditions, ...symptoms, ...treatments, ...tags, ...foods, ...harveyBradshawIndices];
return this.isDestroyed || setProperties(this, {checkins, trackables});
},
peekSortedCheckins() {
return this
.store
.peekAll('checkin')
.toArray()
.sort(
(a, b) => moment(get(a, 'date')).diff(get(b, 'date'), 'days')
);
},
});

View File

@@ -0,0 +1,43 @@
import Ember from 'ember';
import moment from 'moment';
const {
get,
computed,
Mixin,
} = Ember;
export default Mixin.create({
startAt: computed('daysRadius', 'centeredDate', function() {
const daysRadius = get(this, 'daysRadius');
const centeredDate = get(this, 'centeredDate');
if (centeredDate) {
return moment(centeredDate).subtract(daysRadius, 'days');
} else {
return moment().subtract(daysRadius * 2, 'days');
}
}),
endAt: computed('daysRadius', 'centeredDate', function() {
const centeredDate = get(this, 'centeredDate');
if (centeredDate) {
return moment(centeredDate).add(get(this, 'daysRadius'), 'days');
} else {
return moment();
}
}),
daysRadius: computed('SVGWidth', function() {
return Math.ceil(get(this, 'SVGWidth') / (get(this, 'pixelsPerDate') * 2));
}),
startAtWithCache: computed('startAt', function() {
return moment(get(this, 'startAt')).subtract(get(this, 'daysRadius'), 'days');
}),
endAtWithCache: computed('endAt', function() {
return moment(get(this, 'endAt')).add(get(this, 'daysRadius'), 'days');
})
})

View File

@@ -0,0 +1,51 @@
import Ember from 'ember';
import moment from 'moment';
/*
Assumes the following exist:
this.get('store')
this.router
*/
export default Ember.Mixin.create({
checkinByDate(date) {
return new Ember.RSVP.Promise((resolve) => {
this.get('store').query('checkin', {date: date}).then(results => {
var records = results.toArray();
resolve(records);
});
});
},
routeToCheckinsForDate(date) {
this.checkinByDate(date).then(() => {
if (typeof FastBoot === 'undefined') {
this.router.transitionTo('checkin.date', date);
}
});
},
routeToNewCheckin(date, step) {
var newCheckin = this.get('store').createRecord('checkin', {date: date});
newCheckin.save().then(savedCheckin => {
this.router.transitionTo('checkin.show', savedCheckin.get('id'), step ? step : 'conditions');
});
},
routeToCheckin(checkin, step) {
this.router.transitionTo('checkin.show', checkin.id, step ? step : 'summary')
},
actions: {
goToTodaysCheckins() {
this.routeToCheckinsForDate(moment(new Date()).format("YYYY-MM-DD"));
},
goToNewCheckin(date) {
this.routeToNewCheckin(moment(date).format("YYYY-MM-DD"));
},
goToCheckin(checkin) {
this.routeToCheckin(checkin)
},
},
});

View File

@@ -0,0 +1,24 @@
import DS from 'ember-data';
import Ember from 'ember';
export default Ember.Mixin.create({
colorId: DS.attr('string'),
strokeClass: Ember.computed('colorId', function() {
return `colorable-stroke-${this.get('colorId')}`;
}),
bgClass: Ember.computed('colorId', function() {
return `colorable-bg-${this.get('colorId')}`;
}),
borderClass: Ember.computed('colorId', function() {
return `colorable-border-${this.get('colorId')}`;
}),
clrClass: Ember.computed('colorId', function() {
return `colorable-clr-${this.get('colorId')}`;
}),
fillClass: Ember.computed('colorId', function() {
return `colorable-fill-${this.get('colorId')}`;
}),
});

View File

@@ -0,0 +1,7 @@
import Ember from 'ember';
export default Ember.Mixin.create({
pressureFieldByUnits(unit) {
return unit === 'in' ? 'pressureInches' : 'pressure';
},
});

View File

@@ -0,0 +1,24 @@
import Ember from 'ember';
const {
get,
Mixin,
inject: {
service,
},
} = Ember;
export default Mixin.create({
routeHistory: service(),
afterModel(model, transition) {
get(this, 'routeHistory').pushEntry(this.historyEntry(model, transition));
},
historyEntry(model, transition) {
// Redefine this method in every route this mixin included to if it relies on params
// It should return an array of route name and params
// return null if the route should be skipped from adding to history
return [transition.targetName];
},
});

View File

@@ -0,0 +1,25 @@
import Ember from 'ember';
const {
set,
getProperties,
} = Ember;
export default Ember.Mixin.create({
performSearch(term, resolve, reject) {
this
.searchByTerm('topic', term)
.then((topics) => {
set(this, 'foundTopics', topics);
resolve(topics);
}, reject);
},
actions: {
goToTopic(topic) {
const { id, modelType } = getProperties(topic, 'id', 'modelType');
this.transitionToRoute('posts.topic', modelType, id);
},
}
});

View File

@@ -0,0 +1,12 @@
import DS from 'ember-data';
import Ember from 'ember';
export default Ember.Mixin.create({
_destroy: DS.attr('string'),
prepareForDestroy: function() {
this.set('_destroy', '1');
},
isPreparedForDestroy: Ember.computed.equal('_destroy', '1')
});

View File

@@ -0,0 +1,18 @@
import Ember from 'ember';
const {
get,
Mixin,
getProperties,
} = Ember;
export default Mixin.create({
getPostables(page) {
return get(this, 'store').query('postable', { page }).then(postables => {
const fakePostable = get(postables, 'firstObject');
const { posts, comments } = getProperties(fakePostable, 'posts', 'comments');
return posts.toArray().concat(comments.toArray());
});
},
});

View File

@@ -0,0 +1,69 @@
import Ember from 'ember';
export default Ember.Mixin.create({
// In order do debounce search request the extended objects should implement "performSearch" function
// with the following signature:
//
// performSearch(term, resolve, reject) {
// this
// .yourSearchActionWhichReturnsPromise(term)
// .then(function() { resolve(...arguments); }, reject);
// }
//
// and use "searchObjects(term)" action defined in this mixin
//
// also one can redefine "debounceTimeout" in his extended objects if need to
debounceTimeout: 200,
searchByTerm(resource, term) {
return this.customSearch({
resource: resource,
query: {
name: term
}
});
},
randomSearch(resource) {
return this.customSearch({
resource: resource,
scope: 'random'
});
},
customSearch(params) {
return this.store.queryRecord('search', params).then((searchRecord) => {
return searchRecord.get('searchables');
});
},
createRecord(resource, term) {
return this.store.createRecord(resource, { name: term });
},
createAndSave(resource, term) {
return new Ember.RSVP.Promise((resolve, reject) => {
this.createRecord(resource, term).save().then(function(saved) {
resolve(saved);
}, function() {
reject(...arguments);
});
});
},
actions: {
searchObjects(term) {
return new Ember.RSVP.Promise((resolve, reject) => {
Ember.run.debounce(this, this.performSearch, term, resolve, reject, this.get('debounceTimeout'));
});
},
shouldShowCreateOption(term, options) {
let foundOption = options.find(function(item) {
return Ember.isEqual(term.trim().replace(/\s\s+/g, ' ').toLowerCase(), item.get('name').toLowerCase());
});
return !Ember.isPresent(foundOption);
},
},
});

View File

@@ -0,0 +1,5 @@
import Ember from 'ember';
export default Ember.Mixin.create({
});

View File

@@ -0,0 +1,52 @@
import Ember from 'ember';
const {
get,
set,
Mixin,
computed,
} = Ember;
export default Mixin.create({
step: computed('model.stepId', 'stepsService.steps', function() {
return get(this, `stepsService.steps.${get(this, 'model.stepId')}`);
}),
actions: {
moveToNextStep() {
const step = get(this, 'step');
if (!get(step, 'nextId')) {
this.router.transitionTo(this.routeAfterCompleted);
} else {
const nextStep = get(this, `stepsService.steps.${step.nextId}`);
if (get(this, 'isOnboarding')) {
let profile = get(this, 'model.profile');
const savedStepId = get(profile, 'onboardingStepId');
if (nextStep.prevId === savedStepId) {
set(profile, 'onboardingStep', nextStep);
profile.save().then(() => this.transitionTo(nextStep));
} else {
this.transitionTo(nextStep);
}
} else {
this.transitionTo(nextStep);
}
}
},
moveToPrevStep() {
const step = get(this, 'step');
const prevStep = get(this, `stepsService.steps.${step.prevId}`);
this.transitionTo(prevStep);
}
},
transitionTo: function(step) {
this.router.transitionTo(step.prefix, step.stepName);
}
});

View File

@@ -0,0 +1,21 @@
import Ember from 'ember';
const {
set,
inject: {
service,
},
Mixin,
} = Ember;
export default Mixin.create({
logoVisiability: service(),
activate() {
set(this, 'logoVisiability.showHeaderLogo', false);
},
deactivate() {
set(this, 'logoVisiability.showHeaderLogo', true);
},
});

View File

@@ -0,0 +1,53 @@
import DS from 'ember-data';
import Ember from 'ember';
const {
attr,
hasMany,
} = DS;
const {
get,
Mixin,
computed,
} = Ember;
export default Mixin.create({
tagIds: attr(),
symptomIds: attr(),
conditionIds: attr(),
treatmentIds: attr(),
tags: hasMany('tag', { async: false }),
symptoms: hasMany('symptom', { async: false }),
conditions: hasMany('condition', { async: false }),
treatments: hasMany('treatment', { async: false }),
topics: computed('tags', 'symptoms', 'conditions', 'treatments', function() {
return [
...get(this, 'tags').toArray(),
...get(this, 'symptoms').toArray(),
...get(this, 'conditions').toArray(),
...get(this, 'treatments').toArray(),
].sortBy('name');
}),
addTopic(topic) {
if (!get(this, topic.constructor.modelName.pluralize()).find(item => item === topic)) {
this.manipulateTopic(topic, 'pushObject');
}
},
removeTopic(topic) {
this.manipulateTopic(topic, 'removeObject');
},
manipulateTopic(topic, action) {
const id = parseInt(get(topic, 'id'));
const type = topic.constructor.modelName;
const idsKey = `${type}Ids`;
get(this, idsKey)[action](id);
get(this, type.pluralize())[action](topic);
},
});

View File

@@ -0,0 +1,16 @@
import Ember from 'ember';
export default Ember.Mixin.create({
selectableData: Ember.inject.service(),
trackableTypeIsCondition: Ember.computed.equal('trackableType', 'condition'),
trackableTypeIsSymptom: Ember.computed.equal('trackableType', 'symptom'),
trackableTypeIsTreatment: Ember.computed.equal('trackableType', 'treatment'),
trackables: Ember.computed('trackableType', function() {
var key = this.get('trackableType').pluralize();
return this.get(`selectableData.${key}`);
})
});

View File

@@ -0,0 +1,12 @@
import Ember from 'ember';
const {
Mixin,
computed,
} = Ember;
export default Mixin.create({
modelType: computed(function() {
return this.constructor.modelName;
}),
});

View File

@@ -0,0 +1,17 @@
import Ember from 'ember';
import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin';
export default Ember.Mixin.create(UnauthenticatedRouteMixin, {
init() {
this._super(...arguments);
if(this.get('session.fullStoryInitialized')) {
this.teardownFullStoryUser();
}
},
teardownFullStoryUser() {
this.set('session.fullStoryInitialized', false);
},
});

View File

@@ -0,0 +1,38 @@
import Ember from 'ember';
const {
get,
set,
inject: {
service,
},
Mixin
} = Ember;
export default Mixin.create({
ajax: service(),
notifications: service(),
store: service(),
updatePostNotifications(post) {
const ajax = get(this, 'ajax');
if (get(post, 'notifications.reaction') && get(this, 'updateNotifications')) {
const id = get(post, 'id');
const store = get(this, 'store');
ajax
.put(`notifications/post/${id}`)
.then(({ notifications }) => {
notifications.forEach((n) => {
const model = store.peekRecord('notification', n.id);
if(model){
set(model, 'unread', false);
}
});
set(post, 'notifications', {});
});
}
}
});

View File

@@ -0,0 +1,18 @@
import Ember from 'ember';
const {
computed: {
alias
},
inject: {
service
},
Mixin,
} = Ember;
export default Mixin.create({
session: service('session'),
dataStore: service('store'),
screenName: alias('session.actualUser.profile.screenName'),
});