/* * This file belongs to Hoist, an application development toolkit * developed by Extremely Heavy Industries (www.xh.io | info@xh.io) * * Copyright © 2026 Extremely Heavy Industries Inc. */ import {FormModel} from '@xh/hoist/cmp/form'; import {fragment, p, strong} from '@xh/hoist/cmp/layout'; import {ViewManagerModel} from '@xh/hoist/cmp/viewmanager'; import {HoistModel, managed, XH} from '@xh/hoist/core'; import {action, makeObservable, observable} from '@xh/hoist/mobx'; import {some} from 'lodash'; /** * Backing model for ViewManagerModel's SaveAs */ export class SaveAsDialogModel extends HoistModel { readonly parent: ViewManagerModel; @managed readonly formModel: FormModel; @observable isOpen: boolean = false; constructor(parent: ViewManagerModel) { super(); makeObservable(this); this.parent = parent; this.formModel = this.createFormModel(); } @action open() { const {parent, formModel} = this, src = parent.view, name = some(parent.ownedViews, {name: src.name}) ? `Copy of ${src.name}` : src.name; formModel.init({ name, group: src.group, // Do not copy description or visibility from source view description: null, visibility: 'private', isPinned: !!src.info?.isPinned }); this.isOpen = true; } @action close() { this.isOpen = false; } async saveAsAsync() { try { await this.doSaveAsAsync().linkTo(this.parent.saveTask); } catch (e) { XH.handleException(e); } } //------------------------ // Implementation //------------------------ private createFormModel(): FormModel { return new FormModel({ fields: [ { name: 'name', rules: [ ({value}, {visibility}) => { return this.parent.validateViewNameAsync( value, null, visibility === 'global' ); } ] }, {name: 'group'}, {name: 'description'}, {name: 'visibility'} ] }); } private async doSaveAsAsync() { let {formModel, parent} = this, {typeDisplayName, globalDisplayName} = parent, {name, group, description, visibility} = formModel.getData(), isValid = await formModel.validateAsync(), isGlobal = visibility === 'global', isShared = visibility === 'shared'; if (!isValid) return; if (isGlobal) { const confirmed = await XH.confirm({ message: fragment( p( `This ${typeDisplayName} will become a ${globalDisplayName} ${typeDisplayName} visible to all other ${XH.appName} users.` ), p(strong('Are you sure you want to proceed?')) ), confirmProps: { text: `Yes, save ${globalDisplayName} ${typeDisplayName}`, outlined: true, autoFocus: false, intent: 'primary' } }); if (!confirmed) return; } await parent.saveAsAsync({ name: name.trim(), group: group?.trim(), description: description?.trim(), isGlobal, isShared, value: parent.getValue() }); this.close(); } }