diff --git a/changelog.md b/changelog.md index 7c6f724255..3d291fcf6d 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,10 @@ ## 0.6.32 (upcoming) +Tracker: + +- Basic sprints + ## 0.6.31 Core: diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 7f1dd7e713..9f3b4e18c1 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -118,7 +118,6 @@ specifiers: '@rush-temp/preference-assets': file:./projects/preference-assets.tgz '@rush-temp/presentation': file:./projects/presentation.tgz '@rush-temp/prod': file:./projects/prod.tgz - '@rush-temp/prod-tracker': file:./projects/prod-tracker.tgz '@rush-temp/query': file:./projects/query.tgz '@rush-temp/recruit': file:./projects/recruit.tgz '@rush-temp/recruit-assets': file:./projects/recruit-assets.tgz @@ -221,6 +220,7 @@ specifiers: '@types/node': ~16.11.12 '@types/pdfkit': ~0.12.3 '@types/request': ~2.48.8 + '@types/sharp': ~0.30.4 '@types/tar-stream': ^2.2.2 '@types/toposort': ^2.0.3 '@types/uuid': ^8.3.1 @@ -271,7 +271,6 @@ specifiers: mini-css-extract-plugin: ^2.2.0 minio: ^7.0.26 mongodb: ^4.1.1 - node-html-parser: ~5.3.3 pdfkit: ~0.13.0 postcss: ^8.3.4 postcss-load-config: ^3.1.0 @@ -420,7 +419,6 @@ dependencies: '@rush-temp/preference-assets': file:projects/preference-assets.tgz '@rush-temp/presentation': file:projects/presentation.tgz_1e3963ebf0ceeb25b2fa6a1cc87e253c '@rush-temp/prod': file:projects/prod.tgz_8b34f51e833a67e51e5bff1df3e73cc8 - '@rush-temp/prod-tracker': file:projects/prod-tracker.tgz_8b34f51e833a67e51e5bff1df3e73cc8 '@rush-temp/query': file:projects/query.tgz '@rush-temp/recruit': file:projects/recruit.tgz '@rush-temp/recruit-assets': file:projects/recruit-assets.tgz_typescript@4.7.4 @@ -523,6 +521,7 @@ dependencies: '@types/node': 16.11.42 '@types/pdfkit': 0.12.6 '@types/request': 2.48.8 + '@types/sharp': 0.30.4 '@types/tar-stream': 2.2.2 '@types/toposort': 2.0.3 '@types/uuid': 8.3.4 @@ -573,7 +572,6 @@ dependencies: mini-css-extract-plugin: 2.6.1_webpack@5.73.0 minio: 7.0.28 mongodb: 4.7.0 - node-html-parser: 5.3.3 pdfkit: 0.13.0 postcss: 8.4.14 postcss-load-config: 3.1.4_postcss@8.4.14+ts-node@10.8.1 @@ -12464,52 +12462,6 @@ packages: - supports-color dev: false - file:projects/prod-tracker.tgz_8b34f51e833a67e51e5bff1df3e73cc8: - resolution: {integrity: sha512-hOYYMh2Au/J1fHweEgyZbMhrUqWpIej9lA02kjW+gOHzxZZO68RTfPBJq1d+UoaHUWPtC+YxkUPUcGiBPEKgfw==, tarball: file:projects/prod-tracker.tgz} - id: file:projects/prod-tracker.tgz - name: '@rush-temp/prod-tracker' - version: 0.0.0 - dependencies: - '@types/node': 16.11.42 - autoprefixer: 10.4.7_postcss@8.4.14 - compression-webpack-plugin: 9.0.1_webpack@5.73.0 - cross-env: 7.0.3 - css-loader: 5.2.7_webpack@5.73.0 - dotenv-webpack: 7.1.1_webpack@5.73.0 - file-loader: 6.2.0_webpack@5.73.0 - html-webpack-plugin: 5.5.0_webpack@5.73.0 - mini-css-extract-plugin: 2.6.1_webpack@5.73.0 - postcss: 8.4.14 - postcss-load-config: 3.1.4_postcss@8.4.14+ts-node@10.8.1 - postcss-loader: 6.2.1_postcss@8.4.14+webpack@5.73.0 - sass-loader: 12.6.0_sass@1.53.0+webpack@5.73.0 - style-loader: 3.3.1_webpack@5.73.0 - svelte: 3.48.0 - svelte-loader: 3.1.3_svelte@3.48.0 - svgo-loader: 3.0.1 - ts-loader: 9.3.1_typescript@4.7.4+webpack@5.73.0 - webpack: 5.73.0_0539a1ee9cc1e8c0305465d979f40a3d - webpack-bundle-analyzer: 4.5.0 - webpack-cli: 4.10.0_7445a258404e01c9b84d81171e5727fd - webpack-dev-server: 4.9.3_ffd7cf999054608223b9fc836cf5004f - transitivePeerDependencies: - - '@swc/core' - - '@webpack-cli/generators' - - '@webpack-cli/migrate' - - bufferutil - - debug - - esbuild - - fibers - - node-sass - - sass - - sass-embedded - - supports-color - - ts-node - - typescript - - uglify-js - - utf-8-validate - dev: false - file:projects/prod.tgz_8b34f51e833a67e51e5bff1df3e73cc8: resolution: {integrity: sha512-lOWf2/caG2bTwygiVfaeuB2EmI0qXT2J5cyKpc6ZXUPxwGul+YkWiiwjT6gzg0BGVEJssuN4owh7okSdrrlJdg==, tarball: file:projects/prod.tgz} id: file:projects/prod.tgz @@ -14080,7 +14032,7 @@ packages: dev: false file:projects/tool.tgz: - resolution: {integrity: sha512-LjCQIq8dqLFEXvLcBmfJKRtkoJublg0r6DWC2RwIlmJyw61xEEBFHdOn3p1l3EyQPg0PjgAaSoEUPF+ViaxlPQ==, tarball: file:projects/tool.tgz} + resolution: {integrity: sha512-7BKMRQ8UZ8cgJGDXvMGNoAdjUmEAyMx9GVBmBo3gmW56eLhxamaBqdwkunRIemCR77MJ8JJj+qhgWAzpRXpoRg==, tarball: file:projects/tool.tgz} name: '@rush-temp/tool' version: 0.0.0 dependencies: @@ -14153,7 +14105,7 @@ packages: dev: false file:projects/tracker-resources.tgz_1e3963ebf0ceeb25b2fa6a1cc87e253c: - resolution: {integrity: sha512-PKQD9e1Xy9uXITgztIDA3iXNVejZcOdX7dfkahRNSrPvWA7eiK1MOxO1TXGT8UKLAHCxOE9kaNQ9fJqaMca4og==, tarball: file:projects/tracker-resources.tgz} + resolution: {integrity: sha512-gNf+kxHBXh2EhUJNOFg36XUDijRQ7UkWIXl7Hf7Mt+Jg995unSk/8tKPsyJ+YcCkqGB7/Zfu4pTIvB/SGjEUwg==, tarball: file:projects/tracker-resources.tgz} id: file:projects/tracker-resources.tgz name: '@rush-temp/tracker-resources' version: 0.0.0 diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index c5a17abbd7..615689f886 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -49,6 +49,8 @@ import { IssueStatusCategory, Project, ProjectStatus, + Sprint, + SprintStatus, Team, trackerId } from '@anticrm/tracker' @@ -113,12 +115,25 @@ export function TypeProjectStatus (): Type { return { _class: tracker.class.TypeProjectStatus, label: 'TypeProjectStatus' as IntlString } } +/** + * @public + */ +export function TypeSprintStatus (): Type { + return { _class: tracker.class.TypeSprintStatus, label: 'TypeSprintStatus' as IntlString } +} + /** * @public */ @Model(tracker.class.TypeProjectStatus, core.class.Type, DOMAIN_MODEL) export class TTypeProjectStatus extends TType {} +/** + * @public + */ +@Model(tracker.class.TypeSprintStatus, core.class.Type, DOMAIN_MODEL) +export class TTypeSprintStatus extends TType {} + /** * @public */ @@ -201,6 +216,9 @@ export class TIssue extends TAttachedDoc implements Issue { @Prop(TypeString(), tracker.string.Rank) @Hidden() rank!: string + + @Prop(TypeRef(tracker.class.Sprint), tracker.string.Sprint) + sprint!: Ref | null } /** @@ -269,6 +287,40 @@ export class TProject extends TDoc implements Project { declare space: Ref } +/** + * @public + */ +@Model(tracker.class.Sprint, core.class.Doc, DOMAIN_TRACKER) +@UX(tracker.string.Sprint, tracker.icon.Sprint, tracker.string.Sprint) +export class TSprint extends TDoc implements Sprint { + @Prop(TypeString(), tracker.string.Title) + // @Index(IndexKind.FullText) + label!: string + + @Prop(TypeMarkup(), tracker.string.Description) + description?: Markup + + @Prop(TypeSprintStatus(), tracker.string.Status) + status!: SprintStatus + + @Prop(TypeRef(contact.class.Employee), tracker.string.ProjectLead) + lead!: Ref | null + + @Prop(Collection(chunter.class.Comment), chunter.string.Comments) + comments!: number + + @Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, undefined, attachment.string.Files) + attachments?: number + + @Prop(TypeDate(false), tracker.string.StartDate) + startDate!: Timestamp + + @Prop(TypeDate(false), tracker.string.TargetDate) + targetDate!: Timestamp + + declare space: Ref +} + export function createModel (builder: Builder): void { builder.createModel( TTeam, @@ -277,7 +329,9 @@ export function createModel (builder: Builder): void { TIssueStatus, TIssueStatusCategory, TTypeIssuePriority, - TTypeProjectStatus + TTypeProjectStatus, + TSprint, + TTypeSprintStatus ) builder.createDoc(view.class.Viewlet, core.space.Model, { @@ -298,6 +352,11 @@ export function createModel (builder: Builder): void { presenter: tracker.component.ProjectEditor, props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } }, + { + key: '', + presenter: tracker.component.SprintEditor, + props: { kind: 'list', size: 'small', shape: 'round', shouldShowPlaceholder: false } + }, { key: 'modifiedOn', presenter: tracker.component.ModificationDatePresenter, props: { fixed: 'right' } }, { key: '$lookup.assignee', @@ -405,6 +464,7 @@ export function createModel (builder: Builder): void { const backlogId = 'backlog' const boardId = 'board' const projectsId = 'projects' + const sprintsId = 'sprints' builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.AttributePresenter, { presenter: tracker.component.IssuePresenter @@ -434,6 +494,10 @@ export function createModel (builder: Builder): void { presenter: tracker.component.ProjectTitlePresenter }) + builder.mixin(tracker.class.Sprint, core.class.Class, view.mixin.AttributePresenter, { + presenter: tracker.component.SprintTitlePresenter + }) + builder.mixin(tracker.class.Issue, core.class.Class, setting.mixin.Editable, {}) builder.mixin(tracker.class.TypeProjectStatus, core.class.Class, view.mixin.AttributeEditor, { @@ -516,6 +580,12 @@ export function createModel (builder: Builder): void { label: tracker.string.Projects, icon: tracker.icon.Projects, component: tracker.component.TeamProjects + }, + { + id: sprintsId, + label: tracker.string.Sprints, + icon: tracker.icon.Sprint, + component: tracker.component.Sprints } ] } @@ -787,6 +857,34 @@ export function createModel (builder: Builder): void { }, tracker.action.SetProject ) + + createAction( + builder, + { + action: view.actionImpl.ValueSelector, + actionPopup: view.component.ValueSelector, + actionProps: { + attribute: 'sprint', + _class: tracker.class.Sprint, + query: {}, + searchField: 'label', + placeholder: tracker.string.Sprint + }, + label: tracker.string.Sprint, + icon: tracker.icon.Sprint, + keyBinding: [], + input: 'none', + category: tracker.category.Tracker, + target: tracker.class.Issue, + context: { + mode: ['context'], + application: tracker.app.Tracker, + group: 'edit' + } + }, + tracker.action.SetSprint + ) + createAction( builder, { diff --git a/models/tracker/src/plugin.ts b/models/tracker/src/plugin.ts index 5d9d97353a..d9def947ad 100644 --- a/models/tracker/src/plugin.ts +++ b/models/tracker/src/plugin.ts @@ -37,7 +37,8 @@ export default mergeIds(trackerId, tracker, { }, component: { // Required to pass build without errorsF - Nope: '' as AnyComponent + Nope: '' as AnyComponent, + SprintSelector: '' as AnyComponent }, app: { Tracker: '' as Ref diff --git a/packages/theme/styles/_layouts.scss b/packages/theme/styles/_layouts.scss index 3b8dc8ba15..51bf092788 100644 --- a/packages/theme/styles/_layouts.scss +++ b/packages/theme/styles/_layouts.scss @@ -721,6 +721,7 @@ a.no-line { .top-divider { border-top: 1px solid var(--divider-color); } .bottom-divider { border-bottom: 1px solid var(--divider-color); } .bottom-highlight-select { border-bottom: 1px solid var(--highlight-select); } +.left-divider { border-left: 1px solid var(--divider-color); } diff --git a/packages/ui/src/components/SelectPopup.svelte b/packages/ui/src/components/SelectPopup.svelte index fafe95655c..b42c61eda9 100644 --- a/packages/ui/src/components/SelectPopup.svelte +++ b/packages/ui/src/components/SelectPopup.svelte @@ -26,7 +26,7 @@ import { resizeObserver } from '../resize' interface ValueType { - id: number | string + id: number | string | null icon?: Asset iconColor?: string label?: IntlString diff --git a/packages/ui/src/components/calendar/DatePopup.svelte b/packages/ui/src/components/calendar/DatePopup.svelte index 9b4c92ec74..a622ee6a0c 100644 --- a/packages/ui/src/components/calendar/DatePopup.svelte +++ b/packages/ui/src/components/calendar/DatePopup.svelte @@ -13,13 +13,12 @@ // limitations under the License. --> - + + + + {#if viewlet} @@ -91,7 +94,7 @@ {/if} {#if $$slots.aside !== undefined && asideShown} -
+
{/if} diff --git a/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte b/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte index 65b714e4fa..cad2ad3da7 100644 --- a/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte +++ b/plugins/tracker-resources/src/components/issues/edit/ControlPanel.svelte @@ -14,17 +14,19 @@ -->
+ {#if issue.blockedBy?.length} @@ -83,6 +98,13 @@ + {#if issue.sprint} + + + + {/if} + {#if issue.dueDate !== null}
@@ -91,6 +113,13 @@ {/if} + + {#if keys.length > 0} +
+ {#each keys as key (typeof key === 'string' ? key : key.key)} + + {/each} + {/if}
diff --git a/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte b/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte new file mode 100644 index 0000000000..b1d256857f --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintBrowser.svelte @@ -0,0 +1,206 @@ + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+ + diff --git a/plugins/tracker-resources/src/components/sprints/SprintDatePresenter.svelte b/plugins/tracker-resources/src/components/sprints/SprintDatePresenter.svelte new file mode 100644 index 0000000000..cefc209cd9 --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintDatePresenter.svelte @@ -0,0 +1,48 @@ + + + + diff --git a/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte b/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte new file mode 100644 index 0000000000..601bb75bca --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte @@ -0,0 +1,74 @@ + + + +{#if value.sprint || shouldShowPlaceholder} +
+ +
+{/if} diff --git a/plugins/tracker-resources/src/components/sprints/SprintList.svelte b/plugins/tracker-resources/src/components/sprints/SprintList.svelte new file mode 100644 index 0000000000..1bdb5a0e30 --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintList.svelte @@ -0,0 +1,241 @@ + + + +{#await buildModel({ client, _class, keys: itemsConfig, lookup: options.lookup }) then itemModels} +
+ {#if sprints} + {#each sprints as docObject (docObject._id)} +
x === docObject)]} + class="listGrid" + class:mListGridChecked={selectedObjectIdsSet.has(docObject._id)} + class:mListGridFixed={selectedRowIndex === sprints.findIndex((x) => x === docObject)} + class:mListGridSelected={selectedRowIndex === sprints.findIndex((x) => x === docObject)} + on:focus={() => {}} + on:mouseover={() => handleRowFocused(docObject)} + > +
+ {#each itemModels as attributeModel, attributeModelIndex} + {#if attributeModelIndex === 0} +
+
+ { + onObjectChecked([docObject], event.detail) + }} + /> +
+
+ +
+
+ {:else if attributeModelIndex === 1} +
+ +
+
+ {:else} +
+ +
+ {/if} + {/each} +
+
+ {/each} + {:else if loadingProps !== undefined} + {#each Array(getLoadingElementsLength(loadingProps, options)) as _, rowIndex} +
+
+
+ +
+ +
+
+
+
+ {/each} + {/if} +
+{/await} + + diff --git a/plugins/tracker-resources/src/components/sprints/SprintListBrowser.svelte b/plugins/tracker-resources/src/components/sprints/SprintListBrowser.svelte new file mode 100644 index 0000000000..ca57902b0b --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintListBrowser.svelte @@ -0,0 +1,72 @@ + + + + + + { + listProvider.updateFocus(event.detail ?? undefined) + }} + on:check={(event) => { + listProvider.updateSelection(event.detail.docs, event.detail.value) + }} +/> diff --git a/plugins/tracker-resources/src/components/sprints/SprintPopup.svelte b/plugins/tracker-resources/src/components/sprints/SprintPopup.svelte new file mode 100644 index 0000000000..430f46ab43 --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintPopup.svelte @@ -0,0 +1,51 @@ + + + + + + + + diff --git a/plugins/tracker-resources/src/components/sprints/SprintPresenter.svelte b/plugins/tracker-resources/src/components/sprints/SprintPresenter.svelte new file mode 100644 index 0000000000..7385b0f945 --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintPresenter.svelte @@ -0,0 +1,46 @@ + + + +{#if value} +
+ {value.label} +
+{/if} + + diff --git a/plugins/tracker-resources/src/components/sprints/SprintSelector.svelte b/plugins/tracker-resources/src/components/sprints/SprintSelector.svelte new file mode 100644 index 0000000000..bd35f65866 --- /dev/null +++ b/plugins/tracker-resources/src/components/sprints/SprintSelector.svelte @@ -0,0 +1,102 @@ + + + +