Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nations modal #1066

Merged
merged 12 commits into from
Oct 23, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""added notes and pip fields to indigenous nations

Revision ID: 7deec389ae56
Revises: d8b405f9d663
Create Date: 2023-10-18 11:46:46.577009

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '7deec389ae56'
down_revision = 'd8b405f9d663'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('indigenous_nations', schema=None) as batch_op:
batch_op.add_column(sa.Column('notes', sa.String(), nullable=True))
batch_op.add_column(sa.Column('pip_org_type_id', sa.Integer(), nullable=True))
batch_op.create_foreign_key(None, 'pip_org_types', ['pip_org_type_id'], ['id'])

with op.batch_alter_table('indigenous_nations_history', schema=None) as batch_op:
batch_op.add_column(sa.Column('notes', sa.String(), autoincrement=False, nullable=True))
batch_op.add_column(sa.Column('pip_org_type_id', sa.Integer(), autoincrement=False, nullable=True))
batch_op.create_foreign_key(None, 'pip_org_types', ['pip_org_type_id'], ['id'])

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('indigenous_nations_history', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_column('pip_org_type_id')
batch_op.drop_column('notes')

with op.batch_alter_table('indigenous_nations', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_column('pip_org_type_id')
batch_op.drop_column('notes')

# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""create pip_org_type table

Revision ID: d8b405f9d663
Revises: 47b41964f6df
Create Date: 2023-10-18 11:45:36.531064

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = 'd8b405f9d663'
down_revision = '47b41964f6df'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('pip_org_types',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('created_by', sa.String(length=255), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', CURRENT_TIMESTAMP)"), nullable=True),
sa.Column('updated_by', sa.String(length=255), nullable=True),
TomChapmanGov marked this conversation as resolved.
Show resolved Hide resolved
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='t', nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default='f', nullable=False),
sa.PrimaryKeyConstraint('id'),
sqlite_autoincrement=True
)
op.create_table('pip_org_types_history',
sa.Column('id', sa.Integer(), autoincrement=False, nullable=False),
sa.Column('name', sa.String(), autoincrement=False, nullable=False),
sa.Column('created_by', sa.String(length=255), autoincrement=False, nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), autoincrement=False, nullable=True),
sa.Column('updated_by', sa.String(length=255), autoincrement=False, nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), autoincrement=False, nullable=True),
sa.Column('is_active', sa.Boolean(), autoincrement=False, nullable=False),
sa.Column('is_deleted', sa.Boolean(), autoincrement=False, nullable=False),
sa.Column('pk', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('during', postgresql.TSTZRANGE(), nullable=True),
sa.PrimaryKeyConstraint('id', 'pk'),
sqlite_autoincrement=True
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('pip_org_types_history')
op.drop_table('pip_org_types')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions epictrack-api/src/api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@
from .action_configuration import ActionCofiguration
from .task_event_responsibility import TaskEventResponsibility
from .act_section import ActSection
from .pip_org_type import PIPOrgType
6 changes: 6 additions & 0 deletions epictrack-api/src/api/models/indigenous_nation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class IndigenousNation(db.Model, CodeTableVersioned):
name = Column(String(255), nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
pip_link = Column(URLType, default=None, nullable=True)
notes = Column(String)

relationship_holder_id = Column(
ForeignKey("staffs.id"), nullable=True, default=None
Expand All @@ -38,6 +39,11 @@ class IndigenousNation(db.Model, CodeTableVersioned):
"Staff", foreign_keys=[relationship_holder_id], lazy="select"
)

pip_org_type_id = Column(ForeignKey("pip_org_types.id"))
pip_org_type = relationship(
"PIPOrgType", foreign_keys=[pip_org_type_id], lazy="select"
)

def as_dict(self):
"""Return JSON Representation."""
result = CodeTableVersioned.as_dict(self)
Expand Down
26 changes: 26 additions & 0 deletions epictrack-api/src/api/models/pip_org_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright © 2019 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Model to handle all operations related to Region."""

from sqlalchemy import Column, Integer, String
from .code_table import CodeTableVersioned
from .db import db

class PIPOrgType(db.Model, CodeTableVersioned):
"""Model class for PIP Organization Types."""

__tablename__ = 'pip_org_types'

id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(), nullable=False)
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ class IndigenousNationBodyParameterSchema(RequestBodyParameterSchema):

is_active = fields.Bool(
metadata={"description": "Active state of the indigenous nation"})

notes = fields.Str(
metadata={"description": "Notes for the indigenous nation"},
allow_none=True
)

pip_org_type_id = fields.Int(
metadata={"description": "PIP organization type for the indigenous nation"},
validate=validate.Range(min=1),
allow_none=True,
missing=None
)

pip_link = fields.Str(
metadata={"description": "PIP site URL for indigenous nation"},
allow_none=True,
missing=None
)


class IndigenousNationExistenceQueryParamSchema(RequestQueryParameterSchema):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from "react";
import { TextField, Grid, Button } from "@mui/material";

Check warning on line 2 in epictrack-web/src/components/indigenousNation/IndigneousNationForm.tsx

View workflow job for this annotation

GitHub Actions / linting (14.x)

'Button' is defined but never used
import { FormProvider, useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { ETFormLabel } from "../shared/index";
import { Staff } from "../../models/staff";
import ControlledCheckbox from "../shared/controlledInputComponents/ControlledCheckbox";

Check warning on line 8 in epictrack-web/src/components/indigenousNation/IndigneousNationForm.tsx

View workflow job for this annotation

GitHub Actions / linting (14.x)

'ControlledCheckbox' is defined but never used
import indigenousNationService from "../../services/indigenousNationService/indigenousNationService";
import { FirstNation } from "../../models/firstNation";
import staffService from "../../services/staffService/staffService";
import ControlledSelectV2 from "../shared/controlledInputComponents/ControlledSelectV2";
import { MasterContext } from "../shared/MasterContext";
import { PIPOrgType } from "../../models/pipOrgType";
import ControlledSwitch from "../shared/controlledInputComponents/ControlledSwitch";
import RichTextEditor from "../shared/richTextEditor";
import codeService, { Code } from "../../services/codeService";

const schema = yup.object().shape({
name: yup
Expand All @@ -26,21 +30,28 @@
value,
parent["id"]
);
return !(validateINationsResult.data as any)["exists"] as boolean;

Check warning on line 33 in epictrack-web/src/components/indigenousNation/IndigneousNationForm.tsx

View workflow job for this annotation

GitHub Actions / linting (14.x)

Unexpected any. Specify a different type
}
return true;
}
),
pip_url: yup.string(),
});

export default function IndigenousNationForm({ ...props }) {
const [staffs, setStaffs] = React.useState<Staff[]>([]);
const [pipOrgTypes, setPipOrgTypes] = React.useState<PIPOrgType[]>([]);
const [notes, setNotes] = React.useState("");
const ctx = React.useContext(MasterContext);

React.useEffect(() => {
ctx.setFormId("indigenous-nation-form");
}, []);

React.useEffect(() => {
ctx.setTitle(ctx.item ? (ctx.item as FirstNation)?.name : "Nation");
}, [ctx.title, ctx.item]);

React.useEffect(() => {
ctx.setId(props.indigenousNationID);
}, [ctx.id]);
Expand All @@ -60,6 +71,9 @@

React.useEffect(() => {
reset(ctx.item);
if (ctx.item) {
setNotes((ctx.item as FirstNation)?.notes || "");
}
}, [ctx.item]);

const getStaffs = async () => {
Expand All @@ -68,14 +82,37 @@
setStaffs(staffsResult.data as never);
}
};

const codeTypes: { [x: string]: any } = {

Check warning on line 86 in epictrack-web/src/components/indigenousNation/IndigneousNationForm.tsx

View workflow job for this annotation

GitHub Actions / linting (14.x)

Unexpected any. Specify a different type
pip_org_types: setPipOrgTypes,
};

const getCodes = async (code: Code) => {
const codeResult = await codeService.getCodes(code);
if (codeResult.status === 200) {
codeTypes[code]((codeResult.data as never)["codes"]);
}
};

React.useEffect(() => {
getStaffs();
const promises: any[] = [];
Object.keys(codeTypes).forEach(async (key) => {
promises.push(getCodes(key as Code));
});
Promise.all(promises);
}, []);

const onSubmitHandler = async (data: FirstNation) => {
data.notes = notes;
ctx.onSave(data, () => {
reset();
});
ctx.setId(undefined);
};

console.log(pipOrgTypes);

return (
<>
<FormProvider {...methods}>
Expand All @@ -87,8 +124,9 @@
onSubmit={handleSubmit(onSubmitHandler)}
>
<Grid item xs={6}>
<ETFormLabel>Name</ETFormLabel>
<ETFormLabel required>Name</ETFormLabel>
<TextField
placeholder="Name"
fullWidth
error={!!errors?.name?.message}
helperText={errors?.name?.message?.toString()}
Expand All @@ -98,6 +136,7 @@
<Grid item xs={6}>
<ETFormLabel>Relationship Holder</ETFormLabel>
<ControlledSelectV2
placeholder="Select a Relationship Holder"
defaultValue={
(ctx.item as FirstNation)?.relationship_holder_id || ""
}
Expand All @@ -107,8 +146,30 @@
{...register("relationship_holder_id")}
></ControlledSelectV2>
</Grid>
<Grid item xs={6}>
<ETFormLabel>PIP Organization Type</ETFormLabel>
<ControlledSelectV2
placeholder="Select an Organization Type"
defaultValue={(ctx.item as FirstNation)?.pip_org_type_id || ""}
getOptionLabel={(o: PIPOrgType) => (o ? o.name : "")}
getOptionValue={(o: PIPOrgType) => (o ? o.id.toString() : "")}
options={pipOrgTypes || []}
{...register("pip_org_type_id")}
></ControlledSelectV2>
</Grid>
<Grid item xs={6}>
<ETFormLabel>PIP URL</ETFormLabel>
<TextField fullWidth {...register("pip_link")} />
</Grid>
<Grid item xs={12}>
<ETFormLabel>Notes</ETFormLabel>
<RichTextEditor
handleEditorStateChange={setNotes}
initialRawEditorState={(ctx.item as FirstNation)?.notes}
/>
</Grid>
<Grid item xs={6} sx={{ paddingTop: "30px !important" }}>
<ControlledCheckbox
<ControlledSwitch
defaultChecked={(ctx.item as FirstNation)?.is_active}
{...register("is_active")}
/>
Expand Down
4 changes: 4 additions & 0 deletions epictrack-web/src/models/firstNation.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { ListType } from "./code";
import { Staff } from "./staff";
import { MasterBase } from "./type";
import { PIPOrgType } from "./pipOrgType";

export interface FirstNation extends ListType, MasterBase {
is_active: boolean;
relationship_holder_id?: number;
relationship_holder?: Staff;
pip_link: string;
notes?: string;
pip_org_type_id: number;
pip_org_type: PIPOrgType;
}

export interface WorkFirstNation extends ListType, MasterBase {
Expand Down
4 changes: 4 additions & 0 deletions epictrack-web/src/models/pipOrgType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { ListType } from "./code";
import { MasterBase } from "./type";

export interface PIPOrgType extends ListType, MasterBase {}
3 changes: 2 additions & 1 deletion epictrack-web/src/services/codeService/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export type Code =
| "federal_involvements"
| "responsibilities"
| "roles"
| "substitution_acts";
| "substitution_acts"
| "pip_org_types";

const getCodes = async (codeType: Code, apiUrl?: string) => {
return await http.GetRequest(Endpoints.Codes.GET_CODES + `/${codeType}`);
Expand Down
Loading