diff --git a/.github/workflows/part-build.yml b/.github/workflows/part-build.yml index 6a3301b1a..4fef696b1 100644 --- a/.github/workflows/part-build.yml +++ b/.github/workflows/part-build.yml @@ -90,6 +90,8 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 + # 2.2 is installed because it is the last version that officially supports DotnetCliToolReference - name: Setup dotnet uses: actions/setup-dotnet@v2 @@ -124,7 +126,8 @@ jobs: steps: - uses: actions/checkout@v3 - + + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 - name: Setup dotnet uses: actions/setup-dotnet@v2 with: @@ -149,6 +152,7 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 - uses: actions/setup-dotnet@v2 with: dotnet-version: | @@ -175,6 +179,7 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 - uses: actions/setup-dotnet@v2 with: dotnet-version: 7.0.x @@ -203,6 +208,8 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 + - run: npm ci - name: npm version @@ -257,6 +264,8 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 + # build coalesce-vue - run: npm run build-local-deps - run: npm ci @@ -293,6 +302,8 @@ jobs: steps: - uses: actions/checkout@v3 + - run: npm i -g npm@9.5.0 # Pin NPM to avoid breaking changes like https://github.com/nodejs/node/issues/46542 + # build coalesce-vue - run: npm run build-local-deps - run: npm ci diff --git a/playground/Coalesce.Web.Ko/Api/Generated/StandaloneReadCreateController.g.cs b/playground/Coalesce.Web.Ko/Api/Generated/StandaloneReadCreateController.g.cs new file mode 100644 index 000000000..b311d9d9b --- /dev/null +++ b/playground/Coalesce.Web.Ko/Api/Generated/StandaloneReadCreateController.g.cs @@ -0,0 +1,73 @@ + +using Coalesce.Web.Ko.Models; +using IntelliTect.Coalesce; +using IntelliTect.Coalesce.Api; +using IntelliTect.Coalesce.Api.Controllers; +using IntelliTect.Coalesce.Api.DataSources; +using IntelliTect.Coalesce.Mapping; +using IntelliTect.Coalesce.Mapping.IncludeTrees; +using IntelliTect.Coalesce.Models; +using IntelliTect.Coalesce.TypeDefinition; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace Coalesce.Web.Ko.Api +{ + [Route("api/StandaloneReadCreate")] + [Authorize] + [ServiceFilter(typeof(IApiActionFilter))] + public partial class StandaloneReadCreateController + : BaseApiController + { + public StandaloneReadCreateController() : base() + { + GeneratedForClassViewModel = ReflectionRepository.Global.GetClassViewModel(); + } + + [HttpGet("get/{id}")] + [Authorize] + public virtual Task> Get( + int id, + DataSourceParameters parameters, + IDataSource dataSource) + => GetImplementation(id, parameters, dataSource); + + [HttpGet("list")] + [Authorize] + public virtual Task> List( + ListParameters parameters, + IDataSource dataSource) + => ListImplementation(parameters, dataSource); + + [HttpGet("count")] + [Authorize] + public virtual Task> Count( + FilterParameters parameters, + IDataSource dataSource) + => CountImplementation(parameters, dataSource); + + [HttpPost("save")] + [Authorize] + public virtual Task> Save( + [FromForm] StandaloneReadCreateDtoGen dto, + [FromQuery] DataSourceParameters parameters, + IDataSource dataSource, + IBehaviors behaviors) + => SaveImplementation(dto, parameters, dataSource, behaviors); + + [HttpPost("delete/{id}")] + [Authorize] + public virtual Task> Delete( + int id, + IBehaviors behaviors, + IDataSource dataSource) + => DeleteImplementation(id, new DataSourceParameters(), dataSource, behaviors); + } +} diff --git a/playground/Coalesce.Web.Ko/Controllers/Generated/StandaloneReadCreateController.g.cs b/playground/Coalesce.Web.Ko/Controllers/Generated/StandaloneReadCreateController.g.cs new file mode 100644 index 000000000..0c84ac83f --- /dev/null +++ b/playground/Coalesce.Web.Ko/Controllers/Generated/StandaloneReadCreateController.g.cs @@ -0,0 +1,42 @@ +using IntelliTect.Coalesce.Knockout.Controllers; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Hosting; + +namespace Coalesce.Web.Ko.Controllers +{ + [Authorize] + public partial class StandaloneReadCreateController : BaseViewController + { + [Authorize] + public ActionResult Cards() + { + return IndexImplementation(false, @"~/Views/Generated/StandaloneReadCreate/Cards.cshtml"); + } + + [Authorize] + public ActionResult Table() + { + return IndexImplementation(false, @"~/Views/Generated/StandaloneReadCreate/Table.cshtml"); + } + + + [Authorize] + public ActionResult TableEdit() + { + return IndexImplementation(true, @"~/Views/Generated/StandaloneReadCreate/Table.cshtml"); + } + + [Authorize] + public ActionResult CreateEdit() + { + return CreateEditImplementation(@"~/Views/Generated/StandaloneReadCreate/CreateEdit.cshtml"); + } + + [Authorize] + public ActionResult EditorHtml(bool simple = false) + { + return EditorHtmlImplementation(simple); + } + } +} diff --git a/playground/Coalesce.Web.Ko/Models/Generated/StandaloneReadCreateDto.g.cs b/playground/Coalesce.Web.Ko/Models/Generated/StandaloneReadCreateDto.g.cs new file mode 100644 index 000000000..8a2d980c9 --- /dev/null +++ b/playground/Coalesce.Web.Ko/Models/Generated/StandaloneReadCreateDto.g.cs @@ -0,0 +1,72 @@ +using IntelliTect.Coalesce; +using IntelliTect.Coalesce.Mapping; +using IntelliTect.Coalesce.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; + +namespace Coalesce.Web.Ko.Models +{ + public partial class StandaloneReadCreateDtoGen : GeneratedDto + { + public StandaloneReadCreateDtoGen() { } + + private int? _Id; + private string _Name; + private System.DateTimeOffset? _Date; + + public int? Id + { + get => _Id; + set { _Id = value; Changed(nameof(Id)); } + } + public string Name + { + get => _Name; + set { _Name = value; Changed(nameof(Name)); } + } + public System.DateTimeOffset? Date + { + get => _Date; + set { _Date = value; Changed(nameof(Date)); } + } + + /// + /// Map from the domain object to the properties of the current DTO instance. + /// + public override void MapFrom(Coalesce.Domain.StandaloneReadCreate obj, IMappingContext context, IncludeTree tree = null) + { + if (obj == null) return; + var includes = context.Includes; + + this.Id = obj.Id; + this.Name = obj.Name; + this.Date = obj.Date; + } + + /// + /// Map from the current DTO instance to the domain object. + /// + public override void MapTo(Coalesce.Domain.StandaloneReadCreate entity, IMappingContext context) + { + var includes = context.Includes; + + if (OnUpdate(entity, context)) return; + + if (ShouldMapTo(nameof(Id))) entity.Id = (Id ?? entity.Id); + if (ShouldMapTo(nameof(Name))) entity.Name = Name; + if (ShouldMapTo(nameof(Date))) entity.Date = (Date ?? entity.Date); + } + + /// + /// Map from the current DTO instance to a new instance of the domain object. + /// + public override Coalesce.Domain.StandaloneReadCreate MapToNew(IMappingContext context) + { + var entity = new Coalesce.Domain.StandaloneReadCreate(); + MapTo(entity, context); + return entity; + } + } +} diff --git a/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreate.g.ts b/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreate.g.ts new file mode 100644 index 000000000..6a875cc8f --- /dev/null +++ b/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreate.g.ts @@ -0,0 +1,118 @@ + +/// + +// Generated by IntelliTect.Coalesce + +module ViewModels { + + export class StandaloneReadCreate extends Coalesce.BaseViewModel { + public readonly modelName = "StandaloneReadCreate"; + public readonly primaryKeyName = "id"; + public readonly modelDisplayName = "Standalone Read Create"; + public readonly apiController = "/StandaloneReadCreate"; + public readonly viewController = "/StandaloneReadCreate"; + + /** Configuration for all instances of StandaloneReadCreate. Can be overidden on each instance via instance.coalesceConfig. */ + public static coalesceConfig: Coalesce.ViewModelConfiguration + = new Coalesce.ViewModelConfiguration(Coalesce.GlobalConfiguration.viewModel); + + /** Configuration for the current StandaloneReadCreate instance. */ + public coalesceConfig: Coalesce.ViewModelConfiguration + = new Coalesce.ViewModelConfiguration(StandaloneReadCreate.coalesceConfig); + + /** The namespace containing all possible values of this.dataSource. */ + public dataSources: typeof ListViewModels.StandaloneReadCreateDataSources = ListViewModels.StandaloneReadCreateDataSources; + + + public id: KnockoutObservable = ko.observable(null); + public name: KnockoutObservable = ko.observable(null); + public date: KnockoutObservable = ko.observable(moment()); + + + + + + + + + /** + Load the ViewModel object from the DTO. + @param data: The incoming data object to load. + @param force: Will override the check against isLoading that is done to prevent recursion. False is default. + @param allowCollectionDeletes: Set true when entire collections are loaded. True is the default. + In some cases only a partial collection is returned, set to false to only add/update collections. + */ + public loadFromDto = (data: any, force: boolean = false, allowCollectionDeletes: boolean = true): void => { + if (!data || (!force && this.isLoading())) return; + this.isLoading(true); + // Set the ID + this.myId = data.id; + this.id(data.id); + // Load the lists of other objects + + // The rest of the objects are loaded now. + this.name(data.name); + if (data.date == null) this.date(null); + else if (this.date() == null || this.date()!.valueOf() != new Date(data.date).getTime()){ + this.date(moment(new Date(data.date))); + } + if (this.coalesceConfig.onLoadFromDto()){ + this.coalesceConfig.onLoadFromDto()(this as any); + } + this.isLoading(false); + this.isDirty(false); + if (this.coalesceConfig.validateOnLoadFromDto()) this.validate(); + }; + + /** Saves this object into a data transfer object to send to the server. */ + public saveToDto = (): any => { + var dto: any = {}; + dto.id = this.id(); + + dto.name = this.name(); + if (!this.date()) dto.date = null; + else dto.date = this.date()!.format('YYYY-MM-DDTHH:mm:ss.SSSZZ'); + + return dto; + } + + /** + Loads any child objects that have an ID set, but not the full object. + This is useful when creating an object that has a parent object and the ID is set on the new child. + */ + public loadChildren = (callback?: () => void): void => { + var loadingCount = 0; + if (loadingCount == 0 && typeof(callback) == "function") { callback(); } + }; + + public setupValidation(): void { + if (this.errors !== null) return; + this.errors = ko.validation.group([ + this.date.extend({ moment: { unix: true } }), + ]); + this.warnings = ko.validation.group([ + ]); + } + + constructor(newItem?: object, parent?: Coalesce.BaseViewModel | ListViewModels.StandaloneReadCreateList) { + super(parent); + this.baseInitialize(); + const self = this; + + + + + + + self.name.subscribe(self.autoSave); + self.date.subscribe(self.autoSave); + + if (newItem) { + self.loadFromDto(newItem, true); + } + } + } + + export namespace StandaloneReadCreate { + } +} diff --git a/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreateList.g.ts b/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreateList.g.ts new file mode 100644 index 000000000..6e4cdb2c6 --- /dev/null +++ b/playground/Coalesce.Web.Ko/Scripts/Generated/Ko.StandaloneReadCreateList.g.ts @@ -0,0 +1,46 @@ + +/// + +// Generated by IntelliTect.Coalesce + +module ListViewModels { + + export namespace StandaloneReadCreateDataSources { + export class Default extends Coalesce.DataSource { } + export class DefaultSource extends Coalesce.DataSource { + } + } + + export class StandaloneReadCreateList extends Coalesce.BaseListViewModel { + public readonly modelName: string = "StandaloneReadCreate"; + public readonly apiController: string = "/StandaloneReadCreate"; + public modelKeyName: string = "id"; + public itemClass: new () => ViewModels.StandaloneReadCreate = ViewModels.StandaloneReadCreate; + + public filter: { + id?: string; + name?: string; + date?: string; + } | null = null; + + /** The namespace containing all possible values of this.dataSource. */ + public dataSources: typeof StandaloneReadCreateDataSources = StandaloneReadCreateDataSources; + + /** The data source on the server to use when retrieving objects. Valid values are in this.dataSources. */ + public dataSource: Coalesce.DataSource = new this.dataSources.Default(); + + /** Configuration for all instances of StandaloneReadCreateList. Can be overidden on each instance via instance.coalesceConfig. */ + public static coalesceConfig = new Coalesce.ListViewModelConfiguration(Coalesce.GlobalConfiguration.listViewModel); + + /** Configuration for this StandaloneReadCreateList instance. */ + public coalesceConfig: Coalesce.ListViewModelConfiguration + = new Coalesce.ListViewModelConfiguration(StandaloneReadCreateList.coalesceConfig); + + + protected createItem = (newItem?: any, parent?: any) => new ViewModels.StandaloneReadCreate(newItem, parent); + + constructor() { + super(); + } + } +} diff --git a/playground/Coalesce.Web.Ko/Scripts/viewmodels.generated.d.ts b/playground/Coalesce.Web.Ko/Scripts/viewmodels.generated.d.ts index 05abc793f..b10af4425 100644 --- a/playground/Coalesce.Web.Ko/Scripts/viewmodels.generated.d.ts +++ b/playground/Coalesce.Web.Ko/Scripts/viewmodels.generated.d.ts @@ -28,6 +28,8 @@ /// /// /// +/// +/// /// /// /// diff --git a/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Cards.cshtml b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Cards.cshtml new file mode 100644 index 000000000..40a6a2352 --- /dev/null +++ b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Cards.cshtml @@ -0,0 +1,125 @@ +@using IntelliTect.Coalesce.Knockout.Helpers + +@{ ViewBag.Fluid = true; } + + + +
+
+
+

