terrier-engine 4.0.21 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.ts +31 -17
- package/dropdowns.ts +24 -8
- package/forms.ts +33 -0
- package/fragments.ts +9 -7
- package/glyps.ts +2 -2
- package/lightbox.ts +3 -3
- package/modals.ts +4 -3
- package/overlays.ts +100 -33
- package/package.json +1 -1
- package/parts/content-part.ts +188 -0
- package/parts/not-found-page.ts +26 -0
- package/parts/page-part.ts +196 -0
- package/parts/panel-part.ts +47 -0
- package/parts/terrier-part.ts +94 -0
- package/parts/themed-form-part.ts +25 -0
- package/schema.ts +28 -1
- package/toasts.ts +1 -1
- package/parts.ts +0 -485
package/app.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Logger } from "tuff-core/logging"
|
|
2
|
-
import {Part, PartParent} from "tuff-core/parts"
|
|
3
|
-
import
|
|
2
|
+
import {Part, PartConstructor, PartParent} from "tuff-core/parts"
|
|
3
|
+
import TerrierPart from "./parts/terrier-part"
|
|
4
4
|
import Tooltips from "./tooltips"
|
|
5
5
|
import Lightbox from "./lightbox"
|
|
6
|
+
import Theme, {ThemeType} from "./theme"
|
|
7
|
+
import {ModalPart, ModalStackPart} from "./modals"
|
|
8
|
+
import {OverlayLayerType, OverlayPart} from "./overlays"
|
|
6
9
|
|
|
7
10
|
// @ts-ignore
|
|
8
11
|
import logoUrl from './images/optimized/terrier-hub-logo-light.svg'
|
|
9
|
-
import Theme, {ThemeType} from "./theme"
|
|
10
|
-
import {ModalPart, ModalStackPart} from "./modals"
|
|
11
|
-
import {OverlayLayer, OverlayPart} from "./overlays"
|
|
12
12
|
|
|
13
13
|
const log = new Logger('App')
|
|
14
14
|
Logger.level = 'info'
|
|
@@ -50,36 +50,50 @@ export abstract class TerrierApp<
|
|
|
50
50
|
|
|
51
51
|
/// Overlays
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
addOverlay<OverlayType extends Part<StateType>, StateType extends {}>(
|
|
54
54
|
constructor: { new(p: PartParent, id: string, state: StateType): OverlayType; },
|
|
55
55
|
state: StateType,
|
|
56
|
-
|
|
57
|
-
)
|
|
58
|
-
return this.overlayPart.
|
|
56
|
+
type: OverlayLayerType
|
|
57
|
+
) {
|
|
58
|
+
return this.overlayPart.pushLayer(constructor, state, type)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
this.overlayPart.
|
|
63
|
-
|
|
61
|
+
removeOverlay<StateType extends {}>(state: StateType): boolean {
|
|
62
|
+
return this.overlayPart.removeLayer(state)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
popOverlay(type?: OverlayLayerType) {
|
|
66
|
+
this.overlayPart.popLayer(type)
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
clearOverlays() {
|
|
67
70
|
this.overlayPart.clearAll()
|
|
68
71
|
}
|
|
69
72
|
|
|
73
|
+
removeDropdown<StateType extends {}>(state: StateType): boolean {
|
|
74
|
+
this.lastDropdownTarget = undefined
|
|
75
|
+
return this.overlayPart.removeLayer(state)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
clearDropdowns() {
|
|
79
|
+
this.lastDropdownTarget = undefined
|
|
80
|
+
this.popOverlay('dropdown')
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
|
|
71
84
|
lastDropdownTarget?: HTMLElement
|
|
72
85
|
|
|
73
86
|
|
|
74
87
|
/// Modals
|
|
75
88
|
|
|
76
|
-
showModal<ModalType extends ModalPart<StateType, TThemeType, TSelf, TTheme>, StateType>(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
showModal<ModalType extends ModalPart<StateType, TThemeType, TSelf, TTheme>, StateType>(
|
|
90
|
+
constructor: PartConstructor<ModalType, StateType>,
|
|
91
|
+
state: StateType
|
|
92
|
+
): ModalType {
|
|
93
|
+
const modalStack = this.overlayPart.getOrCreateLayer(ModalStackPart, {}, 'modal')
|
|
80
94
|
const modal = modalStack.pushModal(constructor, state)
|
|
81
95
|
modalStack.dirty()
|
|
82
|
-
return modal
|
|
96
|
+
return modal as ModalType
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
|
package/dropdowns.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { untypedKey } from "tuff-core/messages"
|
|
|
3
3
|
import { unique } from "tuff-core/arrays"
|
|
4
4
|
import {PartTag, StatelessPart} from "tuff-core/parts"
|
|
5
5
|
import Overlays from "./overlays"
|
|
6
|
-
import
|
|
6
|
+
import TerrierPart from "./parts/terrier-part"
|
|
7
7
|
import Objects from "tuff-core/objects"
|
|
8
8
|
import Theme, {Action, ThemeType} from "./theme"
|
|
9
|
-
import {TerrierApp} from "./app"
|
|
9
|
+
import {TerrierApp} from "./app"
|
|
10
10
|
|
|
11
11
|
const log = new Logger('Dropdowns')
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ const clearDropdownKey = untypedKey()
|
|
|
17
17
|
* Subclasses must implement the `renderContent()` method to render the dropdown content.
|
|
18
18
|
*/
|
|
19
19
|
export abstract class Dropdown<
|
|
20
|
-
TState,
|
|
20
|
+
TState extends {},
|
|
21
21
|
TThemeType extends ThemeType,
|
|
22
22
|
TApp extends TerrierApp<TThemeType, TApp, TTheme>,
|
|
23
23
|
TTheme extends Theme<TThemeType>
|
|
@@ -29,12 +29,20 @@ export abstract class Dropdown<
|
|
|
29
29
|
return ['tt-dropdown', ...super.parentClasses]
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Override and return true to have the dropdown close when the user clicks anywhere outside of it.
|
|
34
|
+
*/
|
|
35
|
+
get autoClose(): boolean {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
// the computed absolute position of the
|
|
33
40
|
left = 0
|
|
34
41
|
top = 0
|
|
35
42
|
|
|
36
43
|
async init() {
|
|
37
|
-
this.onClick(clearDropdownKey,
|
|
44
|
+
this.onClick(clearDropdownKey, m => {
|
|
45
|
+
log.info("Clearing dropdown", m)
|
|
38
46
|
this.clear()
|
|
39
47
|
})
|
|
40
48
|
}
|
|
@@ -44,11 +52,15 @@ export abstract class Dropdown<
|
|
|
44
52
|
*/
|
|
45
53
|
clear() {
|
|
46
54
|
log.info("Clearing dropdown")
|
|
47
|
-
this.app.
|
|
55
|
+
this.app.removeDropdown(this.state)
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
render(parent: PartTag) {
|
|
51
|
-
|
|
59
|
+
if (this.autoClose) {
|
|
60
|
+
parent.div('.tt-dropdown-backdrop')
|
|
61
|
+
.emitClick(clearDropdownKey)
|
|
62
|
+
}
|
|
63
|
+
parent.div('.tt-dropdown-content', content => {
|
|
52
64
|
this.renderContent(content)
|
|
53
65
|
})
|
|
54
66
|
}
|
|
@@ -71,7 +83,7 @@ export abstract class Dropdown<
|
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
update(_elem: HTMLElement) {
|
|
74
|
-
const content = _elem.querySelector('.dropdown-content')
|
|
86
|
+
const content = _elem.querySelector('.tt-dropdown-content')
|
|
75
87
|
if (this.anchorTarget && content) {
|
|
76
88
|
log.info(`Anchoring dropdown`, content, this.anchorTarget)
|
|
77
89
|
Overlays.anchorElement(content as HTMLElement, this.anchorTarget)
|
|
@@ -91,6 +103,10 @@ export class ActionsDropdown<
|
|
|
91
103
|
> extends Dropdown<Array<Action<TThemeType>>, TThemeType, TApp, TTheme> {
|
|
92
104
|
|
|
93
105
|
|
|
106
|
+
get autoClose(): boolean {
|
|
107
|
+
return true
|
|
108
|
+
}
|
|
109
|
+
|
|
94
110
|
get parentClasses(): Array<string> {
|
|
95
111
|
return ['tt-actions-dropdown', ...super.parentClasses]
|
|
96
112
|
}
|
|
@@ -101,7 +117,7 @@ export class ActionsDropdown<
|
|
|
101
117
|
const keys = unique(this.state.map(action => action.click?.key).filter(Objects.notNull))
|
|
102
118
|
for (const key of keys) {
|
|
103
119
|
this.onClick(key, m => {
|
|
104
|
-
this.
|
|
120
|
+
this.clear()
|
|
105
121
|
log.info(`Re-emitting ${key.id} message`, m, this.parentPart)
|
|
106
122
|
if (this.parentPart) {
|
|
107
123
|
this.parentPart.emit('click', key, m.event, m.data)
|
package/forms.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {SelectOptions} from "tuff-core/forms"
|
|
2
|
+
import {strings} from "tuff-core"
|
|
3
|
+
|
|
4
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
// Options
|
|
6
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Computes a `SelectOptions` array by titleizing the values in a plain string array.
|
|
10
|
+
* @param opts
|
|
11
|
+
*/
|
|
12
|
+
function titleizeOptions(opts: string[], blank?: string): SelectOptions {
|
|
13
|
+
const out = opts.map(c => {
|
|
14
|
+
return {value: c, title: strings.titleize(c)}
|
|
15
|
+
})
|
|
16
|
+
if (blank != undefined) { // don't test length, allow it to be a blank string
|
|
17
|
+
out.unshift({title: blank, value: ''})
|
|
18
|
+
}
|
|
19
|
+
return out
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
24
|
+
// Export
|
|
25
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
26
|
+
|
|
27
|
+
const Forms = {
|
|
28
|
+
titleizeOptions
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default Forms
|
|
32
|
+
|
|
33
|
+
|
package/fragments.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {PartTag} from "tuff-core/parts"
|
|
2
2
|
import {AnchorTagAttrs, HtmlParentTag} from "tuff-core/html"
|
|
3
3
|
import Theme, {Action, Packet, ThemeType} from "./theme"
|
|
4
|
-
import {ActionLevel, PanelActions} from "./parts"
|
|
4
|
+
import {ActionLevel, PanelActions} from "./parts/content-part"
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Base class for Panel and Card fragment builders.
|
|
@@ -102,16 +102,18 @@ export class PanelFragment<TT extends ThemeType> extends ContentFragment<TT> {
|
|
|
102
102
|
* Render the primary and secondary actions to the bottom of a panel
|
|
103
103
|
* @param panel the .panel container
|
|
104
104
|
* @param actions the actions
|
|
105
|
+
* @param theme the theme with which to render actions
|
|
105
106
|
*/
|
|
106
107
|
function panelActions<TT extends ThemeType>(panel: PartTag, actions: PanelActions<TT>, theme: Theme<TT>) {
|
|
107
108
|
if (actions.primary.length || actions.secondary.length) {
|
|
108
109
|
panel.div('.panel-actions', actionsContainer => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
for (const level of ['secondary', 'primary'] as const) {
|
|
111
|
+
const levelActions = actions[level]
|
|
112
|
+
if (!levelActions?.length) continue;
|
|
113
|
+
actionsContainer.div(`.${level}-actions`, container => {
|
|
114
|
+
theme.renderActions(container, levelActions, { iconColor: 'white', defaultClass: level })
|
|
115
|
+
})
|
|
116
|
+
}
|
|
115
117
|
})
|
|
116
118
|
}
|
|
117
119
|
}
|
package/glyps.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// This file was automatically generated by glyps:compile on
|
|
1
|
+
// This file was automatically generated by glyps:compile on 06/01/23 10:19 AM, DO NOT MANUALLY EDIT!
|
|
2
2
|
|
|
3
|
-
const names = ['glyp-abacus', 'glyp-account', 'glyp-accounts_payable', 'glyp-accounts_receivable', 'glyp-action_log', 'glyp-activate', 'glyp-active', 'glyp-activity_high', 'glyp-activity_low', 'glyp-activity_medium', 'glyp-activity_none', 'glyp-address1', 'glyp-adjustment', 'glyp-admin', 'glyp-administration', 'glyp-air_freshener', 'glyp-alert', 'glyp-align_horizontal', 'glyp-align_vertical', 'glyp-anchor', 'glyp-announcement', 'glyp-app_update', 'glyp-append_selection', 'glyp-appointment', 'glyp-appointment_setup', 'glyp-archive', 'glyp-arrow_down', 'glyp-arrow_left', 'glyp-arrow_right', 'glyp-arrow_transfer', 'glyp-arrow_up', 'glyp-ascending', 'glyp-attachment', 'glyp-audit_analyzer', 'glyp-autopay', 'glyp-availability', 'glyp-background_batch', 'glyp-background_job', 'glyp-bait_for_demolition', 'glyp-bar_chart', 'glyp-barcode', 'glyp-bat_exclusion', 'glyp-bed_bug_fumigation', 'glyp-begin_service', 'glyp-belongs_to', 'glyp-billing', 'glyp-billing_office', 'glyp-billing_terms', 'glyp-billto', 'glyp-bioremediation', 'glyp-bird_exclusion', 'glyp-black_light', 'glyp-branch', 'glyp-branch_bats', 'glyp-branch_birds', 'glyp-branch_general', 'glyp-branch_irrigation', 'glyp-branch_landscape', 'glyp-branch_multi_housing', 'glyp-branch_office', 'glyp-branch_orders', 'glyp-branch_residential', 'glyp-branch_sales', 'glyp-branch_termites', 'glyp-branch_weeds', 'glyp-branch_wildlife', 'glyp-build', 'glyp-calculate', 'glyp-calendar', 'glyp-calendar_branch', 'glyp-calendar_map', 'glyp-calendar_rolling', 'glyp-calendar_share', 'glyp-calendar_snap', 'glyp-california', 'glyp-call', 'glyp-callback', 'glyp-camera', 'glyp-cancellation', 'glyp-cancelled', 'glyp-card_american_express', 'glyp-card_discover', 'glyp-card_mastercard', 'glyp-card_visa', 'glyp-catalog', 'glyp-caught', 'glyp-cert', 'glyp-check_all', 'glyp-check_in', 'glyp-check_in_service', 'glyp-checked', 'glyp-checked_empty', 'glyp-checkmark', 'glyp-checkmark_filled', 'glyp-checkout', 'glyp-chemical', 'glyp-chemical_authorization', 'glyp-chemical_backpack_sprayer', 'glyp-chemical_biological_controls', 'glyp-chemical_disinfectant', 'glyp-chemical_fertilizer', 'glyp-chemical_flying_insect_bait', 'glyp-chemical_fumigants', 'glyp-chemical_insect_aerosol', 'glyp-chemical_insect_bait', 'glyp-chemical_insect_dust', 'glyp-chemical_insect_granules', 'glyp-chemical_insect_spray', 'glyp-chemical_label', 'glyp-chemical_mole_bait', 'glyp-chemical_pest_bird_control', 'glyp-chemical_pheromone_products', 'glyp-chemical_power_sprayer', 'glyp-chemical_rodenticide_block', 'glyp-chemical_rodenticide_non_block', 'glyp-chemical_sds', 'glyp-chemical_tree_products', 'glyp-chemical_weed_control', 'glyp-chemical_wildlife_repellents', 'glyp-chemical_wildlife_toxicants', 'glyp-chevron_down', 'glyp-chevron_left', 'glyp-chevron_right', 'glyp-chevron_up', 'glyp-city', 'glyp-click', 'glyp-client_actions', 'glyp-client_pest_sightings', 'glyp-client_required', 'glyp-close', 'glyp-cloud', 'glyp-clypboard', 'glyp-clypedia', 'glyp-clypmart', 'glyp-code', 'glyp-code_details', 'glyp-collections', 'glyp-columns', 'glyp-comment', 'glyp-comment_filled', 'glyp-commission_origin', 'glyp-commissions', 'glyp-company_setup', 'glyp-compass', 'glyp-complete', 'glyp-complete_certificate', 'glyp-complete_enrollment', 'glyp-condition_appliance_machinery', 'glyp-condition_customer', 'glyp-condition_device', 'glyp-condition_door_window', 'glyp-condition_dumpster', 'glyp-condition_entry_point', 'glyp-condition_evidence', 'glyp-condition_exclusion', 'glyp-condition_exterior', 'glyp-condition_interior', 'glyp-condition_plumbing', 'glyp-condition_prep_storage', 'glyp-condition_rodent_evidence', 'glyp-condition_rodent_exclusion', 'glyp-condition_roof_ceiling', 'glyp-condition_structure', 'glyp-condition_supplies', 'glyp-condition_termites', 'glyp-condition_ventilation', 'glyp-condition_wall_floor', 'glyp-condition_wildlife', 'glyp-conditions', 'glyp-consolidate', 'glyp-construction', 'glyp-contract', 'glyp-contract_cancellation', 'glyp-contract_overview', 'glyp-conversation', 'glyp-copesan', 'glyp-copy', 'glyp-credit_memo', 'glyp-credit_non_revenue', 'glyp-credit_production', 'glyp-credit_prospect', 'glyp-credit_sales_bonus', 'glyp-crew', 'glyp-cumulative', 'glyp-cursor', 'glyp-custom_form', 'glyp-customer', 'glyp-customer_service', 'glyp-dashboard', 'glyp-database', 'glyp-dead_animal_removal', 'glyp-default', 'glyp-delete', 'glyp-demo_mode', 'glyp-descending', 'glyp-design', 'glyp-desktop', 'glyp-detail_report', 'glyp-developer', 'glyp-device', 'glyp-device_sync', 'glyp-differential', 'glyp-disable', 'glyp-disabled_filled', 'glyp-distribute_horizontal', 'glyp-distribute_vertical', 'glyp-division', 'glyp-document', 'glyp-documentation', 'glyp-documents', 'glyp-download', 'glyp-driving', 'glyp-duplicate', 'glyp-duplicate_location', 'glyp-duration', 'glyp-edit', 'glyp-email', 'glyp-employment', 'glyp-entertainment_public_venues', 'glyp-equipment_bear_trap', 'glyp-equipment_flying_insect_bait_station', 'glyp-equipment_flying_insect_light_trap', 'glyp-equipment_insect_monitor', 'glyp-equipment_lethal_animal_trap', 'glyp-equipment_live_animal_trap', 'glyp-equipment_live_rodent_trap', 'glyp-equipment_maintenance', 'glyp-equipment_map_viewer', 'glyp-equipment_maps', 'glyp-equipment_mosquito_trap', 'glyp-equipment_other', 'glyp-equipment_pheromone_trap', 'glyp-equipment_pick_up', 'glyp-equipment_rodent_bait', 'glyp-equipment_rodent_trap', 'glyp-equipment_termite_bait_station', 'glyp-equipment_termite_monitor', 'glyp-exclusion', 'glyp-expand', 'glyp-expiring', 'glyp-exterior', 'glyp-extras', 'glyp-facebook', 'glyp-farm', 'glyp-farm_grain_seed', 'glyp-fast_and_frequent', 'glyp-favorite', 'glyp-feedback', 'glyp-field_guide', 'glyp-field_training', 'glyp-file_blank', 'glyp-file_html', 'glyp-file_image', 'glyp-file_pdf', 'glyp-file_printable', 'glyp-file_spreadsheet', 'glyp-file_text', 'glyp-filter', 'glyp-finance', 'glyp-finding', 'glyp-folder', 'glyp-followup', 'glyp-food_bev_pharma', 'glyp-formula', 'glyp-fuel', 'glyp-fumigation', 'glyp-gain_loss', 'glyp-generate_invoices', 'glyp-generate_orders', 'glyp-geo', 'glyp-geo_heat_map', 'glyp-google', 'glyp-google_calendar', 'glyp-government', 'glyp-grain_seed', 'glyp-grid', 'glyp-grouping_combine', 'glyp-grouping_separate', 'glyp-has_many', 'glyp-health_care', 'glyp-heat_map', 'glyp-heat_treatment', 'glyp-help', 'glyp-hidden', 'glyp-honeybee_removal', 'glyp-housing', 'glyp-in_progress', 'glyp-incomplete_certificate', 'glyp-industrial', 'glyp-info', 'glyp-information_technology', 'glyp-inspect_map', 'glyp-inspections', 'glyp-insulation', 'glyp-interior', 'glyp-invoice', 'glyp-invoice_review', 'glyp-irrigation_install', 'glyp-irrigation_maintenance', 'glyp-items', 'glyp-job', 'glyp-justice', 'glyp-k9_inspection', 'glyp-key', 'glyp-label_bottom', 'glyp-label_left', 'glyp-label_right', 'glyp-label_top', 'glyp-labor', 'glyp-landscape', 'glyp-landscape_maintenance', 'glyp-laptop', 'glyp-lead', 'glyp-lead_listing', 'glyp-lead_source', 'glyp-leads_report', 'glyp-learning_hub', 'glyp-ledger', 'glyp-legal', 'glyp-license', 'glyp-lifetime', 'glyp-line_cap_arrow', 'glyp-line_cap_bar', 'glyp-line_cap_circle', 'glyp-line_cap_none', 'glyp-line_caps', 'glyp-line_style', 'glyp-link', 'glyp-location', 'glyp-location_charge', 'glyp-location_credit', 'glyp-location_kind', 'glyp-location_message', 'glyp-location_origin', 'glyp-location_tags', 'glyp-locations', 'glyp-locked', 'glyp-lodging', 'glyp-log_in', 'glyp-log_out', 'glyp-log_report', 'glyp-logbook', 'glyp-logbook_documents', 'glyp-lot_number', 'glyp-manager', 'glyp-map', 'glyp-markdown', 'glyp-market', 'glyp-materials', 'glyp-mattress_encasement', 'glyp-merge', 'glyp-message_billing', 'glyp-message_collections', 'glyp-message_complaint', 'glyp-message_misc', 'glyp-message_technician', 'glyp-messages', 'glyp-misc', 'glyp-miscellaneous', 'glyp-move_order', 'glyp-mowing', 'glyp-multi_housing', 'glyp-mute', 'glyp-navicon', 'glyp-new_location', 'glyp-no_charge', 'glyp-no_service', 'glyp-note', 'glyp-note_access', 'glyp-note_billing', 'glyp-note_collection', 'glyp-note_complaint', 'glyp-note_directions', 'glyp-note_focused', 'glyp-note_office', 'glyp-note_preservice', 'glyp-note_sales', 'glyp-note_service', 'glyp-notification', 'glyp-number', 'glyp-office', 'glyp-office_government', 'glyp-office_training', 'glyp-on_demand', 'glyp-on_demand_order', 'glyp-open', 'glyp-open_invoice', 'glyp-operations', 'glyp-options', 'glyp-order_actions', 'glyp-order_approved', 'glyp-order_batch', 'glyp-order_editor', 'glyp-order_pending', 'glyp-order_series', 'glyp-order_unapproved', 'glyp-org_structure', 'glyp-org_unit', 'glyp-org_unit_settings', 'glyp-origin', 'glyp-origin_client', 'glyp-origin_tech', 'glyp-outlook', 'glyp-overlap', 'glyp-password', 'glyp-past_due', 'glyp-paused', 'glyp-pay_brackets', 'glyp-payment', 'glyp-payment_ach', 'glyp-payment_application_apply', 'glyp-payment_application_correction', 'glyp-payment_application_initial', 'glyp-payment_application_refund', 'glyp-payment_application_transfer', 'glyp-payment_application_unapply', 'glyp-payment_application_unapply_all', 'glyp-payment_applications', 'glyp-payment_batch', 'glyp-payment_cash', 'glyp-payment_check', 'glyp-payment_coupon', 'glyp-payment_credit', 'glyp-payment_discount', 'glyp-payment_eft', 'glyp-payment_finance_charge', 'glyp-payments', 'glyp-payroll', 'glyp-pdf', 'glyp-pending', 'glyp-periodic', 'glyp-periodic_assessment', 'glyp-permission', 'glyp-pest', 'glyp-pest_ants', 'glyp-pest_bats', 'glyp-pest_bed_bugs', 'glyp-pest_birds', 'glyp-pest_crawling_insects', 'glyp-pest_dermestids', 'glyp-pest_fall_invaders', 'glyp-pest_flying_insects', 'glyp-pest_moles', 'glyp-pest_mosquitoes', 'glyp-pest_nuisance_animals', 'glyp-pest_ornamental', 'glyp-pest_ornamental_diseases', 'glyp-pest_roaches', 'glyp-pest_rodents', 'glyp-pest_scorpions', 'glyp-pest_snakes', 'glyp-pest_spiders', 'glyp-pest_stinging_insects', 'glyp-pest_stored_product_pests', 'glyp-pest_ticks_and_fleas', 'glyp-pest_viruses_and_bacteria', 'glyp-pest_weeds', 'glyp-pest_wood_destroyers', 'glyp-phone', 'glyp-pick_date', 'glyp-pick_list', 'glyp-platform_android', 'glyp-platform_ios', 'glyp-platform_macos', 'glyp-platform_windows', 'glyp-play', 'glyp-plus', 'glyp-plus_filled', 'glyp-portal', 'glyp-price_increase', 'glyp-price_increase_alt', 'glyp-pricing_table', 'glyp-print', 'glyp-privacy', 'glyp-product_sale', 'glyp-production', 'glyp-professional_consultation', 'glyp-program', 'glyp-program_elements', 'glyp-program_initiation', 'glyp-program_order', 'glyp-program_review', 'glyp-promo', 'glyp-proposal', 'glyp-protection', 'glyp-purchase_order', 'glyp-quality', 'glyp-radio_checked', 'glyp-radio_empty', 'glyp-reassign', 'glyp-receipt', 'glyp-recent', 'glyp-recommendation', 'glyp-record_details', 'glyp-recurring_revenue', 'glyp-redo', 'glyp-refresh', 'glyp-refund', 'glyp-region', 'glyp-released', 'glyp-remove', 'glyp-renewal', 'glyp-report', 'glyp-required_input', 'glyp-reschedule', 'glyp-restaurant_bar', 'glyp-revenue', 'glyp-review', 'glyp-rfid', 'glyp-ride_along', 'glyp-rodent_exclusion', 'glyp-route_change', 'glyp-route_optimization', 'glyp-rows', 'glyp-ruler', 'glyp-sales', 'glyp-sales_contest', 'glyp-sales_pipeline', 'glyp-sales_tax', 'glyp-sales_tax_exemption', 'glyp-schedule_lock', 'glyp-schedule_lock_afternoon', 'glyp-schedule_lock_day', 'glyp-schedule_lock_exact', 'glyp-schedule_lock_four_hour', 'glyp-schedule_lock_morning', 'glyp-schedule_lock_none', 'glyp-schedule_lock_two_day', 'glyp-schedule_lock_two_hour', 'glyp-schedule_lock_week', 'glyp-schedule_tyoe_every', 'glyp-schedule_type_every', 'glyp-schedule_type_none', 'glyp-schedule_type_on_demand', 'glyp-schedule_type_schedule', 'glyp-scheduled', 'glyp-scheduling', 'glyp-school_church', 'glyp-script', 'glyp-search', 'glyp-seeding', 'glyp-segment', 'glyp-sent', 'glyp-sentricon', 'glyp-service_agreement', 'glyp-service_form', 'glyp-service_miscellaneous', 'glyp-service_reminder', 'glyp-service_report', 'glyp-service_request', 'glyp-services', 'glyp-settings', 'glyp-setup', 'glyp-signature', 'glyp-simulator', 'glyp-site_map', 'glyp-site_map_annotation', 'glyp-site_map_chemical', 'glyp-site_map_edit_details', 'glyp-site_map_edit_geo', 'glyp-site_map_equipment', 'glyp-site_map_exterior', 'glyp-site_map_foundation', 'glyp-site_map_icon', 'glyp-site_map_interior', 'glyp-site_map_label', 'glyp-site_map_perimeter', 'glyp-site_map_settings_left', 'glyp-site_map_settings_right', 'glyp-site_map_template', 'glyp-skip', 'glyp-smart_traps', 'glyp-sms', 'glyp-snow_removal', 'glyp-sort', 'glyp-special', 'glyp-split', 'glyp-spp_scorecard', 'glyp-square_edge', 'glyp-start_sheet', 'glyp-start_time', 'glyp-statement', 'glyp-states', 'glyp-sticky', 'glyp-stop_time', 'glyp-store_material', 'glyp-store_order', 'glyp-store_order_back_order', 'glyp-store_order_cancelled', 'glyp-store_order_complete', 'glyp-store_order_pending', 'glyp-store_order_pending_return', 'glyp-store_order_pre_order', 'glyp-store_order_returned', 'glyp-stores', 'glyp-styling', 'glyp-subscribe', 'glyp-supplemental', 'glyp-support', 'glyp-sync', 'glyp-table', 'glyp-tablet', 'glyp-tablets', 'glyp-tag_manager', 'glyp-tags', 'glyp-task_runs', 'glyp-tech_pest_sightings', 'glyp-technician', 'glyp-technician_approach', 'glyp-template', 'glyp-termite_fumigation', 'glyp-terrier', 'glyp-territory', 'glyp-text', 'glyp-thermometer', 'glyp-third_party_billing', 'glyp-ticket_type', 'glyp-tickets', 'glyp-tidy', 'glyp-time', 'glyp-time_entry', 'glyp-timeline', 'glyp-toolbox', 'glyp-tqi', 'glyp-tracker', 'glyp-tracking', 'glyp-training_course', 'glyp-treatment_split', 'glyp-trends', 'glyp-trip_charge', 'glyp-ui_type', 'glyp-unchecked', 'glyp-undo', 'glyp-unit_sweep', 'glyp-unit_tag', 'glyp-university', 'glyp-unlocked', 'glyp-unscheduled', 'glyp-update_check_positions', 'glyp-upload', 'glyp-user', 'glyp-user_credit', 'glyp-user_tags', 'glyp-users', 'glyp-utility', 'glyp-vacation', 'glyp-vacuum', 'glyp-variant', 'glyp-vendor', 'glyp-versions', 'glyp-video', 'glyp-visible', 'glyp-warehouse', 'glyp-wdo', 'glyp-web_dusting', 'glyp-website', 'glyp-wildlife', 'glyp-wildlife_exclusion', 'glyp-winter_check', 'glyp-wizard', 'glyp-work', 'glyp-work_class', 'glyp-work_code', 'glyp-work_order', 'glyp-work_production', 'glyp-work_progress', 'glyp-work_yield', 'glyp-year', 'glyp-yield', 'glyp-zip_code', 'glyp-zone_adjacent', 'glyp-zone_check', 'glyp-zone_production', 'glyp-zone_remote', 'glyp-zoom_fit'] as const
|
|
3
|
+
const names = ['glyp-abacus', 'glyp-account', 'glyp-accounts_payable', 'glyp-accounts_receivable', 'glyp-action_log', 'glyp-activate', 'glyp-active', 'glyp-activity_high', 'glyp-activity_low', 'glyp-activity_medium', 'glyp-activity_none', 'glyp-address1', 'glyp-adjustment', 'glyp-admin', 'glyp-administration', 'glyp-air_freshener', 'glyp-alert', 'glyp-align_horizontal', 'glyp-align_vertical', 'glyp-anchor', 'glyp-announcement', 'glyp-app_update', 'glyp-append_selection', 'glyp-appointment', 'glyp-appointment_setup', 'glyp-archive', 'glyp-arrow_down', 'glyp-arrow_left', 'glyp-arrow_right', 'glyp-arrow_transfer', 'glyp-arrow_up', 'glyp-ascending', 'glyp-attachment', 'glyp-audit_analyzer', 'glyp-autopay', 'glyp-availability', 'glyp-background_batch', 'glyp-background_job', 'glyp-bait_for_demolition', 'glyp-bar_chart', 'glyp-barcode', 'glyp-bat_exclusion', 'glyp-bed_bug_fumigation', 'glyp-begin_service', 'glyp-belongs_to', 'glyp-billing', 'glyp-billing_office', 'glyp-billing_terms', 'glyp-billto', 'glyp-bioremediation', 'glyp-bird_exclusion', 'glyp-black_light', 'glyp-branch', 'glyp-branch_bats', 'glyp-branch_birds', 'glyp-branch_general', 'glyp-branch_irrigation', 'glyp-branch_landscape', 'glyp-branch_multi_housing', 'glyp-branch_office', 'glyp-branch_orders', 'glyp-branch_residential', 'glyp-branch_sales', 'glyp-branch_termites', 'glyp-branch_weeds', 'glyp-branch_wildlife', 'glyp-build', 'glyp-calculate', 'glyp-calendar', 'glyp-calendar_branch', 'glyp-calendar_map', 'glyp-calendar_rolling', 'glyp-calendar_share', 'glyp-calendar_snap', 'glyp-california', 'glyp-call', 'glyp-callback', 'glyp-camera', 'glyp-cancellation', 'glyp-cancelled', 'glyp-card_american_express', 'glyp-card_discover', 'glyp-card_mastercard', 'glyp-card_visa', 'glyp-catalog', 'glyp-caught', 'glyp-cert', 'glyp-check_all', 'glyp-check_in', 'glyp-check_in_service', 'glyp-checked', 'glyp-checked_empty', 'glyp-checkmark', 'glyp-checkmark_filled', 'glyp-checkout', 'glyp-chemical', 'glyp-chemical_authorization', 'glyp-chemical_backpack_sprayer', 'glyp-chemical_biological_controls', 'glyp-chemical_disinfectant', 'glyp-chemical_fertilizer', 'glyp-chemical_flying_insect_bait', 'glyp-chemical_fumigants', 'glyp-chemical_insect_aerosol', 'glyp-chemical_insect_bait', 'glyp-chemical_insect_dust', 'glyp-chemical_insect_granules', 'glyp-chemical_insect_spray', 'glyp-chemical_label', 'glyp-chemical_mole_bait', 'glyp-chemical_pest_bird_control', 'glyp-chemical_pheromone_products', 'glyp-chemical_power_sprayer', 'glyp-chemical_rodenticide_block', 'glyp-chemical_rodenticide_non_block', 'glyp-chemical_sds', 'glyp-chemical_tree_products', 'glyp-chemical_weed_control', 'glyp-chemical_wildlife_repellents', 'glyp-chemical_wildlife_toxicants', 'glyp-chevron_down', 'glyp-chevron_left', 'glyp-chevron_right', 'glyp-chevron_up', 'glyp-city', 'glyp-click', 'glyp-client_actions', 'glyp-client_pest_sightings', 'glyp-client_required', 'glyp-close', 'glyp-cloud', 'glyp-clypboard', 'glyp-clypedia', 'glyp-clypmart', 'glyp-code', 'glyp-code_details', 'glyp-collections', 'glyp-columns', 'glyp-comment', 'glyp-comment_filled', 'glyp-commission_origin', 'glyp-commissions', 'glyp-company_setup', 'glyp-compass', 'glyp-complete', 'glyp-complete_certificate', 'glyp-complete_enrollment', 'glyp-condition_appliance_machinery', 'glyp-condition_customer', 'glyp-condition_device', 'glyp-condition_door_window', 'glyp-condition_dumpster', 'glyp-condition_entry_point', 'glyp-condition_evidence', 'glyp-condition_exclusion', 'glyp-condition_exterior', 'glyp-condition_interior', 'glyp-condition_plumbing', 'glyp-condition_prep_storage', 'glyp-condition_rodent_evidence', 'glyp-condition_rodent_exclusion', 'glyp-condition_roof_ceiling', 'glyp-condition_structure', 'glyp-condition_supplies', 'glyp-condition_termites', 'glyp-condition_ventilation', 'glyp-condition_wall_floor', 'glyp-condition_wildlife', 'glyp-conditions', 'glyp-consolidate', 'glyp-construction', 'glyp-contract', 'glyp-contract_cancellation', 'glyp-contract_overview', 'glyp-conversation', 'glyp-copesan', 'glyp-copy', 'glyp-credit_memo', 'glyp-credit_non_revenue', 'glyp-credit_production', 'glyp-credit_prospect', 'glyp-credit_sales_bonus', 'glyp-crew', 'glyp-cumulative', 'glyp-cursor', 'glyp-custom_form', 'glyp-customer', 'glyp-customer_service', 'glyp-dashboard', 'glyp-database', 'glyp-dead_animal_removal', 'glyp-default', 'glyp-delete', 'glyp-demo_mode', 'glyp-descending', 'glyp-design', 'glyp-desktop', 'glyp-detail_report', 'glyp-developer', 'glyp-device', 'glyp-device_sync', 'glyp-differential', 'glyp-disable', 'glyp-disabled_filled', 'glyp-distribute_horizontal', 'glyp-distribute_vertical', 'glyp-division', 'glyp-document', 'glyp-documentation', 'glyp-documents', 'glyp-download', 'glyp-driving', 'glyp-duplicate', 'glyp-duplicate_location', 'glyp-duration', 'glyp-edit', 'glyp-email', 'glyp-employment', 'glyp-entertainment_public_venues', 'glyp-equipment_bear_trap', 'glyp-equipment_flying_insect_bait_station', 'glyp-equipment_flying_insect_light_trap', 'glyp-equipment_insect_monitor', 'glyp-equipment_lethal_animal_trap', 'glyp-equipment_live_animal_trap', 'glyp-equipment_live_rodent_trap', 'glyp-equipment_maintenance', 'glyp-equipment_map_viewer', 'glyp-equipment_maps', 'glyp-equipment_mosquito_trap', 'glyp-equipment_other', 'glyp-equipment_pheromone_trap', 'glyp-equipment_pick_up', 'glyp-equipment_rodent_bait', 'glyp-equipment_rodent_trap', 'glyp-equipment_termite_bait_station', 'glyp-equipment_termite_monitor', 'glyp-exclusion', 'glyp-expand', 'glyp-expiring', 'glyp-exterior', 'glyp-extras', 'glyp-facebook', 'glyp-farm', 'glyp-farm_grain_seed', 'glyp-fast_and_frequent', 'glyp-favorite', 'glyp-feedback', 'glyp-field_guide', 'glyp-field_training', 'glyp-file_blank', 'glyp-file_html', 'glyp-file_image', 'glyp-file_pdf', 'glyp-file_printable', 'glyp-file_spreadsheet', 'glyp-file_text', 'glyp-filter', 'glyp-finance', 'glyp-finding', 'glyp-folder', 'glyp-followup', 'glyp-food_bev_pharma', 'glyp-formula', 'glyp-fuel', 'glyp-fumigation', 'glyp-gain_loss', 'glyp-generate_invoices', 'glyp-generate_orders', 'glyp-geo', 'glyp-geo_heat_map', 'glyp-google', 'glyp-google_calendar', 'glyp-government', 'glyp-grain_seed', 'glyp-grid', 'glyp-grouping_combine', 'glyp-grouping_separate', 'glyp-has_many', 'glyp-health_care', 'glyp-heat_map', 'glyp-heat_treatment', 'glyp-help', 'glyp-hidden', 'glyp-honeybee_removal', 'glyp-housing', 'glyp-in_progress', 'glyp-incomplete_certificate', 'glyp-industrial', 'glyp-info', 'glyp-information_technology', 'glyp-inspect_map', 'glyp-inspections', 'glyp-insulation', 'glyp-interior', 'glyp-invoice', 'glyp-invoice_review', 'glyp-irrigation_install', 'glyp-irrigation_maintenance', 'glyp-items', 'glyp-job', 'glyp-join', 'glyp-join_inner', 'glyp-join_left', 'glyp-justice', 'glyp-k9_inspection', 'glyp-key', 'glyp-label_bottom', 'glyp-label_left', 'glyp-label_right', 'glyp-label_top', 'glyp-labor', 'glyp-landscape', 'glyp-landscape_maintenance', 'glyp-laptop', 'glyp-lead', 'glyp-lead_listing', 'glyp-lead_source', 'glyp-leads_report', 'glyp-learning_hub', 'glyp-ledger', 'glyp-legal', 'glyp-license', 'glyp-lifetime', 'glyp-line_cap_arrow', 'glyp-line_cap_bar', 'glyp-line_cap_circle', 'glyp-line_cap_none', 'glyp-line_caps', 'glyp-line_style', 'glyp-link', 'glyp-location', 'glyp-location_charge', 'glyp-location_credit', 'glyp-location_kind', 'glyp-location_message', 'glyp-location_origin', 'glyp-location_tags', 'glyp-locations', 'glyp-locked', 'glyp-lodging', 'glyp-log_in', 'glyp-log_out', 'glyp-log_report', 'glyp-logbook', 'glyp-logbook_documents', 'glyp-lot_number', 'glyp-manager', 'glyp-map', 'glyp-markdown', 'glyp-market', 'glyp-materials', 'glyp-mattress_encasement', 'glyp-merge', 'glyp-message_billing', 'glyp-message_collections', 'glyp-message_complaint', 'glyp-message_misc', 'glyp-message_technician', 'glyp-messages', 'glyp-misc', 'glyp-miscellaneous', 'glyp-move_order', 'glyp-mowing', 'glyp-multi_housing', 'glyp-mute', 'glyp-navicon', 'glyp-new_location', 'glyp-no_charge', 'glyp-no_service', 'glyp-note', 'glyp-note_access', 'glyp-note_billing', 'glyp-note_collection', 'glyp-note_complaint', 'glyp-note_directions', 'glyp-note_focused', 'glyp-note_office', 'glyp-note_preservice', 'glyp-note_sales', 'glyp-note_service', 'glyp-notification', 'glyp-number', 'glyp-office', 'glyp-office_government', 'glyp-office_training', 'glyp-on_demand', 'glyp-on_demand_order', 'glyp-open', 'glyp-open_invoice', 'glyp-operations', 'glyp-options', 'glyp-order_actions', 'glyp-order_approved', 'glyp-order_batch', 'glyp-order_editor', 'glyp-order_pending', 'glyp-order_series', 'glyp-order_unapproved', 'glyp-org_structure', 'glyp-org_unit', 'glyp-org_unit_settings', 'glyp-origin', 'glyp-origin_client', 'glyp-origin_tech', 'glyp-outlook', 'glyp-overlap', 'glyp-password', 'glyp-past_due', 'glyp-paused', 'glyp-pay_brackets', 'glyp-payment', 'glyp-payment_ach', 'glyp-payment_application_apply', 'glyp-payment_application_correction', 'glyp-payment_application_initial', 'glyp-payment_application_refund', 'glyp-payment_application_transfer', 'glyp-payment_application_unapply', 'glyp-payment_application_unapply_all', 'glyp-payment_applications', 'glyp-payment_batch', 'glyp-payment_cash', 'glyp-payment_check', 'glyp-payment_coupon', 'glyp-payment_credit', 'glyp-payment_discount', 'glyp-payment_eft', 'glyp-payment_finance_charge', 'glyp-payments', 'glyp-payroll', 'glyp-pdf', 'glyp-pending', 'glyp-periodic', 'glyp-periodic_assessment', 'glyp-permission', 'glyp-pest', 'glyp-pest_ants', 'glyp-pest_bats', 'glyp-pest_bed_bugs', 'glyp-pest_birds', 'glyp-pest_crawling_insects', 'glyp-pest_dermestids', 'glyp-pest_fall_invaders', 'glyp-pest_flying_insects', 'glyp-pest_moles', 'glyp-pest_mosquitoes', 'glyp-pest_nuisance_animals', 'glyp-pest_ornamental', 'glyp-pest_ornamental_diseases', 'glyp-pest_roaches', 'glyp-pest_rodents', 'glyp-pest_scorpions', 'glyp-pest_snakes', 'glyp-pest_spiders', 'glyp-pest_stinging_insects', 'glyp-pest_stored_product_pests', 'glyp-pest_ticks_and_fleas', 'glyp-pest_viruses_and_bacteria', 'glyp-pest_weeds', 'glyp-pest_wood_destroyers', 'glyp-phone', 'glyp-pick_date', 'glyp-pick_list', 'glyp-platform_android', 'glyp-platform_ios', 'glyp-platform_macos', 'glyp-platform_windows', 'glyp-play', 'glyp-plus', 'glyp-plus_filled', 'glyp-portal', 'glyp-price_increase', 'glyp-price_increase_alt', 'glyp-pricing_table', 'glyp-print', 'glyp-privacy', 'glyp-product_sale', 'glyp-production', 'glyp-professional_consultation', 'glyp-program', 'glyp-program_elements', 'glyp-program_initiation', 'glyp-program_order', 'glyp-program_review', 'glyp-promo', 'glyp-proposal', 'glyp-protection', 'glyp-purchase_order', 'glyp-quality', 'glyp-radio_checked', 'glyp-radio_empty', 'glyp-reassign', 'glyp-receipt', 'glyp-recent', 'glyp-recommendation', 'glyp-record_details', 'glyp-recurring_revenue', 'glyp-redo', 'glyp-refresh', 'glyp-refund', 'glyp-region', 'glyp-released', 'glyp-remove', 'glyp-renewal', 'glyp-report', 'glyp-required_input', 'glyp-reschedule', 'glyp-restaurant_bar', 'glyp-revenue', 'glyp-review', 'glyp-rfid', 'glyp-ride_along', 'glyp-rodent_exclusion', 'glyp-route_change', 'glyp-route_optimization', 'glyp-rows', 'glyp-ruler', 'glyp-sales', 'glyp-sales_contest', 'glyp-sales_pipeline', 'glyp-sales_tax', 'glyp-sales_tax_exemption', 'glyp-schedule_lock', 'glyp-schedule_lock_afternoon', 'glyp-schedule_lock_day', 'glyp-schedule_lock_exact', 'glyp-schedule_lock_four_hour', 'glyp-schedule_lock_morning', 'glyp-schedule_lock_none', 'glyp-schedule_lock_two_day', 'glyp-schedule_lock_two_hour', 'glyp-schedule_lock_week', 'glyp-schedule_tyoe_every', 'glyp-schedule_type_every', 'glyp-schedule_type_none', 'glyp-schedule_type_on_demand', 'glyp-schedule_type_schedule', 'glyp-scheduled', 'glyp-scheduling', 'glyp-school_church', 'glyp-script', 'glyp-search', 'glyp-seeding', 'glyp-segment', 'glyp-sent', 'glyp-sentricon', 'glyp-service_agreement', 'glyp-service_form', 'glyp-service_miscellaneous', 'glyp-service_reminder', 'glyp-service_report', 'glyp-service_request', 'glyp-services', 'glyp-settings', 'glyp-setup', 'glyp-signature', 'glyp-simulator', 'glyp-site_map', 'glyp-site_map_annotation', 'glyp-site_map_chemical', 'glyp-site_map_edit_details', 'glyp-site_map_edit_geo', 'glyp-site_map_equipment', 'glyp-site_map_exterior', 'glyp-site_map_foundation', 'glyp-site_map_icon', 'glyp-site_map_interior', 'glyp-site_map_label', 'glyp-site_map_perimeter', 'glyp-site_map_settings_left', 'glyp-site_map_settings_right', 'glyp-site_map_template', 'glyp-skip', 'glyp-smart_traps', 'glyp-sms', 'glyp-snow_removal', 'glyp-sort', 'glyp-special', 'glyp-split', 'glyp-spp_scorecard', 'glyp-square_edge', 'glyp-start_sheet', 'glyp-start_time', 'glyp-statement', 'glyp-states', 'glyp-sticky', 'glyp-stop_time', 'glyp-store_material', 'glyp-store_order', 'glyp-store_order_back_order', 'glyp-store_order_cancelled', 'glyp-store_order_complete', 'glyp-store_order_pending', 'glyp-store_order_pending_return', 'glyp-store_order_pre_order', 'glyp-store_order_returned', 'glyp-stores', 'glyp-styling', 'glyp-subscribe', 'glyp-supplemental', 'glyp-support', 'glyp-sync', 'glyp-table', 'glyp-tablet', 'glyp-tablets', 'glyp-tag_manager', 'glyp-tags', 'glyp-task_runs', 'glyp-tech_pest_sightings', 'glyp-technician', 'glyp-technician_approach', 'glyp-template', 'glyp-termite_fumigation', 'glyp-terrier', 'glyp-territory', 'glyp-text', 'glyp-thermometer', 'glyp-third_party_billing', 'glyp-ticket_type', 'glyp-tickets', 'glyp-tidy', 'glyp-time', 'glyp-time_entry', 'glyp-timeline', 'glyp-toolbox', 'glyp-tqi', 'glyp-tracker', 'glyp-tracking', 'glyp-training_course', 'glyp-treatment_split', 'glyp-trends', 'glyp-trip_charge', 'glyp-ui_type', 'glyp-unchecked', 'glyp-undo', 'glyp-unit_sweep', 'glyp-unit_tag', 'glyp-university', 'glyp-unlocked', 'glyp-unscheduled', 'glyp-update_check_positions', 'glyp-upload', 'glyp-user', 'glyp-user_credit', 'glyp-user_tags', 'glyp-users', 'glyp-utility', 'glyp-vacation', 'glyp-vacuum', 'glyp-variant', 'glyp-vendor', 'glyp-versions', 'glyp-video', 'glyp-visible', 'glyp-warehouse', 'glyp-wdo', 'glyp-web_dusting', 'glyp-website', 'glyp-wildlife', 'glyp-wildlife_exclusion', 'glyp-winter_check', 'glyp-wizard', 'glyp-work', 'glyp-work_class', 'glyp-work_code', 'glyp-work_order', 'glyp-work_production', 'glyp-work_progress', 'glyp-work_yield', 'glyp-year', 'glyp-yield', 'glyp-zip_code', 'glyp-zone_adjacent', 'glyp-zone_check', 'glyp-zone_production', 'glyp-zone_remote', 'glyp-zoom_fit'] as const
|
|
4
4
|
|
|
5
5
|
const Glyps = {
|
|
6
6
|
names
|
package/lightbox.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Logger } from "tuff-core/logging"
|
|
|
2
2
|
import { untypedKey } from "tuff-core/messages"
|
|
3
3
|
import {Part, PartTag} from "tuff-core/parts"
|
|
4
4
|
import {TerrierApp} from "./app"
|
|
5
|
-
import Theme, {ThemeType} from "./theme"
|
|
5
|
+
import Theme, {ThemeType} from "./theme"
|
|
6
6
|
|
|
7
7
|
const log = new Logger('Lightbox')
|
|
8
8
|
|
|
@@ -58,7 +58,7 @@ function showPart<
|
|
|
58
58
|
TApp extends TerrierApp<TT,TApp, TTheme>,
|
|
59
59
|
TTheme extends Theme<TT>
|
|
60
60
|
>(app: TApp, state: LightboxState) {
|
|
61
|
-
app.
|
|
61
|
+
app.addOverlay(LightboxPart, {app,...state}, 'lightbox')
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const closeKey = untypedKey()
|
|
@@ -91,7 +91,7 @@ class LightboxPart<
|
|
|
91
91
|
close() {
|
|
92
92
|
this.element?.classList.remove('active')
|
|
93
93
|
setTimeout(_ => {
|
|
94
|
-
this.state.app.
|
|
94
|
+
this.state.app.removeOverlay(this.state)
|
|
95
95
|
}, 500)
|
|
96
96
|
}
|
|
97
97
|
}
|
package/modals.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Logger } from "tuff-core/logging"
|
|
2
2
|
import { untypedKey } from "tuff-core/messages"
|
|
3
|
-
import
|
|
3
|
+
import TerrierPart from "./parts/terrier-part"
|
|
4
4
|
import {PartConstructor, PartTag} from "tuff-core/parts"
|
|
5
|
-
import Theme, {ThemeType} from "./theme"
|
|
6
|
-
import {TerrierApp} from "./app"
|
|
5
|
+
import Theme, {ThemeType} from "./theme"
|
|
6
|
+
import {TerrierApp} from "./app"
|
|
7
|
+
import ContentPart from "./parts/content-part"
|
|
7
8
|
|
|
8
9
|
const log = new Logger('Modals')
|
|
9
10
|
|
package/overlays.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Part, PartTag, StatelessPart, NoState, PartConstructor} from "tuff-core/parts"
|
|
2
2
|
import { Size, Box, Side } from "tuff-core/box"
|
|
3
3
|
import { Logger } from "tuff-core/logging"
|
|
4
|
+
import {arrays} from "tuff-core";
|
|
4
5
|
|
|
5
6
|
const log = new Logger('Overlays')
|
|
6
7
|
|
|
@@ -8,67 +9,133 @@ const log = new Logger('Overlays')
|
|
|
8
9
|
// Part
|
|
9
10
|
////////////////////////////////////////////////////////////////////////////////
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const OverlayLayerTypes = ['modal', 'dropdown', 'lightbox', 'jump'] as const
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
-
* There can only be one part per layer.
|
|
15
|
+
* The type of overlay for any given layer.
|
|
16
16
|
*/
|
|
17
|
-
export type
|
|
17
|
+
export type OverlayLayerType = typeof OverlayLayerTypes[number]
|
|
18
18
|
|
|
19
19
|
export class OverlayPart extends Part<NoState> {
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
layerStates: OverlayLayerState<any, any>[] = []
|
|
22
|
+
|
|
23
|
+
updateLayers(): StatelessPart[] {
|
|
24
|
+
return this.assignCollection('layers', OverlayLayer, this.layerStates)
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
/**
|
|
24
|
-
* Creates a part
|
|
25
|
-
* Discards the old part at that layer, if there was one.
|
|
28
|
+
* Creates a part and pushes it onto the overlay stack.
|
|
26
29
|
* @param constructor
|
|
27
30
|
* @param state
|
|
28
|
-
* @param
|
|
31
|
+
* @param type
|
|
32
|
+
* @return the new part
|
|
29
33
|
*/
|
|
30
|
-
|
|
31
|
-
constructor:
|
|
34
|
+
pushLayer<PartType extends Part<StateType>, StateType extends {}>(
|
|
35
|
+
constructor: PartConstructor<PartType, StateType>,
|
|
32
36
|
state: StateType,
|
|
33
|
-
|
|
37
|
+
type: OverlayLayerType
|
|
34
38
|
): PartType {
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
return part
|
|
39
|
+
this.layerStates.push({partClass: constructor, partState: state, type})
|
|
40
|
+
const parts = this.updateLayers()
|
|
41
|
+
return (parts[parts.length-1] as OverlayLayer<PartType, StateType>).part as PartType
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
43
|
-
* @param
|
|
45
|
+
* Same as `pushLayer`, except that it will re-use the first existing layer of the given type, if present.
|
|
46
|
+
* @param constructor
|
|
47
|
+
* @param state
|
|
48
|
+
* @param type
|
|
49
|
+
* @return the new or existing part
|
|
44
50
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
getOrCreateLayer<PartType extends Part<StateType>, StateType extends {}>(
|
|
52
|
+
constructor: PartConstructor<PartType, StateType>,
|
|
53
|
+
state: StateType,
|
|
54
|
+
type: OverlayLayerType
|
|
55
|
+
): PartType {
|
|
56
|
+
const layers = this.getCollectionParts('layers')
|
|
57
|
+
for (const layer of layers) {
|
|
58
|
+
if (layer.state.type == type) {
|
|
59
|
+
return (layer as OverlayLayer<PartType, StateType>).part as PartType
|
|
60
|
+
}
|
|
50
61
|
}
|
|
51
|
-
this.
|
|
62
|
+
const part = this.pushLayer(constructor, state, type)
|
|
63
|
+
return part as PartType
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
/**
|
|
55
|
-
*
|
|
67
|
+
* Pops the top layer off the overlay stack.
|
|
68
|
+
* @return the part that was popped, if there was one.
|
|
56
69
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
popLayer(type?: OverlayLayerType): StatelessPart | undefined {
|
|
71
|
+
const oldParts = this.getCollectionParts('layers')
|
|
72
|
+
if (type) {
|
|
73
|
+
for (let i = this.layerStates.length-1; i>=0; i--) {
|
|
74
|
+
if (this.layerStates[i].type == type) {
|
|
75
|
+
const part = oldParts[i]
|
|
76
|
+
this.layerStates = arrays.without(this.layerStates, this.layerStates[i])
|
|
77
|
+
this.updateLayers()
|
|
78
|
+
return part
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return undefined
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// no type specified, pop the top one
|
|
85
|
+
this.layerStates = this.layerStates.slice(0, this.layerStates.length - 1)
|
|
86
|
+
this.updateLayers()
|
|
87
|
+
return oldParts[oldParts.length - 1]
|
|
60
88
|
}
|
|
61
89
|
}
|
|
62
90
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Removes the layer with the given state from the stack.
|
|
93
|
+
* @param state
|
|
94
|
+
* @return true if there was a layer actually removed
|
|
95
|
+
*/
|
|
96
|
+
removeLayer<StateType extends {}>(state: StateType): boolean {
|
|
97
|
+
for (const layerState of this.layerStates) {
|
|
98
|
+
if (layerState.partState == state) {
|
|
99
|
+
this.layerStates = arrays.without(this.layerStates, layerState)
|
|
100
|
+
this.updateLayers()
|
|
101
|
+
return true
|
|
68
102
|
}
|
|
69
103
|
}
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Clear all overlay layers.
|
|
109
|
+
*/
|
|
110
|
+
clearAll() {
|
|
111
|
+
this.layerStates = []
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
render(parent: PartTag) {
|
|
115
|
+
this.renderCollection(parent, 'layers')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
type OverlayLayerState<PartType extends Part<StateType>, StateType extends {}> = {
|
|
121
|
+
partClass: PartConstructor<PartType, StateType>
|
|
122
|
+
partState: StateType
|
|
123
|
+
type: OverlayLayerType
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
class OverlayLayer<PartType extends Part<StateType>, StateType extends {}> extends Part<OverlayLayerState<PartType, StateType>> {
|
|
127
|
+
|
|
128
|
+
part!: PartType
|
|
129
|
+
|
|
130
|
+
async init() {
|
|
131
|
+
this.part = this.makePart(this.state.partClass, this.state.partState)
|
|
70
132
|
}
|
|
71
133
|
|
|
134
|
+
render(parent: PartTag) {
|
|
135
|
+
parent.part(this.part)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
72
139
|
}
|
|
73
140
|
|
|
74
141
|
|