+ Standalone Read Create List +

+
+
+
+ + Page + + of + + +
+ + +
+ Create + +
+
+
+ +
+ + +
+ + +@section Scripts +{ + +} diff --git a/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/CreateEdit.cshtml b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/CreateEdit.cshtml new file mode 100644 index 000000000..cf26f4d70 --- /dev/null +++ b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/CreateEdit.cshtml @@ -0,0 +1,75 @@ +@using IntelliTect.Coalesce.Knockout.Helpers + + +
+
+
+ + +
+

Standalone Read Create

+ Loading... +
+
+
+ +
+ +
@(Knockout.InputFor(p => p.Name))
+
+
+ +
@(Knockout.InputFor(p => p.Date))
+
+
+
+
+ + + +@section Scripts +{ + +} diff --git a/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Table.cshtml b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Table.cshtml new file mode 100644 index 000000000..cacaad00d --- /dev/null +++ b/playground/Coalesce.Web.Ko/Views/Generated/StandaloneReadCreate/Table.cshtml @@ -0,0 +1,152 @@ +@using IntelliTect.Coalesce.Knockout.Helpers + +@{ ViewBag.Fluid = true; } + + +
+
+
+

+ Standalone Read Create List +

+
+
+
+ + Page + + of + + +
+ + +
+ Create + + @if (ViewBag.Editable) + { + Make Read-only + } +
+
+
+
+
+
+
+ + + + + + + + + + + @if (@ViewBag.Editable) + { + + + } + else + { + + + } + + + +
+ Name + + + Date + + +
@(Knockout.InputFor(p => p.Name))@(Knockout.InputFor(p => p.Date))@(Knockout.DisplayFor(p => p.Name, true))@(Knockout.DisplayFor(p => p.Date, true)) + +
+ +
+
+
+
+
+
+
+ + +@section Scripts +{ + +} diff --git a/playground/Coalesce.Web.Ko/package-lock.json b/playground/Coalesce.Web.Ko/package-lock.json index d737981dc..ff72af22c 100644 --- a/playground/Coalesce.Web.Ko/package-lock.json +++ b/playground/Coalesce.Web.Ko/package-lock.json @@ -37,6 +37,7 @@ "gulp-typescript": "^6.0.0-alpha.1", "natives": "1.1.6", "sass": "^1.24.5", + "source-map": "0.7.4", "typescript": "4.4.4" } }, @@ -2560,15 +2561,6 @@ "node": ">=0.10.0" } }, - "node_modules/gulp-typescript/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/gulp-typescript/node_modules/through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", @@ -4600,15 +4592,24 @@ "node": ">=0.10.0" } }, - "node_modules/source-map": { + "node_modules/snapdragon/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/source-map-resolve": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", @@ -5267,6 +5268,15 @@ "source-map": "^0.5.1" } }, + "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -7378,12 +7388,6 @@ } } }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", @@ -8929,6 +8933,12 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true } } }, @@ -8975,9 +8985,9 @@ } }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true }, "source-map-resolve": { @@ -9527,6 +9537,14 @@ "dev": true, "requires": { "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } } }, "which": { diff --git a/playground/Coalesce.Web.Ko/package.json b/playground/Coalesce.Web.Ko/package.json index e8b37a0de..6beb4b857 100644 --- a/playground/Coalesce.Web.Ko/package.json +++ b/playground/Coalesce.Web.Ko/package.json @@ -32,7 +32,8 @@ "gulp-typescript": "^6.0.0-alpha.1", "natives": "1.1.6", "sass": "^1.24.5", - "typescript": "4.4.4" + "typescript": "4.4.4", + "source-map": "0.7.4" }, "overrides": { "glob-parent": "^5.1.1"